【译】ObjectBox官方文档(4)——关系
转载请注明出处 第一次翻译文档,水平有限,如有任何错误和不妥,望指正。此外如想知道与Realm 和 GreenDAO的对比请查看这篇博客 官网: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 将创建并插入它。有关更新关系的细节,请参阅下面的详细信息。
想要获取订单的客户,需要调用 ToOne 的getTarget()
方法:
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 插件将在您的代码执行之前转换您的实体类,以便在构造函数中进行适当的初始化。因此,即使在构造函数代码中,您也可以假设 ToOne 和 ToMany / List 属性已经被初始化,并且已经准备好使用了。
To-Many关系
要定义一个 To-Many 关系,您可以使用类型 List 或 ToMany 类的属性。由于只有 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)——关系相关推荐
- [译] AsyncDisplayKit/Texture 官方文档(1)
官方文档链接:texturegroup.org/docs/gettin- 开始使用 Texture Texture 的基本单位是 Node,ASDisplayNode 是 UIView 和 CALay ...
- [译]1-Key-Value Coding Programming Guide 官方文档第一部分
Key-Value Coding Programming Guide 官方文档第一部分 2018.9.20 第一次修正 iOS-KVC官方文档第一部分 Key-Value Coding Program ...
- redisson使用全解——redisson官方文档+注释(中篇)
文章目录 八.分布式锁和同步器(重要!) 8.1. 可重入锁(Reentrant Lock) 8.2. 公平锁(Fair Lock) 8.3. 联锁(MultiLock) 8.4. 红锁(RedLoc ...
- Python的C语言接口 - 详解官方文档
Python的C语言接口 - 详解官方文档 索引 Python的C语言接口 - 详解官方文档 介绍 / Introduce 代码标准 / Coding Standards 包含文件 / Include ...
- 深入理解Java 8 Lambda表达式(Oracle官方文档版)
Java 8 问世三年了,9马上也要问世了,所以,嗯,我要开始学8了-- 官方文档:http://docs.oracle.com/javase/tutorial/java/javaOO/lambdae ...
- Redis分布式锁(Redlock官方文档的理解)
Redis分布式锁(Redlock官方文档的理解) 我github博客原文 官网解释 分布式锁在许多不同进程下需要对共享资源进行互斥操作的环境下,十分需要 Redis作者提出了 Redlock 算法 ...
- Cassandra 3.x官方文档(1)---关于Cassandra
写在前面 cassandra3.x官方文档的非官方翻译.翻译内容水平全依赖本人英文水平和对cassandra的理解.所以强烈建议阅读英文版cassandra 3.x 官方文档.此文档一半是翻译,一半是 ...
- 《maven官方文档》5分钟开始Maven
原文地址 前提 你必须明白如何在电脑上安装软件.如果你不知道如何做,请向你学校.办公室里等的人请教下,或者付费给他人让他们解释给你.Maven邮件组不是寻求这个建议的最好地方. 安装 Maven是个J ...
- 教你如何阅读Oracle数据库官方文档
< Ask Oracle官方原创 > Oracle 官方文档 数量庞大,而且往往没有侧重点,让oracle新手看起来很费力.但是,仍有很多Oracle使用者认为任何oracle学习资料都比 ...
- oracle语法官方文档,Oracle官方文档必备语法知识
很多Oracle DBA虽然接触Oracle时间很长,但是一旦想不起语法或找不出相应参数时,习惯百度或谷歌.虽然已经下载了官方文档,但是 Oracle官方文档必备语法知识 [日期:2015-04-21 ...
最新文章
- 脑细胞膜等效神经网路12分类实例
- Excel—SUMPRODUCT用法指南
- 如何使用JavaScript更改元素的类?
- liigo:爱可视70平板电脑使用感受,遗憾与满足并存
- lemur run PLSA
- Docker实战部署JavaWeb项目-基于SpringBoot
- CCF认证训练行动路线图
- IIS6 部署.Net相关程序问题集锦
- 已知背景和物体的均值方差,求最佳分割阈值
- php 框架测试,PHP测试框架PHPUnit组织测试操作示例
- hook技术截取服务器信息,Windows Hook技术
- 木子-数据库-oracle如何创建一个新的实例
- 把用户证书安装成系统证书
- 写个简单的飞机游戏玩玩
- 电阻(5)NTC电阻篇
- centos配置启动项_查看centos开机启动项命令 - 老牛博客
- 浅析企业即时通讯软件为企业带来的好处有哪些
- 好用的实时渲染器不止lumion,上呆猫云工作站,跨过显卡门槛get更多制作搭配……
- 【yolov5检测代码简化】Yolov5 detect.py推理代码简化,输入图片,输出图片和结果
- 一个简单的ETL开发的过程(informatica)
热门文章
- 2021-08-03 SELECT简单查询
- 2021-06-28操作表单
- Linux shell统计文件数脚本,使用shell脚本巧妙统计文件
- java 按两个键_java – 使用调度程序按下多个键
- java web 学习网站_我的第一个javaweb学习----模仿社区网站(三)
- 冷链场景应用实例解读
- 2021-03-08
- 面向对象分析和设计的几个关键步骤_超市设计中不容忽视的小细节
- html span设置外边距,行内元素内外边距探究:为何span设置上下margin和padding不起效...
- 时域上的乘积等于频域上的卷积_图卷积神经网络:Graph Convolutional Networks