转载请注明出处 第一次翻译文档,水平有限,如有任何错误和不妥,望指正。此外如想知道与RealmGreenDAO的对比请查看这篇博客 官网:ObjectBox 官方示例:Github

在对象中可以引用其他对象,例如,简单的引用对象或者引用一个 List 对象,在数据库术语中,我们称这些引用 关系 。定义关系的对象我们称其为 源对象,我们把引用的对象称之为 目标对象,所以这个关系是有指向性的。

To-One关系

使用ToOne类定义 To-One 关系,它是一个针对目标对象的智能代理,会透明地缓存目标对象(?)。例如,一个订单通常由一个客户完成。我们可以对订单类(Order)进行建模并与客户(Customer)建立一个一对一关系:

// Customer.java
@Entity
public class Customer {@Id public long id;}// Order.java
@Entity
public class Order {@Id public long id;public ToOne<Customer> customer;}
复制代码

现在让我们添加一个客户和一些订单。需要设置相关的 customer 对象,在ToOne实例上调用setTarget()并放置 order 对象:

Customer customer = new Customer();
Order order = new Order();
order.customer.setTarget(customer);
long orderId = boxStore.boxFor(Order.class).put(order); // puts order and customer
复制代码

如果 customer 对象在数据库中还不存在,则 ToOne 将创建并插入它。有关更新关系的细节,请参阅下面的详细信息。

想要获取订单的客户,需要调用 ToOnegetTarget()方法:

Order order = boxStore.boxFor(Order.class).get(orderId);
Customer customer = order.customer.getTarget(customer);
复制代码

它使用 ID 进行查找,这在 ObjectBox 中非常快。如果您只需要 ID 而不是整个目标对象,那么就调用getTargetId()。它可以更高效,因为它根本不涉及数据库。

我们也可以将客户关系移除:

order.customer.setTarget(null);
boxStore.boxFor(Order.class).put(order);
复制代码

注意,这并没有将客户从数据库中删除,它只是将关系分解。

Initialization Magic

您是否注意到在上面的代码示例中,ToOne 字段customer从未被初始化?为什么代码仍然可以使用customer而没有任何NullPointerException?因为字段实际上是初始化的,初始化代码在您的源代码中是不可见的。

ObjectBox gradle 插件将在您的代码执行之前转换您的实体类,以便在构造函数中进行适当的初始化。因此,即使在构造函数代码中,您也可以假设 ToOneToMany / List 属性已经被初始化,并且已经准备好使用了。

To-Many关系

要定义一个 To-Many 关系,您可以使用类型 ListToMany 类的属性。由于只有 ToOne 类, ToMany 类可以帮助您跟踪更改并将这些更改应用到数据库中。如果您不需要或不想要这些,请使用 List 类型,并自己处理数据库更改。

One-to-Many (1:N)一对多关系

要定义一对多关系,您需要用@backlink来注释您的关系属性。它连接到目标对象中的一个 To-One 关系。使用客户和订单的例子,我们可以修改客户(Customer)类,使其与订单(Order)有许多关系:

// Customer.java
@Entity
public class Customer {@Id public long id;@Backlinkpublic ToMany<Order> orders;}// Order.java
@Entity
public class Order {@Id public long id;public ToOne<Customer> customer;}
复制代码

@backlink注释告诉 ObjectBox 它的 ToOne 关系,用于填充订单列表。如果在 Order 类中与多个客户存在关系,您需要显式地指定@backlink(to="Customer")的名称。

让我们给新客户添加一些订单。ToMany 实现了 Java List 接口,因此我们可以简单地使用它添加:

Customer customer = new Customer();
customer.orders.add(new Order());
customer.orders.add(new Order());
long customerId = boxStore.boxFor(Customer.class).put(customer); // puts customer and orders
复制代码

通过访问订单列表,我们可以轻松地获得客户的订单:

Customer customer = boxStore.boxFor(Customer.class).get(customerId);
for (Order order : customer.orders) {// TODO
}
复制代码

remove 与之前一样:

Order order = customer.orders.remove(0);
boxStore.boxFor(Customer.class).put(customer);
// optional: 也可以从它的Box中删除订单
// boxStore.boxFor(Order.class).remove(order);
复制代码

