CRUD - Java SDK
写入操作
您可以在 域 中创建对象、更新域 中的对象,以及最终从 域 中删除对象。 由于这些操作会修改域的状态,因此我们将其称为写入。
Realm 通过事务来处理写入。 事务是一系列读写操作,Realm 将其视为单个不可分割的操作。 换言之,事务是“全有或全无”:事务中的所有操作要么成功,要么事务中的所有操作都不生效。
注意
所有写入都必须在事务中进行。
一个域一次只允许一个打开的写事务(write transaction)。Realm 会阻止其他线程上的其他写入,直到打开的事务完成。 因此,在事务中从 Realm 读取值时,不存在争用情况。
完成事务后,Realm 要么提交事务,要么取消事务:
当 Realm提交事务时,Realm 会将所有更改写入磁盘。 对于同步 Realm,Realm 会将更改排队以便与 Atlas App Services 同步。
当 Realm取消写事务或事务中的操作导致错误时,所有更改都将被丢弃(或“回滚”)。
提示
Realm 对象写入属于文件写入
每当您创建、更新或删除 Realm 对象时,您的更改都会更新该对象在 Realm 中的表示,并向任何订阅的侦听器发出通知。 因此,您应该仅在必要时写入 Realm 对象以持久保存数据。
重要
UI 线程上的同步读写
默认情况下,您只能使用异步事务在应用程序的 UI 线程中读取或写入 Realm。 也就是说,除非您明确允许使用同步方法,否则您只能在 Android 应用程序的主线程中使用名称以单词Async
结尾的 Realm
方法。
此限制是为了应用程序用户的利益:在 UI 线程上执行读写操作,可能导致 UI 交互无响应或速度缓慢,所以通常来说,最好以异步方式或在后台线程中处理这些操作。但是,如果应用程序需要在 UI 线程上使用同步 Realm 读取或写入,则可以通过以下 SyncConfiguration
选项明确支持使用同步方法:
SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION) .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build(); Realm.getInstanceAsync(config, new Realm.Callback() { public void onSuccess(Realm realm) { Log.v( "EXAMPLE", "Successfully opened a realm with reads and writes allowed on the UI thread." ); } });
val config = SyncConfiguration.Builder(app.currentUser(), PARTITION) .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build() Realm.getInstanceAsync(config, object : Realm.Callback() { override fun onSuccess(realm: Realm) { Log.v("EXAMPLE", "Successfully opened a realm with reads and writes allowed on the UI thread.") } })
托管对象
托管对象是实时 Realm 对象,会根据 Realm 中底层数据的变更进行更新。 托管对象只能来自开放的 Realm,并且只要该 Realm 保持打开状态,就会接收更新。 托管对象不能在线程之间传递。
非托管对象
非托管对象是非实时Realm对象的实例。 您可以通过自己手动构造Realm 对象,或调用 Realm .copyFromRealm()来获取非托管对象。 非托管对象可以在线程之间传递。
运行事务
Realm 将每个事务表示为包含零个或多个读写操作的回调函数。 要运行事务,请定义事务回调并将其传递给 Realm 的write
方法。 在此回调中,您可以在 Realm 上自由创建、读取、更新和删除。 如果回调中的代码在 Realm 运行时抛出异常,Realm 将取消事务。 否则,Realm 会在回调后立即提交事务。
例子
以下代码演示如何使用executeTransaction()或executeTransactionAsync()运行事务。如果回调中的代码抛出异常,Realm 将取消事务。 否则,Realm 将提交事务。
realm.executeTransaction(r -> { // Create a turtle enthusiast named Ali. TurtleEnthusiast ali = r.createObject(TurtleEnthusiast.class, new ObjectId()); ali.setName("Ali"); // Find turtles younger than 2 years old RealmResults<Turtle> hatchlings = r.where(Turtle.class).lessThan("age", 2).findAll(); // Give all hatchlings to Ali. hatchlings.setObject("owner", ali); });
realm.executeTransaction { r: Realm -> // Create a turtle enthusiast named Ali. val ali = r.createObject(TurtleEnthusiast::class.java, ObjectId()) ali.name = "Ali" // Find turtles younger than 2 years old val hatchlings = r.where(Turtle::class.java).lessThan("age", 2).findAll() // Give all hatchlings to Ali. hatchlings.setObject("owner", ali) }