如何在 ORMLite 中指定对象自定义序列化?
How to specify object custom serialization in ORMLite?
我想将 ParentClass 类型的某些字段作为 json 字符串存储到我的数据库中。我不想使用 Serializable 接口并且 DataType.SERIALIZABLE 因为它与序列化 class 的完整 class 名称相关联。
所以我使用以下代码:
class ParentClass {
@DatabaseField(persisterClass = MyFieldClassPersister.class)
private MyFieldClass myField;
}
where persister class 一种:
public class MyFieldClassPersister extends StringType {
private static final MyFieldClassPersister singleTon = new MyFieldClassPersister();
public static MyFieldClassPersister getSingleton() {
return singleTon;
}
protected MyFieldClassPersister() {
super(SqlType.STRING, new Class<?>[0]);
}
@Override
public Object parseDefaultString(FieldType fieldType, String defaultStr) {
return jsonStringToObject(defaultStr);
}
@Override
public Object resultToSqlArg(FieldType fieldType, DatabaseResults results, int columnPos) throws SQLException {
String string = results.getString(columnPos);
return jsonStringToObject(string);
}
private static MyFieldClass jsonStringToObject(String string) {
// json to object conversion logic
}
}
这是我遇到的两个问题:
我不知道如何指定从对象到字符串的自定义转换。似乎 ORMLite 调用 Object.toString() 以获得对象的字符串表示形式。如果在 Persister 中有一些方法,我可以在其中指定如何将对象转换为字符串(在我的例子中为 json),那就太好了。是的,我可以在 MyFieldClass 中覆盖 toString() 方法,但在 Persister 中执行转换更方便。为了指定从模型对象到 db-object 的转换,我可以重写任何方法吗?
如果我将自定义字段类型标记为字符串类型:
class ParentClass {
@DatabaseField(dataType = DataType.STRING, persisterClass = MyFieldClassPersister.class)
private MyFieldClass myField;
}
然后 ormlite 在保存对象时崩溃并显示以下消息:
java.lang.IllegalArgumentException: Field class com.myapp.venue.MyFieldClass for
field FieldType:name=myField,class=ParentClass is not valid for type
com.j256.ormlite.field.types.StringType@272ed83b, maybe should be
class java.lang.String
如果我省略数据类型规范,它不会崩溃。我能以某种方式避免这次崩溃吗?在我看来,最好明确指定类型。
所以基本上你的持久化应该以下面的方式实现:
public class MyFieldClassPersister extends StringType {
private static final MyFieldClassPersister INSTANCE = new MyFieldClassPersister();
private MyFieldClassPersister() {
super(SqlType.STRING, new Class<?>[] { MyFieldClass.class });
}
public static MyFieldClassPersister getSingleton() {
return INSTANCE;
}
@Override
public Object javaToSqlArg(FieldType fieldType, Object javaObject) {
MyFieldClass myFieldClass = (MyFieldClass) javaObject;
return myFieldClass != null ? getJsonFromMyFieldClass(myFieldClass) : null;
}
@Override
public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos) {
return sqlArg != null ? getMyFieldClassFromJson((String) sqlArg) : null;
}
private String getJsonFromMyFieldClass(MyFieldClass myFieldClass) {
// logic here
}
private MyFieldClass getMyFieldClassFromJson(String json) {
// logic here
}
}
您应该在 OrmLiteSqliteOpenHelper
class
的 onCreate
方法中注册它
@Override
public void onCreate(SQLiteDatabaseHolder holder, ConnectionSource connectionSource) {
try {
//...
DataPersisterManager
.registerDataPersisters(MyFieldClassPersister.getSingleton());
} catch (SQLException e) {
// log exception
}
}
然后你可以像这样在你的模型中使用它:
@DatabaseField(persisterClass = MyFieldClassPersister.class, columnName = "column_name")
protected MyFieldClass myFieldClass;
不要在 onCreate() 方法中注册持久化适配器。只有在首次创建数据库时才会调用此方法。您应该将其添加到其他地方,例如您的构造函数或 onOpen() 方法。
我想将 ParentClass 类型的某些字段作为 json 字符串存储到我的数据库中。我不想使用 Serializable 接口并且 DataType.SERIALIZABLE 因为它与序列化 class 的完整 class 名称相关联。
所以我使用以下代码:
class ParentClass {
@DatabaseField(persisterClass = MyFieldClassPersister.class)
private MyFieldClass myField;
}
where persister class 一种:
public class MyFieldClassPersister extends StringType {
private static final MyFieldClassPersister singleTon = new MyFieldClassPersister();
public static MyFieldClassPersister getSingleton() {
return singleTon;
}
protected MyFieldClassPersister() {
super(SqlType.STRING, new Class<?>[0]);
}
@Override
public Object parseDefaultString(FieldType fieldType, String defaultStr) {
return jsonStringToObject(defaultStr);
}
@Override
public Object resultToSqlArg(FieldType fieldType, DatabaseResults results, int columnPos) throws SQLException {
String string = results.getString(columnPos);
return jsonStringToObject(string);
}
private static MyFieldClass jsonStringToObject(String string) {
// json to object conversion logic
}
}
这是我遇到的两个问题:
我不知道如何指定从对象到字符串的自定义转换。似乎 ORMLite 调用 Object.toString() 以获得对象的字符串表示形式。如果在 Persister 中有一些方法,我可以在其中指定如何将对象转换为字符串(在我的例子中为 json),那就太好了。是的,我可以在 MyFieldClass 中覆盖 toString() 方法,但在 Persister 中执行转换更方便。为了指定从模型对象到 db-object 的转换,我可以重写任何方法吗?
如果我将自定义字段类型标记为字符串类型:
class ParentClass { @DatabaseField(dataType = DataType.STRING, persisterClass = MyFieldClassPersister.class) private MyFieldClass myField; }
然后 ormlite 在保存对象时崩溃并显示以下消息:
java.lang.IllegalArgumentException: Field class com.myapp.venue.MyFieldClass for
field FieldType:name=myField,class=ParentClass is not valid for type
com.j256.ormlite.field.types.StringType@272ed83b, maybe should be
class java.lang.String
如果我省略数据类型规范,它不会崩溃。我能以某种方式避免这次崩溃吗?在我看来,最好明确指定类型。
所以基本上你的持久化应该以下面的方式实现:
public class MyFieldClassPersister extends StringType {
private static final MyFieldClassPersister INSTANCE = new MyFieldClassPersister();
private MyFieldClassPersister() {
super(SqlType.STRING, new Class<?>[] { MyFieldClass.class });
}
public static MyFieldClassPersister getSingleton() {
return INSTANCE;
}
@Override
public Object javaToSqlArg(FieldType fieldType, Object javaObject) {
MyFieldClass myFieldClass = (MyFieldClass) javaObject;
return myFieldClass != null ? getJsonFromMyFieldClass(myFieldClass) : null;
}
@Override
public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos) {
return sqlArg != null ? getMyFieldClassFromJson((String) sqlArg) : null;
}
private String getJsonFromMyFieldClass(MyFieldClass myFieldClass) {
// logic here
}
private MyFieldClass getMyFieldClassFromJson(String json) {
// logic here
}
}
您应该在 OrmLiteSqliteOpenHelper
class
onCreate
方法中注册它
@Override
public void onCreate(SQLiteDatabaseHolder holder, ConnectionSource connectionSource) {
try {
//...
DataPersisterManager
.registerDataPersisters(MyFieldClassPersister.getSingleton());
} catch (SQLException e) {
// log exception
}
}
然后你可以像这样在你的模型中使用它:
@DatabaseField(persisterClass = MyFieldClassPersister.class, columnName = "column_name")
protected MyFieldClass myFieldClass;
不要在 onCreate() 方法中注册持久化适配器。只有在首次创建数据库时才会调用此方法。您应该将其添加到其他地方,例如您的构造函数或 onOpen() 方法。