Realm数据库踩坑

今天升级Realm数据库实体类的时候,发现数据库东西不见了,折腾了一下午,得到一些教训,这里转一些知识点,下次升级时候用。


/**
 * Realm数据库升级
 */
public class MyMigration implements RealmMigration {

    @Override
    public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
        RealmSchema schema = realm.getSchema();

        if (oldVersion == 1) {
            // Boolean.class : 是required
            // boolean.class : 可nullable
            schema.get("Friend").addField("hasChecked", boolean.class);// 因为大写了Boolean,始终有Bug

            oldVersion++;// 如果后期还有操作继续下个判断
        }
    }
}

Realm数据库踩坑

江左小梅郎 / 文 发表于2017-07-20 09:26

注:本文为Realm在项目中的使用注意事项,不能作为使用说明来阅读。

Realm使用配置

  1. 项目build.gradle 中, classpath “io.realm:realm-gradle-plugin:2.2.1”
  2. app的build.gradle中, apply plugin: ‘realm-android’

☆☆☆ 注意:
在注入依赖时,确保 apply plugin: ‘realm-android’ 位于 apply plugin: ‘android-apt’ 的下方
原因:猜测 realm 依赖注解

使用注意事项

Realm数据库,必须在生成realm对象实例的线程中进行操作。因此不需要编写helper定义全局变量。

  1. 可在Application启动时,初始化一个全局的config
  2. 在需要数据库操作的activity、fragment或者线程中,Realm.getInstance(config)即可,用完可直接close。

☆ 插入和修改 操作,必须放在事物中进行;
☆ 查询操作可选择直接查询和异步事物查询(当数据量较大,可能会引起ANR的时候),不过后者并不会马上查到数据,是有一定延时的;
☆ 删除语句,需要使用事物,但不能使用异步事物,否则将失败
☆☆ 继承了RealmObject的数据model,如果实现了带参数的构造函数的话,必须实现无参构造函数,否则编译出错。

数据库升级

☆ 注意:如果你创建Model并运行过,然后修改了Model。那么就需要升级数据库,否则会抛异常。
☆☆☆☆☆ 数据库版本升级时,若要增加字段,则该字段必须设置 FieldAttribute.REQUIRED 属性,否则数据库会出错,打不开。

eg. schema.addField("stock", String.class, FieldAttribute.REQUIRED)

@Index——添加搜索索引 为字段添加搜索索引,这样会使得插入的速度变慢,数据量也变得更大。不过在查询速度将变得更快,建议只在优化读 取性能的特定情况时添加索引。支持索引:String,byte,short,int,long,boolean和Date字段。

具体使用可参考链接

以下为数据库升级类RealmMigration使用范例:

注:COPY的,贴在此处作为收藏O(∩_∩)O。

public class Migration implements RealmMigration {

    @Override
    public void migrate(final DynamicRealm realm, long oldVersion, long newVersion) {
        // During a migration, a DynamicRealm is exposed. A DynamicRealm is an untyped variant of a 
        // normal Realm, but with the same object creation and query capabilities.
        // A DynamicRealm uses Strings instead of Class references because the Classes might not 
        // even exist or have been renamed.
        // Access the Realm schema in order to create, modify or delete classes and their fields.
        RealmSchema schema = realm.getSchema();
        /************************************************
         // Version 0
         class Person
         @Required String firstName;
         @Required String lastName;
         int    age;
         // Version 1
         class Person
         @Required String fullName;            // combine firstName and lastName into single field.
         int age;
         ************************************************/
        // Migrate from version 0 to version 1
        if (oldVersion == 0) {
            RealmObjectSchema personSchema = schema.get("Person");
            // Combine 'firstName' and 'lastName' in a new field called 'fullName'
            personSchema
                    .addField("fullName", String.class, FieldAttribute.REQUIRED)
                    .transform(new RealmObjectSchema.Function() {
                        @Override
                        public void apply(DynamicRealmObject obj) {
                            obj.set("fullName", obj.getString("firstName") + " " + obj.getString("lastName"));
                        }
                    })
                    .removeField("firstName")
                    .removeField("lastName");
            oldVersion++;
        }
        /************************************************
         // Version 2
         class Pet                   // add a new model class
         @Required String name;
         @Required String type;
         class Person
         @Required String fullName;
         int age;
         RealmList<Pet> pets;    // add an array property
         ************************************************/
        // Migrate from version 1 to version 2
        if (oldVersion == 1) {
            // Create a new class
            RealmObjectSchema petSchema = schema.create("Pet")
                    .addField("name", String.class, FieldAttribute.REQUIRED)
                    .addField("type", String.class, FieldAttribute.REQUIRED);
            // Add a new field to an old class and populate it with initial data
            schema.get("Person")
                    .addRealmListField("pets", petSchema)
                    .transform(new RealmObjectSchema.Function() {
                        @Override
                        public void apply(DynamicRealmObject obj) {
                            if (obj.getString("fullName").equals("JP McDonald")) {
                                DynamicRealmObject pet = realm.createObject("Pet");
                                pet.setString("name", "Jimbo");
                                pet.setString("type", "dog");
                                obj.getList("pets").add(pet);
                            }
                        }
                    });
            oldVersion++;
        }
        /************************************************
         // Version 3
         class Pet
         @Required String name;
         int type;               // type becomes int
         class Person
         String fullName;        // fullName is nullable now
         RealmList<Pet> pets;    // age and pets re-ordered (no action needed)
         int age;
         ************************************************/
        // Migrate from version 2 to version 3
        if (oldVersion == 2) {
            RealmObjectSchema personSchema = schema.get("Person");
            personSchema.setNullable("fullName", true); // fullName is nullable now.
            // Change type from String to int
            schema.get("Pet")
                    .addField("type_tmp", int.class)
                    .transform(new RealmObjectSchema.Function() {
                        @Override
                        public void apply(DynamicRealmObject obj) {
                            String oldType = obj.getString("type");
                            if (oldType.equals("dog")) {
                                obj.setLong("type_tmp", 1);
                            } else if (oldType.equals("cat")) {
                                obj.setInt("type_tmp", 2);
                            } else if (oldType.equals("hamster")) {
                                obj.setInt("type_tmp", 3);
                            }
                        }
                    })
                    .removeField("type")
                    .renameField("type_tmp", "type");
            oldVersion++;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章