Rafy 领域实体框架 - 树型实体功能(自关联表)

简介:

在 Rafy 领域实体框架中,对自关联的实体结构做了特殊的处理,下面对这一功能进行讲解。

 

场景


在开发数据库应用程序时,往往会遇到自关联表的场景。例如,分类信息、组织架构中的部门、文件夹信息等,都是不限制层级的。如下图中操作系统的文件夹:

image

在开发这类程序时,往往是设计一张表,表中的一个可空的外键直接引用这张表本身。对应的实体如下图:

image

而针对这样的场景,许多ORM框架都不做默认的处理,开发者往往每次都要做重复的工作:建立类似结构的表,编写关系处理代码,编写查询代码……而这种场景经常会出现,所以 Rafy 实体框架中,默认就支持了树型实体的一系列功能,来降低重复劳动。

 

功能及使用说明


在 Rafy 中的树型实体功能,只需开发者使用一行代码为指定的实体打开这个功能,框架会自动完成以下工作:

  • 自动添加实体的自引用关系。自动生成数据库自关联表。
  • 自动维护树节点的 TreeIndex 索引。
  • 自带多个查询,用于查询树节点。
  • 查询结果自动转变为树的结构。
  • 支持树节点的按需加载。

下面,将逐一进行讲解。

 

打开树型实体功能


开发者只需使用一行代码即可让指定的实体转变为树型实体。在指定实体的配置代码中,添加下面这行代码即可:

image

 

自动添加实体的自引用关系


实体基类上已经默认带有以下几个属性,来表达树节点之间的关系。

image

当某个实体类型被配置为树型实体时,这几个属性才会有意义。 
SupportTree:指示该实体是否为树型实体。 
TreeIndex:树节点的编码、索引。此属性会映射为数据库中的字段。 
TreePId:该树节点的父节点的 Id。此属性会映射为数据库中的字段。 
TreeParent:该树节点的父节点实体。 
TreeChildren:该树节点的所有子节点集合。

 

自动生成数据库自关联表


运行程序后,该实体对应的表将会自动添加两个字段:TreeIndex、TreePId,如下图:

image

 

自动维护树节点的 TreeIndex 索引


TreeIndex 是树结点的系统编号,由框架自动维护。下图显示了一个正在使用的树的 TreeIndex 的格式:

image

这个属性不但可以用于显示,更重要的是它是树型实体大量功能的结构基础。例如,当查询某个节点下的所有节点时,就是通过 TreeIndex 来进行模糊匹配的。所以这个属性的值非常重要,只能由框架来自行维护,而不能由开发者来设置。

开发者可以通过 TreeParent、TreeChildren、TreePId 等属性来变更节点与节点之间的父子关系,这时,对应的节点的 TreeIndex 则会同时自动变更。

 

树结构的表示


树的结构非常重要,我手画了张草图来表示:

image

主要由三个类型构成整个树:EntityList、Entity、EntityTreeChildren。这个结构可以表示完整的一棵树,也可以表示部分树。其中,EntityList 用于存储树的根节点(如果是部分树,则表示最上层节点);Entity 表示树中的每一个节点;EntityTreeChildren 集合则表示某个节点下的子节点。

另外,EntityTreeChildren 集合可以按需加载。当它还没有进行加载时,遍历整个树只能遍历到当前已经在内存中的树节点。例如,上图中,Root3的子节点没有被加载,1.2.2 的子节点也没有被加载。

那么,如何加载还没有加载到内存中的节点呢?这需要使用到 ITreeComponent 接口中的 LoadAllNodes 方法。EntityList、Entity、EntityTreeChildren 这三个类型都实现了 ITreeComponent 接口,下面是这个接口的定义:

image

另外,可以使用其中的 EachNode 方法来以深度优先的算法遍历整棵树。

 

自带多个查询,用于查询树节点


实体仓库中带有许多查询方法,其中一些是专门为树型实体设计的:

  • GetTreeRoots:查询所有的根节点。
  • GetByTreePId:查找指定树节点的直接子节点。
  • GetByTreeParentIndex:递归查找指定父索引号的节点下的所有子节点。
  • LoadAllTreeParents:递归加载某个节点的所有父节点。使用此方法后,指定节点的父节点将被赋值到它的 TreeParent 属性上。
  • GetAllTreeParents:获取指定索引对应的树节点的所有父节点。 查询出的父节点同样以一个部分树的形式返回。

另外,一些非树实体的查询方法,对于树型实体也是可用的。如 GetAll、GetByParentId 等。但是也会有所区别,例如 GetAll 方法在查询非树实体时,查询出的实体列表中包含所有的实体;但是在查询树型实体时,结果会按照树的结构来进行加载,即列表中只会有根节点,其它节点则分别在根节点的下级节点中。

同时,这些查询往往支持是否使用贪婪加载的参数。以 GetTreeRoots 方法举例,它的接口是这样的:public EntityList GetTreeRoots(EagerLoadOptions eagerLoad = null); 。它在默认情况下只返回根节点,而根节点中的子节点是没有被加载的。但是,我们可以通过参数中的 eagerLoad 来指定,在加载根节点的同时,把所有的子节点都加载上。

 

以上只是对一些接口做一些必要的解释,具体的使用方法及其它的接口,请参照注释及源码中的单元测试。

image

 

限制


说了上面这么多自带的功能,但是 Rafy 中树型实体的设计也有这的限制:一个树型实体类型对应的数据表中,只能存储一棵树。树中的所有节点的 TreeIndex 都必须是唯一的。

 

