Atlas Device SDK 已弃用。 有关详细信息,请参阅
弃用页面。
本页上的示例使用具有两种 Realm 对象类型的项目管理应用的Realm 数据模型: Project
和Task
。 Project
具有零个或多个Tasks
。
请参阅 Project
和 Task
这两个类的模式,如下所示:
import org.bson.types.ObjectId; |
|
import io.realm.RealmObject; |
import io.realm.annotations.PrimaryKey; |
import io.realm.annotations.RealmClass; |
import io.realm.annotations.Required; |
|
public class ProjectTask extends RealmObject { |
@PrimaryKey |
public ObjectId _id; |
@Required |
public String name; |
public String assignee; |
public int progressMinutes; |
public boolean isComplete; |
public int priority; |
@Required |
public String _partition; |
} |
import org.bson.types.ObjectId; |
|
import io.realm.RealmList; |
import io.realm.RealmObject; |
import io.realm.annotations.PrimaryKey; |
import io.realm.annotations.RealmClass; |
import io.realm.annotations.Required; |
|
public class Project extends RealmObject { |
@PrimaryKey |
public ObjectId _id; |
@Required |
public String name; |
public RealmList<ProjectTask> tasks = new RealmList<>(); |
} |
import io.realm.RealmObject |
import io.realm.annotations.PrimaryKey |
import io.realm.annotations.Required |
import org.bson.types.ObjectId |
|
open class ProjectTask( |
@PrimaryKey |
var _id: ObjectId = ObjectId(), |
@Required |
var name: String = "", |
var assignee: String? = null, |
var progressMinutes: Int = 0, |
var isComplete: Boolean = false, |
var priority: Int = 0, |
var _partition: String = "" |
): RealmObject() |
import io.realm.RealmList |
import io.realm.RealmObject |
import io.realm.annotations.PrimaryKey |
import io.realm.annotations.Required |
import org.bson.types.ObjectId |
|
open class Project( |
@PrimaryKey |
var _id: ObjectId = ObjectId(), |
@Required |
var name: String = "", |
var tasks: RealmList<ProjectTask> = RealmList(), |
): RealmObject() |
在事务中,您可以像更新所选语言中的任何其他对象一样更新 Realm 对象。 只需为属性分配新值或更新属性即可。
以下示例将海龟的名称更改为“Archibald”,并通过为属性分配新值将阿奇博尔德的年龄设置为 101:
realm.executeTransaction(r -> { |
|
Turtle turtle = r.where(Turtle.class).findFirst(); |
|
|
turtle.setName("Archibald"); |
turtle.setAge(101); |
}); |
realm.executeTransaction { r: Realm -> |
|
val turtle = r.where(Turtle::class.java).findFirst() |
|
|
turtle!!.name = "Archibald" |
turtle.age = 101 |
} |
更新或插入是一种写入操作,它可以插入具有给定主键的新对象,也可以更新已具有该主键的现有对象。 我们将其称为更新或插入,因为它是“更新或插入”操作。 当对象可能存在或不存在时(例如将数据集批量导入到现有域中),此功能非常有用。更新或插入是一种在添加新条目时更新现有条目的优雅方法。
以下示例演示了如何使用域更新或更新或插入(upsert)对象。 我们创建一个名为“Drew”的新海龟爱好者,然后使用 insertOrUpdate()将其名称更新为“Andy”:
realm.executeTransaction(r -> { |
ObjectId id = new ObjectId(); |
TurtleEnthusiast drew = new TurtleEnthusiast(); |
drew.set_id(id); |
drew.setName("Drew"); |
drew.setAge(25); |
|
|
r.insertOrUpdate(drew); |
TurtleEnthusiast andy = new TurtleEnthusiast(); |
andy.set_id(id); |
andy.setName("Andy"); |
andy.setAge(56); |
|
|
r.insertOrUpdate(andy); |
}); |
realm.executeTransaction { r: Realm -> |
val id = ObjectId() |
val drew = TurtleEnthusiast() |
drew._id = id |
drew.name = "Drew" |
drew.age = 25 |
|
|
r.insertOrUpdate(drew) |
val andy = TurtleEnthusiast() |
andy._id = id |
andy.name = "Andy" |
andy.age = 56 |
|
|
r.insertOrUpdate(andy) |
} |
您还可以使用copyToRealmOrUpdate()根据提供的对象创建新对象,或更新具有相同主键的现有对象。 使用CHECK_SAME_VALUES_BEFORE_SET
ImportFlag仅更新所提供对象中不同的字段:
以下示例演示了如何插入一个对象,或者,如果已存在具有相同主键的对象,则仅更新那些不同的字段:
realm.executeTransaction(r -> { |
ObjectId id = new ObjectId(); |
TurtleEnthusiast drew = new TurtleEnthusiast(); |
drew.set_id(id); |
drew.setName("Drew"); |
drew.setAge(25); |
|
|
r.insertOrUpdate(drew); |
TurtleEnthusiast andy = new TurtleEnthusiast(); |
andy.set_id(id); |
andy.setName("Andy"); |
|
|
|
r.copyToRealmOrUpdate(andy, ImportFlag.CHECK_SAME_VALUES_BEFORE_SET); |
}); |
realm.executeTransaction { r: Realm -> |
val id = ObjectId() |
val drew = TurtleEnthusiast() |
drew._id = id |
drew.name = "Drew" |
drew.age = 25 |
|
|
r.insertOrUpdate(drew) |
val andy = TurtleEnthusiast() |
andy._id = id |
andy.name = "Andy" |
|
|
r.copyToRealmOrUpdate(andy, |
ImportFlag.CHECK_SAME_VALUES_BEFORE_SET) |
} |
Realm 支持collection的更新。集合更新会同时将同一更新应用于集合中多个对象的特定属性。
以下示例演示了如何更新集合。 由于 Turtle 的owner
属性和 TurtleEnthusiast 的turtles
属性之间存在隐式反向关系,因此当您使用setObject()更新集合中所有海龟的“所有者”属性时,Realm 会自动更新约瑟芬的海龟列表。
realm.executeTransaction(r -> { |
|
TurtleEnthusiast josephine = r.createObject(TurtleEnthusiast.class, new ObjectId()); |
josephine.setName("Josephine"); |
|
|
RealmResults<Turtle> turtles = r.where(Turtle.class).equalTo("name", "Pierogi").findAll(); |
|
|
turtles.setObject("owner", josephine); |
}); |
realm.executeTransaction { r: Realm -> |
|
val josephine = realm.createObject( |
TurtleEnthusiast::class.java, |
ObjectId() |
) |
josephine.name = "Josephine" |
|
|
val turtles = r.where(Turtle::class.java) |
.equalTo("name", "Pierogi") |
.findAll() |
|
|
turtles.setObject("owner", josephine) |
} |
由于 域 collection始终反映最新状态,因此当您迭代collection时,它们可能会出现、消失或更改。要获得可迭代的稳定collection,可以创建collection数据的快照。快照可保证元素的顺序不会更改,即使删除或修改元素也是如此。
Iterator
从RealmResults
创建的对象会自动使用快照。 从RealmList
实例创建的Iterator
对象不使用快照。 使用RealmList.createSnapshot() 或RealmResults.createSnapshot() 要手动生成快照,您可以手动迭代:
以下示例演示了如何使用从RealmResults
Iterator
创建的隐式快照或从RealmList
创建的手动快照安全地迭代集合:
RealmResults<Frog> frogs = realm.where(Frog.class) |
.equalTo("species", "bullfrog") |
.findAll(); |
|
|
realm.executeTransaction(r -> { |
for (Frog frog : frogs) { |
frog.setSpecies("Lithobates catesbeiana"); |
} |
}); |
|
|
realm.executeTransaction(r -> { |
OrderedRealmCollectionSnapshot<Frog> frogsSnapshot = frogs.createSnapshot(); |
for (int i = 0; i < frogsSnapshot.size(); i++) { |
frogsSnapshot.get(i).setSpecies("Lithobates catesbeiana"); |
} |
}); |
val frogs = realm.where(Frog::class.java) |
.equalTo("species", "bullfrog") |
.findAll() |
|
|
realm.executeTransaction { |
for (frog in frogs) { |
frog.species = "Lithobates catesbeiana" |
} |
} |
|
|
realm.executeTransaction { |
val frogsSnapshot = frogs.createSnapshot() |
for (i in frogsSnapshot.indices) { |
frogsSnapshot[i]!!.species = "Lithobates catesbeiana" |
} |
} |