CRUD - 读取 - C++ SDK
在此页面上
您可以通过查找、筛选和排序对象来读回存储在 Realm 中的数据。
Realm 读取一般包括以下步骤:
从 Realm 中获取特定类型的所有对象。
(可选)筛选结果。
查询操作返回结果集合。 这些集合是实时的,这意味着它们始终包含关联查询的最新结果。
读取特征
围绕这三个关键读取特征设计应用的数据访问模式,以尽可能高效地读取数据。
结果不是副本
查询结果不是数据的副本。 修改查询结果会直接修改磁盘上的数据。 这种内存映射还意味着结果是实时的:也就是说,它们始终反映磁盘上的当前状态。
结果出现延迟
Realm 仅在您实际请求该查询的结果时才运行查询。 这种延迟求值使您能够编写高性能代码来处理大型数据集和复杂查询。 您可以链接多个筛选器操作,而无需额外的工作来处理中间状态。
引用被保留
Realm 对象模型的优势之一是,Realm 会自动将对象的所有关系保留为直接引用。 这使您能够直接通过查询结果遍历关系图。
直接引用或指针允许您直接通过该引用访问相关对象的属性。
当您需要直接使用对象时,其他数据库通常会将对象从数据库存储复制到应用程序内存中。由于应用程序对象包含直接引用,因此您只有一个选项:将每个直接引用所引用的对象从数据库中复制出来(如果需要),或仅复制每个对象的外键并在该对象被访问的情况下使用该键来查询此对象。如果选择将引用的对象复制到应用程序内存中,则可能会为从未访问过的对象占用大量资源;但是,如果选择仅复制外键,引用的对象查找则可能会导致应用程序变慢。
Realm 使用零拷贝活动对象绕过所有这些操作。Realm 对象访问器使用内存映射直接指向数据库存储,因此 Realm 中的对象与应用程序内存中的查询结果没有区别。因此,您可从任一查询结果遍历整个 Realm 的直接引用。
限制查询结果
由于出现延迟求值,因此无需任何特殊机制来限制 Realm 的查询结果。例如,如果您的查询匹配到数千个对象,但您只想加载前十个对象,则只需访问结果集合的前十个元素即可。
分页
借助延迟求值,分页的常见任务变得非常简单。例如,假设您有一个与某一查询关联的结果集合,而该查询可与您 Realm 中的数千个对象匹配。您选择每页显示一百个对象。要前进到任一页面,只需从与目标页面相对应的索引开始访问结果集合中的元素即可。
读取 Realm 对象
查询给定类型的所有对象
要在 Realm 中查询给定类型的对象,请将对象类型 YourClassName
传递给realm::query<T>成员函数。
这将返回一个 Results 对象,代表域中给定类型的所有对象。
auto managedBusinesses = realm.objects<realm::Business>();
根据对象属性筛选查询
筛选器根据一个或多个对象属性的值选择结果子集。 Realm 提供了一个功能齐全的查询引擎,您可以用它来定义筛选器。
auto businessesNamedMongoDB = managedBusinesses.where( [](auto &business) { return business.name == "MongoDB"; });
支持的查询操作符
目前,Realm C++ SDK 支持以下查询操作符:
相等(
==
、!=
)大于/小于(
>
、>=
、<
、<=
)复合查询(
||
、&&
)
检查结果集的大小并访问结果
Realm Results公开成员函数来处理结果。 您可能想要检查结果设立的大小,或访问权限特定索引处的对象。
auto managedBusinesses = realm.objects<realm::Business>(); auto businessesNamedMongoDB = managedBusinesses.where( [](auto &business) { return business.name == "MongoDB"; }); CHECK(businessesNamedMongoDB.size() >= 1); auto mongoDB = businessesNamedMongoDB[0];
此外,您可以遍历结果,或观察结果集的变化。
读取 Map 属性
您可以像检查标准C++映射一样遍历和检查域 映射属性 的值 :
auto employees = realm.objects<realm::Employee>(); auto employeesNamedTommy = employees.where( [](auto &employee) { return employee.firstName == "Tommy"; }); auto tommy = employeesNamedTommy[0]; // You can get an iterator for an element matching a key using `find()` auto tuesdayIterator = tommy.locationByDay.find("Tuesday"); // You can access values for keys like any other map type auto mondayLocation = tommy.locationByDay["Monday"];
读取设置属性
您可以迭代、检查集的大小以及查找集属性中的值:
auto repositories = realm.objects<realm::Repository>(); auto repositoriesNamedDocsRealm = repositories.where([](auto &repository) { return repository.ownerAndName == "mongodb/docs-realm"; }); auto docsRealm = repositoriesNamedDocsRealm[0]; // You can check the size of the set auto numberOfPullRequests = docsRealm.openPullRequestNumbers.size(); // Find an element in the set whose value is 3064 auto it = managedDocsRealm.openPullRequestNumbers.find(3064); // Get a copy of the set that exists independent of the managed set auto openRealmPullRequests = docsRealm.openPullRequestNumbers.detach();
对列表和查询结果进行排序
排序操作允许您配置 Realm 返回列表对象和查询结果的顺序。 您可以根据列表或结果collection中对象的一个或多个属性进行排序。仅当您显式排序时,Realm 才能保证顺序一致。
与使用 std::sort 不同 ,Realm 的排序实现保留了对象的延迟加载。它不会将整个结果集或列表对象拉入内存,而仅在访问时将其加载到内存中。
要排序,请使用一个或多个sort_descriptor对列表或结果集调用.sort()
函数。
sort_descriptor
包括:
作为排序依据的所需键路径,为字符串形式。
一个布尔值,用于指定排序顺序,其中“true”为升序,
false
为降序。
在此示例中,我们按降序对priority
上的结果集进行排序。
auto items = realm.objects<realm::Item>(); // Sort with `false` returns objects in descending order. auto itemsSorted = items.sort("priority", false);
您还可以按多个排序描述符对列表或结果集进行排序。 在此示例中,我们先按升序对assignee
上的列表属性进行排序,然后再按降序对priority
上的列表属性进行排序。
auto sortedListProperty = specificProject.items.sort({{"assignee", true}, {"priority", false}});