Replies: 1 comment
-
不考虑指针形态的组合,理由也是非常简单:
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
需求分析
目前来说,我们仅仅支持最为简单的模型定义。但是在大多数场景下,用户会考虑使用组合来定义模型。例如常见的是公司有规范,所有的数据库表都必须有创建时间和更新时间。在这种情况下,最好的解决方案就是大家都组合一个公共的结构体,例如:
在这种情况下,我们认为
User
对应的表含有三个列:id
,create_time
和update_time
。场景分析
除了前面提到的这种最简单的组合形式以外,用户可能定义一些比较奇怪的组合形式。
指针组合
目前我们不需要支持 UserV1 这种形态,即不支持使用指针的组合。目前想象不到在 ORM 场景中,有什么是必须要使用这种形态来解决的。
多重组合
这种虽然罕见,但是可以考虑支持。
嵌套组合
即组合套组合。
嵌套组合在复杂的企业级应用中可能会出现,所以可以考虑支持这种形态。那么结合前面多重组合,那么这种形态也是可以的:
字段冲突
在简单的模型定义里面,是不存在字段冲突的情况的,因为编译期会直接报错。但是在引入了组合之后,那么字段冲突就变可能了。冲突可能是内部结构体字段和外部结构体字段冲突,也可能是多重嵌套不同内部结构体之间的字段冲突。例如:
或者:
在 eorm 中,组合被认为是同一张表,而同一张表是不允许出现重复列的。我们的选择是,如果碰到冲突列,我们会报错。等到将来综合用户反馈,再进一步考虑要不要放松这个限制。
忽略组合
某些时候用户希望忽略掉组合。例如说:
组合与普通字段的区别
另外还有一点需要澄清,即组合和普通字段在模型定义上的不同语义:
关键在于,在使用组合的情况下,我们认为它们是同一张表;而定义成 UserV3 这种普通字段,我们认为它更加接近于关联关系,即一对多,多对一等。
功能需求
从前面的场景分析可以总结下来,我们需要做到的是:
同样地,组合的内部结构体字段也可以使用
eorm
标签,用于定义列的别名等。非功能需求
在引入组合之后,影响最大的就是性能,而且使用组合的性能必然比不使用组合的性能差。因为组合难免会引入递归计算之类的问题。很显然,这样会比普通的结构体消耗更多的 CPU 资源和内存资源。
行业方案
简单来说,支持组合应该算是 ORM 里面的标准。GORM,Beego ORM,ENT,Vitess 都支持组合,虽然他们从程度上来说各不相同。因为我们在场景分析里面已经做出了决定究竟要支持什么样的组合,所以这里就不必深入探究它们对组合的支持程度。
设计
支持组合主要影响的是
这两个部分可以看做是 eorm 的核心模块,因为相应的,CRUD 等各种查询也会间接收到影响。
详细设计
模型元数据解析
目前我们已经有了一个接口和一个实现:
那么修改就局限于在它的
Register
方法。这个Register
无可避免要使用递归来解析元数据:要点是:
Register
不再直接解析字段,而是依赖于parseField
进行解析parseField
会遍历字段,如果一个字段是组合,那么就递归解析parseField
在递归解析组合的时候,会检测字段有没有冲突Value 读字段
目前我们设计的
Value
接口,只含有一个方法:并且只有一个基于反射的实现
reflectValue
。所以在支持组合之后要考虑如何读取到组合的字段,例如在模型定义为:如果发起调用
val.Field("CreateTime")
,那么应该返回BaseEntity.CreateTime
的值。解决方案是引入祖先概念。在
ColumnMeta
里面新加一个字段:那么
reflecValue
的取值逻辑就变成:相应地,要在前面的
parseFields
里面加上相应的计算Ancestors
的逻辑。IgnoreFieldsOption
这个方法也要考虑支持忽略组合:
测试
单元测试
单元测试要覆盖功能需求里面的场景:
同时要考虑这些场景混合在一起:
集成测试
N/A。
基准测试
要对
Register
方法和Field
进行基准测试,要考虑三种情况:模糊测试
需要对
Field
进行模糊测试。同样需要考虑三种情况:Beta Was this translation helpful? Give feedback.
All reactions