首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Realm Java 開發全攻略:從環境搭建到高級特性實戰

     編輯:Java 綜合教學

Realm Java 開發全攻略

Realm 作為新一代移動端數據庫,其 Java 版本為 Android 開發帶來了極致的性能與開發體驗。本文涵蓋 Gradle 集成、模型定義、關聯查詢、異步操作、數據遷移、加密等完整技術棧,並對比 Swift 版本差異,助力 Android 開發者快速落地。

環境搭建與配置

Gradle 依賴接入

// Project build.gradle
buildscript {
    repositories { jcenter() }
    dependencies {
        classpath "io.realm:realm-gradle-plugin:0.88.3"
    }
}

// Module build.gradle
apply plugin: 'realm-android'

ProGuard 保護規則

-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class * { *; }
-dontwarn javax.**
-dontwarn io.realm.**

數據模型定義

支援類型

boolean、byte、short、int、long、float、double、String、Date、byte[]、RealmObject、RealmList

必填字段與空值控制

使用 @Required 標註非空字段,適用於:Boolean、Byte、Short、Integer、Long、Float、Double、String、byte[]、Date。基本類型與 RealmList 隱含非空。注意: 必須提供 getter/setter,否則無法正確讀寫。

忽略屬性

@Ignore
private String tempField;

自動更新特性

與 Swift 版本一致,物件修改即時反映到所有引用:

realm.beginTransaction();
Dog myDog = realm.createObject(Dog.class);
myDog.setName("Fido");
myDog.setAge(1);
realm.commitTransaction();

Dog myPuppy = realm.where(Dog.class).equalTo("age", 1).findFirst();
realm.beginTransaction();
myPuppy.setAge(2);
realm.commitTransaction();
myDog.getAge(); // 返回 2

索引與主鍵

@Index
private String name;

@PrimaryKey
private long id;  // 隱含 @Index + @Required

支援主鍵類型:String、short、int、long。關鍵提示: 使用 copyToRealmOrUpdate() 替代 createObject() 避免主鍵衝突。

關聯關係與鏈式查詢

一對一

public class Contact extends RealmObject {
    private Email email;  // 設為 null 斷開關聯,不刪除 Email 實例
}

一對多

public class Contact extends RealmObject {
    private RealmList<Email> emails;
}

鏈式查詢實戰

// 查找擁有棕色名為 Fluffy 狗狗的用戶
RealmResults<User> r1 = realm.where(User.class)
    .equalTo("dogs.name", "Fluffy")
    .equalTo("dogs.color", "Brown")
    .findAll();

// 分步查詢(結果不同)
RealmResults<User> r2 = realm.where(User.class)
    .equalTo("dogs.name", "Fluffy")
    .findAll()
    .where()
    .equalTo("dogs.color", "Brown")
    .findAll();

寫入事務體系

標準事務

Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
// 增刪改操作
realm.commitTransaction();

// 可隨時回滾
realm.beginTransaction();
User user = realm.createObject(User.class);
realm.cancelTransaction();

事務塊(自動管理)

realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        User user = realm.createObject(User.class);
        user.setName("John");
        user.setEmail("john@corporation.com");
    }
});

異步事務(大量寫入)

realm.executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm bgRealm) {
        User user = bgRealm.createObject(User.class);
        user.setName("John");
    }
}, new Realm.Transaction.OnSuccess() {
    @Override
    public void onSuccess() { /* 成功回調 */ }
}, new Realm.Transaction.OnError() {
    @Override
    public void onError(Throwable error) { /* 失敗回調 */ }
});

// 可取消的異步任務
RealmAsyncTask transaction = realm.executeTransactionAsync(...);
public void onStop() {
    if (transaction != null && !transaction.isCancelled()) {
        transaction.cancel();
    }
}

查詢系統詳解

採用 Fluent Interface 流式 API,支援惰性加載、引用語義、自動更新。

條件構建器

RealmResults<User> result = realm.where(User.class)
    .equalTo("name", "John")
    .or()
    .equalTo("name", "Peter")
    .findAll();

// 空結果 size() == 0,非 null

操作符分類

  • 範圍:between()、greaterThan()、lessThan()、greaterThanOrEqualTo()、lessThanOrEqualTo()
  • 相等:equalTo()、notEqualTo()
  • 字符串:contains()、beginsWith()、endsWith()
  • 邏輯分組:beginGroup()、endGroup()、or()、not()

排序與聚合

result.sort("age");
result.sort("age", Sort.DESCENDING);

long sum = results.sum("age").longValue();
long min = results.min("age").longValue();
double avg = results.average("age");

鏈式查詢與異步查詢

// 鏈式查詢
RealmResults<User> teens = realm.where(User.class).between("age", 13, 20).findAll();
User firstJohn = teens.where().equalTo("name", "John").findFirst();

// 異步查詢(需 Looper 線程)
RealmResults<User> result = realm.where(User.class).findAllAsync();
result.addChangeListener(new RealmChangeListener() {
    @Override
    public void onChange() { /* UI 更新 */ }
});

// 強制同步加載(阻塞當前線程)
result.load();

Realm 實例管理

配置構建器模式

RealmConfiguration config = new RealmConfiguration.Builder(context)
    .name("myrealm.realm")
    .encryptionKey(getKey())
    .schemaVersion(42)
    .setModules(new MySchemaModule())
    .migration(new MyMigration())
    .build();

Realm.setDefaultConfiguration(config);

