Realm数据库踩坑

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

  1. 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 依赖注解
  2. 使用注意事项: 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字段。

具体使用可参考链接:http://www.jianshu.com/p/37af717761cc

以下为数据库升级类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++;
    }
}

}