【译】ObjectBox官方文档——关系
【译】ObjectBox官方文档——关系
转载请注明出处
第一次翻译文档,水平有限,如有任何错误和不妥,望指正。此外如想知道与Realm 和 GreenDAO的对比请查看这篇博客
官网:ObjectBox
官方示例:Github
在对象中可以引用其他对象,例如,简单的引用对象或者引用一个 List 对象,在数据库术语中,我们称这些引用 关系 。定义关系的对象我们称其为 源对象,我们把引用的对象称之为 目标对象,所以这个关系是有指向性的。
To-One关系
使用ToOne
类定义 To-One 关系,它是一个针对目标对象的智能代理,会透明地缓存目标对象(?)。例如,一个订单通常由一个客户完成。我们可以对订单类(Order
)进行建模并与客户(Customer
)建立一个一对一关系:
1 | // Customer.java |
现在让我们添加一个客户和一些订单。需要设置相关的 customer 对象,在ToOne实例上调用setTarget()
并放置 order 对象:
1 | Customer customer = new Customer(); |
如果 customer 对象在数据库中还不存在,则 ToOne 将创建并插入它。有关更新关系的细节,请参阅下面的详细信息。
想要获取订单的客户,需要调用 ToOne 的getTarget()
方法:
1 | Order order = boxStore.boxFor(Order.class).get(orderId); |
它使用 ID 进行查找,这在 ObjectBox 中非常快。如果您只需要 ID 而不是整个目标对象,那么就调用getTargetId()
。它可以更高效,因为它根本不涉及数据库。
我们也可以将客户关系移除:
1 | order.customer.setTarget(null); |
注意,这并没有将客户从数据库中删除,它只是将关系分解。
Initialization Magic
您是否注意到在上面的代码示例中,ToOne 字段customer
从未被初始化?为什么代码仍然可以使用customer
而没有任何NullPointerException
?因为字段实际上是初始化的,初始化代码在您的源代码中是不可见的。
ObjectBox gradle 插件将在您的代码执行之前转换您的实体类,以便在构造函数中进行适当的初始化。因此,即使在构造函数代码中,您也可以假设 ToOne 和 ToMany / List 属性已经被初始化,并且已经准备好使用了。
To-Many关系
要定义一个 To-Many 关系,您可以使用类型 List 或 ToMany 类的属性。由于只有 ToOne 类, ToMany 类可以帮助您跟踪更改并将这些更改应用到数据库中。如果您不需要或不想要这些,请使用 List 类型,并自己处理数据库更改。
One-to-Many (1:N)一对多关系
要定义一对多关系,您需要用@backlink
来注释您的关系属性。它连接到目标对象中的一个 To-One 关系。使用客户和订单的例子,我们可以修改客户(Customer)类,使其与订单(Order)有许多关系:
1 | // Customer.java |
@backlink
注释告诉 ObjectBox 它的 ToOne 关系,用于填充订单列表。如果在 Order 类中与多个客户存在关系,您需要显式地指定@backlink(to="Customer")
的名称。
让我们给新客户添加一些订单。ToMany 实现了 Java List 接口,因此我们可以简单地使用它添加:
1 | Customer customer = new Customer(); |
通过访问订单列表,我们可以轻松地获得客户的订单:
1 | Customer customer = boxStore.boxFor(Customer.class).get(customerId); |
remove 与之前一样:
1 | Order order = customer.orders.remove(0); |
Many-to-Many (N:M)多对多关系
要定义多对多关系,只需使用 ToMany 类添加属性。假设学生和老师的例子,这就是一个与很多老师有关系的简单的学生类的例子(( ̄ェ ̄;)):
1 | // Teacher.java |
为学生添加老师就像操作一个列表:
1 | Teacher teacher1 = new Teacher(); |
为了得到一个学生的老师,我们只需要访问这个列表:
1 | Student student1 = boxStore.boxFor(Student.class).get(student1.id); |
如果一个学生离开了课堂,我们可以移除一位老师:
1 | student1.teachers.remove(0); |
更新关系
ToOne和ToMany类可以帮助您维护关系的状态。一旦您的实体拥有了关系,它们将跟踪更改并将更改应用到数据库中。ObjectBox
支持对新版本的关系更新(尚未持久化; ID 为零)和现有的(持久化的; ID 不是零)的实体。
更新 To-One
ToOne 类提供了以下方法来更新关系:
setTarget(entity)
:设置实体(新的或者已存在)为新的关系目标,传null
即清除关系setTargetId(entityId)
:设置与给定 Id 的目标实体的关系;通过0
来清除关系
1 | order.customer.setTarget(customer); // or order.customer.setCustomerId(customer.getId()); |
更新 To-Many
ToMany 类实现java.lang.List
接口,同时为实体添加更改跟踪。如果要向 ToMany 对象添加实体,那么这些实体对象将被放在数据库中。同样地,您也可以将实体从 ToMany 对象中移除。注意,从列表中删除实体实际上并没有从数据库中删除实体;只是关系被清除了。不要忘记将拥有的实体应用到数据库中,以对数据库进行跟踪。
1 | customer.orders.add(order1); |
如果您已经设置了@Id(assignable = true)
并将 ID 设置为尚未添加的源实体,那么将实体添加到或从 ToMany 移除实体将会失败。作为一种变通方法,您可以在修改 ToManys 之前,通过调用customerbox.attach(customer)
(在上面的示例中的第1行之前)来修改这个实体。
树状关系
你可以对树状关系进行建模,使用To-One,To-Many的关系指向它自身:
1 |
|
生成的实体可以让您导航它的父类和子类:
1 | TreeNode parent = entity.parent.getTarget(); |