內存與動態 Realm

  • In-Memory: 無磁盤持久化,適合緩存、測試
  • DynamicRealm: 無需模型類,通過字符串操作,靈活但失去類型安全

實例關閉規範

// 一般線程
try {
    Realm realm = Realm.getDefaultInstance();
    // 使用 realm
} finally {
    if (realm != null) realm.close();
}

// Looper 線程
public class MyThread extends Thread {
    private Realm realm;
    public void run() {
        Looper.prepare();
        try {
            realm = Realm.getDefaultInstance();
            Looper.loop();
        } finally {
            if (realm != null) realm.close();
        }
    }
}

// API 19+ try-with-resources
try (Realm realm = Realm.getDefaultInstance()) {
    // 自動關閉
}

線程模型深度解析

核心原則與 Swift 版本一致:不可跨線程傳遞 Realm 實例,各線程持有獨立快照。

生產者-消費者模式範例

// UI 線程
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    realm = Realm.getDefaultInstance();
    RealmResults<Customer> customers = realm.where(Customer.class).findAllAsync();
    customers.addChangeListener(new RealmChangeListener() {
        @Override
        public void onChange() {
            listAdapter.notifyDataSetChanged(); // 自動更新 UI
        }
    });
}

// 後台服務線程
public class PollingService extends Service {
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Realm realm = Realm.getDefaultInstance();
        String json = customerApi.getCustomers();
        realm.beginTransaction();
        realm.createObjectFromJson(Customer.class, json);
        realm.commitTransaction(); // UI 線程自動收到變更通知
        return START_STICKY;
    }
}

Schema 模組化管理

支援類白名單、庫模組隔離、多模組合併:

// 庫模組(library = true 防止生成默認模組)
@RealmModule(library = true, allClasses = true)
public class MyLibraryModule {}

// App 整合庫模組
RealmConfiguration config = new RealmConfiguration.Builder(context)
    .name("app.realm")
    .setModules(Realm.getDefaultModule(), new MyLibraryModule())
    .build();

JSON 導入支援

支援 String、JSONObject、JSONArray、InputStream 四種來源:

realm.beginTransaction();
realm.createObjectFromJson(City.class, "{ city: \"Copenhagen\", id: 1 }");
realm.createObjectFromJson(City.class, jsonObject);
realm.createObjectFromJson(City.class, jsonArray);
realm.createAllFromJson(City.class, inputStream);
realm.commitTransaction();

Null 處理規則: 非 @Required 字段設為 null;@Required 字段拋異常;JSON 缺失字段保持原值不變。

通知機制

僅在 Looper 線程回調,非 Looper 線程需手動 Realm.refresh()。支援 Realm、RealmObject、RealmResults 級別監聽,Listener 必須強引用持有:

// 類級別監聽(含關聯變更)
Person person = realm.where(Person.class).findFirst();
person.addChangeListener(new RealmChangeListener() {
    @Override
    public void onChange() {
        // 關聯 Dog 更新也會觸發
    }
});

數據遷移實戰

採用線性遷移模式,必須處理跨版本升級:

RealmMigration migration = new RealmMigration() {
    @Override
    public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
        RealmSchema schema = realm.getSchema();
        
        // v0 → v1: 合併 firstName + lastName → fullName
        if (oldVersion == 0) {
            RealmObjectSchema personSchema = schema.get("Person");
            personSchema.addField("fullName", String.class, FieldAttribute.REQUIRED)
                .transform(obj -> obj.set("fullName", obj.getString("firstName") + " " + obj.getString("lastName")))
                .removeField("firstName")
                .removeField("lastName");
            oldVersion++;
        }
        
        // v1 → v2: 新增 Pet 類與關聯
        if (oldVersion == 1) {
            RealmObjectSchema petSchema = schema.create("Pet")
                .addField("name", String.class, FieldAttribute.REQUIRED)
                .addField("type", String.class, FieldAttribute.REQUIRED);
            schema.get("Person")
                .addRealmListField("pets", petSchema)
                .transform(obj -> { /* 初始化數據 */ });
            oldVersion++;
        }
        
        // v2 → v3: 字段類型變更與可空性調整
        if (oldVersion == 2) {
            schema.get("Person").setNullable("fullName", true);
            schema.get("Pet")
                .addField("type_tmp", int.class)
                .transform(obj -> { /* 字符串轉枚舉 */ })
                .removeField("type")
                .renameField("type_tmp", "type");
        }
    }
};

數據加密

AES-256 加密(64 字節密鑰),性能損耗 <10%。加密後無法用 Browser 查看,每次開啟需提供密鑰:

byte[] key = new byte[64];
new SecureRandom().nextBytes(key);
RealmConfiguration config = new RealmConfiguration.Builder(context)
    .encryptionKey(key)
    .build();
Realm realm = Realm.getInstance(config);

第三方庫整合

GSON 適配

Gson gson = new GsonBuilder()
    .setExclusionStrategies(new ExclusionStrategy() {
        @Override
        public boolean shouldSkipField(FieldAttributes f) {
            return f.getDeclaringClass().equals(RealmObject.class);
        }
        @Override
        public boolean shouldSkipClass(Class<?> clazz) {
            return false;
        }
    })
    .create();

Retrofit 整合

// Retrofit 1.x
RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint("https://api.github.com")
    .setConverter(new GsonConverter(gson))
    .build();

// Retrofit 2.x
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com")
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build();
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved