Dao 或 mapper 层是面向数据库的,用来对表进行操作
Service 层则是面向对象的,用来对实体进行操作
实体操作的核心是什么?
- 实体的结构:list,tree
- 实体之间的关系:主次,一对一,一对多,多对多
▮实体结构——list
List 的结构不用多说,就是最常见的表结构。我们主要是要设计一些基础属性,如
基础属性:
基础属性 | 解释 |
---|---|
ID | 唯一标识,建议用雪花 |
CreateTime | 创建时间 |
CreateUser | 创建用户 |
UpdateTime | 修改时间 |
UpdateUser | 修改用户 |
Dr | 逻辑删除(0没删,1删除) |
Ts | 时间戳,用来确保数据是最新的 |
雪花作为唯一标识
雪花算法是唯一且自增的,对排序、分库分表都有很好的支持
确保数据最新的
在 update 操作中,如果修改的实体的 ts 小于数据库里的 ts,则说明这次修改没有使用最新数据。在修改的过程中,数据库里数据被其他人修改过了,所以这次 update 不能成功
▮实体结构——tree
tree 也可以说是一种特殊的 list,比 list 多了几个用来关联其它节点的字段而已,毕竟 tree 也可以看做链表的一种。
Tree 结构是可以存入表结构里的,常见的有两种实现方式
- 普通树:pid,depth
- 先序树:left,right,depth
普通树和先序树的区别:
普通树 | 先序树 | |
---|---|---|
增删 | 简单 | 复杂 |
查找父节点 | 简单 | 简单 |
查找子节点 | 简单 | 简单 |
查找孙节点 | 复杂 | 简单 |
查找子孙节点 | 复杂 | 简单 |
查找父节点 | 简单 | 简单 |
查找两节点的共同父节点 | 复杂 | 简单 |
综述,频繁增删用普通树,频繁查询用先序树 |
▮实体的基础 service 接口
每个实体应有的基础 service
Service | 解释 |
---|---|
保存 | 增加(无主键)和修改(有主键) |
保存后返回 | 保存并将实体返回 |
逻辑删除 | dr改为1 |
物理删除 | 直接在表里删除 |
根据条件查一个 | 传入条件,返回一个实体 |
根据条件查多个 | 传入条件,返回实体列表 |
▮实体之间的关系——一对一,一对多,主次
一对一和一对多本质上没有什么区别,但相关联的两个实体通常是有主次之分的。比如在一对一,一对多的关系中,次实体会多一个字段用来指向主实体。因此
- 次实体应有属性来存储主实体的 id
- 次实体应该提供 service(主实体不需要提供额外的 service)
Service 接口 | 解释 |
---|---|
保存并绑定主实体 | 保存的同时也把主实体的 key 绑定上 |
根据主实体删除 | 主实体 key 的匹配项都删除 |
根据主实体查单个 | 主实体key 的匹配项,一对一关系 |
根据主实体查多个 | 主实体 key 的匹配项,一对多关系 |
▮实体之间的关系——多对多
多对多的双方是平等的,没有主次之分。通过都是增加额外的映射表来存储多对多的映射关系。
因次,多对多要加一张映射表,同时也要增加对应的映射服务
MappingService
MappingService 接口 | 解释 |
---|---|
绑定两个实体 | |
解绑两个实体 | |
解绑所有实体绑定 | 传入实体 1 或实体 2,删除所有相关映射 |
查询某个实体的所有绑定 | 传入实体 1 或实体 2,查询所有相关映射 |
查询所有实体 1,根据实体 2 | 这里是查询出实体,而不是映射 |
查询所有实体 2,根据实体 1 | 这里是查询出实体,而不是映射 |