Many-to-Many (N:M)多对多关系

要定义多对多关系,只需使用 ToMany 类添加属性。假设学生和老师的例子,这就是一个与很多老师有关系的简单的学生类的例子(( ̄ェ ̄;)):

// Teacher.java
@Entity
public class Teacher{@Id public long id;}// Student.java
@Entity
public class Student{@Id public long id;public ToMany<Teacher> teachers;}
复制代码

为学生添加老师就像操作一个列表:

Teacher teacher1 = new Teacher();
Teacher teacher2 = new Teacher();Student student1 = new Student();
student1.teachers.add(teacher1);
student1.teachers.add(teacher2);Student student2 = new Student();
student2.teachers.add(teacher2);// puts students and teachers
boxStore.boxFor(Student.class).put(student1, student2);
复制代码

为了得到一个学生的老师,我们只需要访问这个列表:

Student student1 = boxStore.boxFor(Student.class).get(student1.id);
for (Teacher teacher : student1.teachers) {// TODO
}
复制代码

如果一个学生离开了课堂,我们可以移除一位老师:

student1.teachers.remove(0);
// boxStore.boxFor(Student.class).put(student1);
// 比put更有效率:
student1.teachers.applyChangesToDb();
复制代码

更新关系

ToOne和ToMany类可以帮助您维护关系的状态。一旦您的实体拥有了关系,它们将跟踪更改并将更改应用到数据库中。ObjectBox 支持对新版本的关系更新(尚未持久化; ID 为零)和现有的(持久化的; ID 不是零)的实体。

更新 To-One

ToOne 类提供了以下方法来更新关系:

  • setTarget(entity):设置实体(新的或者已存在)为新的关系目标,传null即清除关系
  • setTargetId(entityId):设置与给定 Id 的目标实体的关系;通过0来清除关系
order.customer.setTarget(customer); // or order.customer.setCustomerId(customer.getId());
orderBox.put(order);
复制代码

更新 To-Many

ToMany 类实现java.lang.List接口,同时为实体添加更改跟踪。如果要向 ToMany 对象添加实体,那么这些实体对象将被放在数据库中。同样地,您也可以将实体从 ToMany 对象中移除。注意,从列表中删除实体实际上并没有从数据库中删除实体;只是关系被清除了。不要忘记将拥有的实体应用到数据库中,以对数据库进行跟踪。

customer.orders.add(order1);
customer.orders.remove(order2);
customerBox.put(customer);
复制代码

如果您已经设置了@Id(assignable = true)并将 ID 设置为尚未添加的源实体,那么将实体添加到或从 ToMany 移除实体将会失败。作为一种变通方法,您可以在修改 ToManys 之前,通过调用customerbox.attach(customer)(在上面的示例中的第1行之前)来修改这个实体。

树状关系

你可以对树状关系进行建模,使用To-One,To-Many的关系指向它自身:

@Entity
public class TreeNode {@Id long id;ToOne<TreeNode> parent;@BackLinkToMany<TreeNode> children;
}
复制代码

生成的实体可以让您导航它的父类和子类:

TreeNode parent = entity.parent.getTarget();
List<TreeNode> children = entity.children;
复制代码

转载于:https://juejin.im/post/5a31d253f265da431b6d3656

