今天升級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使用配置
- 項目build.gradle 中, classpath “io.realm:realm-gradle-plugin:2.2.1”
- app的build.gradle中, apply plugin: ‘realm-android’
☆☆☆ 注意:
在注入依賴時,確保 apply plugin: ‘realm-android’ 位於 apply plugin: ‘android-apt’ 的下方
原因:猜測 realm 依賴註解
使用注意事項
Realm數據庫,必須在生成realm對象實例的線程中進行操作。因此不需要編寫helper定義全局變量。
- 可在Application啓動時,初始化一個全局的config
- 在需要數據庫操作的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++;
}
}
}