好了,鉴于篇幅,这篇文章只是简单地讲解了树型实体中的重点概念及功能,并没有深入说明。这是因为,在使用的过程中你会发现,一般情况下用起来非常容易,只需要打开树型实体功能,并调用想要的查询就可以了,用不到特别复杂的 API。如果确实需要深入了解,那么在理解了整个树的结构设计后,再结合帮助、注释以及源码中的单元测试,相信也会比较简单。


本文转自BloodyAngel博客园博客,原文链接:http://www.cnblogs.com/zgynhqf/p/4133511.html,如需转载请自行联系原作者

相关文章
|
6月前
|
存储 缓存 安全
Java字符串缓冲区
字符串缓冲区是用于处理可变字符串的容器,Java中提供了`StringBuffer`和`StringBuilder`两种实现。由于`String`类不可变,当需要频繁修改字符串时,使用缓冲区更高效。`StringBuffer`是一个线程安全的容器,支持动态扩展、任意类型数据转为字符串存储,并提供多种操作方法(如`append`、`insert`、`delete`等)。通过这些方法,可以方便地对字符串进行添加、插入、删除等操作,最终将结果转换为字符串。示例代码展示了如何创建缓冲区对象并调用相关方法完成字符串操作。
138 13
|
网络协议 Java API
SpringBoot整合Elasticsearch-Rest-Client、测试保存、复杂检索
这篇文章介绍了如何在SpringBoot中整合Elasticsearch-Rest-Client,并提供了保存数据和进行复杂检索的测试示例。
SpringBoot整合Elasticsearch-Rest-Client、测试保存、复杂检索
|
10月前
|
编解码
使用媒体查询动态调整文字大小
【10月更文挑战第24天】通过使用媒体查询动态调整文字大小,我们可以更好地适应不同的屏幕环境,为用户提供更舒适的阅读体验。
|
11月前
|
敏捷开发 监控 测试技术
深入理解自动化测试:从理论到实践
自动化测试在软件开发中扮演着至关重要的角色,它不仅提高了测试效率,还确保了软件质量的一致性和可靠性。本文将引导你了解自动化测试的核心概念,探讨其在不同开发阶段的应用,并通过一个简单的代码示例,展示如何实现一个基本的自动化测试脚本。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的见解和实用的技能。
230 1
|
缓存 前端开发 JavaScript
如何减少React中无关组件的重渲染
你是否同我一样,总是会遇到一些莫名其妙的渲染问题,有时为了解决bug,需要耗费相当气力来debug呢?快来一起学习下react re-render 这些小技巧吧,或许能帮你减少组件树中无关组件的重渲染及重挂载,可以提升性能,同时也能提高用户体验哟。 案例代码:https://github.com/buzingar/re-render-demos
2534 5
|
弹性计算 测试技术 固态存储
【ECS测评大赛】ECS C5全方位对比测评、服务搭建(含Alinux 3)
本篇采用AWS对阿里云进行对比参照,将基于用户实例控制台,实例性能各方面参数进行对比,以及整体服务运行对服务器资源消耗情况,并且您还可以看到分别使用CentOS 7和Alinux 3分别搭建LAMP,LNMP环境,在后面会展现出常规用户使用案例,如wordpress博客搭建,Discuz!论坛搭建,KodCloud系统搭建,NextCloud云盘搭建,私人NAS搭建,极狐GitLab 一体化 DevOps 平台搭建 对应的阿里云社区视频为:https://developer.aliyun.com/live/249082,只涉及部分服务搭建
39660 27
【ECS测评大赛】ECS C5全方位对比测评、服务搭建(含Alinux 3)
|
运维 数据可视化 前端开发
学会这个Thread Dump分析工具,让您秒变性能分析大师!
学会这个Thread Dump分析工具,让您秒变性能分析大师!
1794 0
学会这个Thread Dump分析工具,让您秒变性能分析大师!
|
Web App开发 自然语言处理 机器人
十行代码即可为你的网站添加语音小助手,无需任何外部依赖
前面一篇文章有讲到通过 Web Speech API 来朗诵诗歌,写了个诗歌朗诵的小网站。 而 Web Speech API 除了语音输出外,还支持语音识别,你可以通过 Web Speech API 收集用户的语音指令,为你的网站添加一些有趣的功能:比如在小说阅读网站上添加语音指令,让你可以语音控制翻书、下一章等,让你可以更方便的一边看小说一边吃薯片。🐶
十行代码即可为你的网站添加语音小助手,无需任何外部依赖
|
Java Nacos 开发者
【On Nacos】SpringBoot 方式使用 Nacos
本文介绍下如何在 Spring Boot 项目中使用 Nacos,Nacos 主要分为两个部分,配置中心和服务注册与发现。在使用 Spring Boot 项目中使用 Nacos ,首先要保证启动一个 Nacos 服务,具体可以参考[【快速上手 Nacos】](https://github.com/li-xiao-shuang/on-nacos/blob/master/docs/%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B%20Nacos.md)来搭建一个单机的 Nacos 服务。
850 0
【On Nacos】SpringBoot 方式使用 Nacos
|
Web App开发 供应链 大数据
【菜鸟网络系列研究】第四方物流体如何统筹第三方物流
【菜鸟网络系列研究】第四方物流体如何统筹第三方物流
1608 0
【菜鸟网络系列研究】第四方物流体如何统筹第三方物流

热门文章

最新文章