如何在ORMLite中指定对象自定义序列化? [英] How to specify object custom serialization in ORMLite?

查看:95
本文介绍了如何在ORMLite中指定对象自定义序列化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将一些类型为ParentClass的字段作为json字符串存储到我的数据库中。我不想使用Serializable接口和DataType.SERIALIZABLE,因为它与序列化类的完整类名绑定。

I would like to store some field of type ParentClass as json string into my database. I don't want to use Serializable interface and DataType.SERIALIZABLE cause it ties with full class name of serialized class.

所以我使用以下代码:

class ParentClass {

    @DatabaseField(persisterClass = MyFieldClassPersister.class)
    private MyFieldClass myField;
}

其中persister class有一种:

where persister class a kind of:

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
    }

}

以下是我遇到的两个问题:

Here are two issues I've met:


  1. 我没有得到如何指定从对象到字符串的自定义转换。似乎ORMLite调用Object.toString()以获取对象的字符串表示。在Persister中有一些方法会很棒,我可以在其中指定如何将Object转换为字符串(在我的例子中为json)。是的,我可以覆盖MyFieldClass中的toString()方法,但在Persister中执行转换更方便。是否有任何方法可以覆盖以指定从模型对象到db-object的转换?

  1. I didn't get how to specify custom convertion from object to string. Seems that ORMLite calls Object.toString() in order to get string representation of the object. It would be great to have some method in Persister in which I could specify how to convert Object to string (json in my case). Yes, I can override toString() method in MyFieldClass, but it is more convenient to perform conversion in Persister. Is there any method I could override in order to specify convertion from model object to db-object?

如果我将自定义字段类型标记为字符串类型:

If I mark my custom field type as String type:

class ParentClass {

    @DatabaseField(dataType = DataType.STRING, persisterClass = MyFieldClassPersister.class)
    private MyFieldClass myField;
}


然后ormlite崩溃使用以下消息保存对象:

then ormlite crashes when saving object with the following message:

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

如果我省略dataType规范,它不会崩溃。我能以某种方式避免这种崩溃吗?在我看来,明确指定类型更好。

It doesn't crash if I omit dataType specification. Can I avoid this crash in some way? It seems to me that it's better to specify types explicitly.

推荐答案

所以基本上你的persister应该以下一个方式实现:

So basically your persister should be implemented in the next way:

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
    }
}

你应该注册它在 onCreate 的方法 OrmLiteSqliteOpenHelper class

You should register it in onCreate method of your OrmLiteSqliteOpenHelper class

    @Override
    public void onCreate(SQLiteDatabaseHolder holder, ConnectionSource connectionSource) {
            try {
                //...
                DataPersisterManager
                 .registerDataPersisters(MyFieldClassPersister.getSingleton());
            } catch (SQLException e) {
                // log exception
            }
    }

然后你可以在你的模型中使用它,如下所示:

And then you can use it in your model like this:

@DatabaseField(persisterClass = MyFieldClassPersister.class, columnName = "column_name")
protected MyFieldClass myFieldClass;

这篇关于如何在ORMLite中指定对象自定义序列化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