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++;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章