【译】ObjectBox官方文档(4)——关系相关推荐

  1. [译] AsyncDisplayKit/Texture 官方文档(1)

    官方文档链接:texturegroup.org/docs/gettin- 开始使用 Texture Texture 的基本单位是 Node,ASDisplayNode 是 UIView 和 CALay ...

  2. [译]1-Key-Value Coding Programming Guide 官方文档第一部分

    Key-Value Coding Programming Guide 官方文档第一部分 2018.9.20 第一次修正 iOS-KVC官方文档第一部分 Key-Value Coding Program ...

  3. redisson使用全解——redisson官方文档+注释(中篇)

    文章目录 八.分布式锁和同步器(重要!) 8.1. 可重入锁(Reentrant Lock) 8.2. 公平锁(Fair Lock) 8.3. 联锁(MultiLock) 8.4. 红锁(RedLoc ...

  4. Python的C语言接口 - 详解官方文档

    Python的C语言接口 - 详解官方文档 索引 Python的C语言接口 - 详解官方文档 介绍 / Introduce 代码标准 / Coding Standards 包含文件 / Include ...

  5. 深入理解Java 8 Lambda表达式(Oracle官方文档版)

    Java 8 问世三年了,9马上也要问世了,所以,嗯,我要开始学8了-- 官方文档:http://docs.oracle.com/javase/tutorial/java/javaOO/lambdae ...

  6. Redis分布式锁(Redlock官方文档的理解)

    Redis分布式锁(Redlock官方文档的理解) 我github博客原文 官网解释 分布式锁在许多不同进程下需要对共享资源进行互斥操作的环境下,十分需要 Redis作者提出了 Redlock 算法 ...

  7. Cassandra 3.x官方文档(1)---关于Cassandra

    写在前面 cassandra3.x官方文档的非官方翻译.翻译内容水平全依赖本人英文水平和对cassandra的理解.所以强烈建议阅读英文版cassandra 3.x 官方文档.此文档一半是翻译,一半是 ...

  8. 《maven官方文档》5分钟开始Maven

    原文地址 前提 你必须明白如何在电脑上安装软件.如果你不知道如何做,请向你学校.办公室里等的人请教下,或者付费给他人让他们解释给你.Maven邮件组不是寻求这个建议的最好地方. 安装 Maven是个J ...

  9. 教你如何阅读Oracle数据库官方文档

    < Ask Oracle官方原创 > Oracle 官方文档 数量庞大,而且往往没有侧重点,让oracle新手看起来很费力.但是,仍有很多Oracle使用者认为任何oracle学习资料都比 ...

  10. oracle语法官方文档,Oracle官方文档必备语法知识

    很多Oracle DBA虽然接触Oracle时间很长,但是一旦想不起语法或找不出相应参数时,习惯百度或谷歌.虽然已经下载了官方文档,但是 Oracle官方文档必备语法知识 [日期:2015-04-21 ...

最新文章

  1. 脑细胞膜等效神经网路12分类实例
  2. Excel—SUMPRODUCT用法指南
  3. 如何使用JavaScript更改元素的类?
  4. liigo:爱可视70平板电脑使用感受,遗憾与满足并存
  5. lemur run PLSA
  6. Docker实战部署JavaWeb项目-基于SpringBoot
  7. CCF认证训练行动路线图
  8. IIS6 部署.Net相关程序问题集锦
  9. 已知背景和物体的均值方差,求最佳分割阈值
  10. php 框架测试,PHP测试框架PHPUnit组织测试操作示例
  11. hook技术截取服务器信息,Windows Hook技术
  12. 木子-数据库-oracle如何创建一个新的实例
  13. 把用户证书安装成系统证书
  14. 写个简单的飞机游戏玩玩
  15. 电阻(5)NTC电阻篇
  16. centos配置启动项_查看centos开机启动项命令 - 老牛博客
  17. 浅析企业即时通讯软件为企业带来的好处有哪些
  18. 好用的实时渲染器不止lumion,上呆猫云工作站,跨过显卡门槛get更多制作搭配……
  19. 【yolov5检测代码简化】Yolov5 detect.py推理代码简化,输入图片,输出图片和结果
  20. 一个简单的ETL开发的过程(informatica)

热门文章

  1. 2021-08-03 SELECT简单查询
  2. 2021-06-28操作表单
  3. Linux shell统计文件数脚本,使用shell脚本巧妙统计文件
  4. java 按两个键_java – 使用调度程序按下多个键
  5. java web 学习网站_我的第一个javaweb学习----模仿社区网站(三)
  6. 冷链场景应用实例解读
  7. 2021-03-08
  8. 面向对象分析和设计的几个关键步骤_超市设计中不容忽视的小细节
  9. html span设置外边距,行内元素内外边距探究:为何span设置上下margin和padding不起效...
  10. 时域上的乘积等于频域上的卷积_图卷积神经网络:Graph Convolutional Networks