Java 关于数据库 Entity 如何设计

2022-07-28 09:50:43 +08:00
 hahaFck

喜欢写 sql ,所以不想用 hibernate 类似的完全托管访问数据库的框架,一般用 mybatis 之类的将查询结果转换成 entity 。

这种情况下如果类之间有关联关系,在设计 api 的时候大家一般如何做呢。

比如 User 关联 Department ,在 User 里面是用 departmentId 还是 Department 实体,

如果用 id 属性,在一些情况下需要 department 表的信息,就需要二次查询。

用实体 Department 的情况下(查询 User 时增加 left join department ),是很方便访问关联表的数据,但是会遇到下面两个问题:

  1. 如果 Department 又关联了 Organization 属性呢?Organization 又关联了其他的 Entity 呢, 这样一个查询 User 表的数据的 sql 会关联到很多其他的表,而且很多的 sql 语句都是重复使用的,比如查询 DepartmentOrganization 的列字段和直接查询 Department 实体时的字段是一样的,如果 department 表新增加了字段,这几处的 sql 都要改。

2.

5948 次点击
所在节点    程序员
62 条回复
mazhiyuan
2022-07-28 09:57:28 +08:00
为啥有这表设计呢
zhao1014
2022-07-28 09:58:35 +08:00
跟数据库保持一致
hahaFck
2022-07-28 10:00:12 +08:00
@mazhiyuan 不可能都是单表啊,肯定要有关联的。
zmal
2022-07-28 10:00:32 +08:00
不要在 sql 里写业务逻辑。
hahaFck
2022-07-28 10:00:48 +08:00
@zhao1014 那查询时候怎么查呢,把关联的 entity 都给查出来?
hahaFck
2022-07-28 10:01:14 +08:00
@zmal 就是查询,没有复杂的业务逻辑。
zhao1014
2022-07-28 10:03:53 +08:00
@hahaFck 你需要什么就查什么啊,你也说了有些时候需要其他表的信息,那就查第二次,总比你每次需要 user 时都做一次 left join 好吧。
hcven
2022-07-28 10:04:36 +08:00
和数据库保持一致,不要在数据库中 join ,可以先查 user 列表,再获取 user 列表中所有的 departmentId ,departmentId 列表去数据库查,在业务层组装 UserBO
youngforever
2022-07-28 10:06:19 +08:00
和数据库保持一致+1 ,返回给前端的另开 VO ,能不 join 的尽量不要 join ,根据 departmentId 再查一遍
zhangleshiye
2022-07-28 10:08:21 +08:00
@hahaFck 提取业务服务把, 比如用户服务 权限服务, 服务内部可以用多表连接 ,服务之间组装业务对象就在代码层组装。22223
james2013
2022-07-28 10:08:46 +08:00
有封装 mybatis 的框架,比如 Mapper,MyBatis-Plus,单表查询不需要写 sql,直接用 java 代码查出来,有复杂的 sql 再写到 xml 里
zhao1014
2022-07-28 10:12:02 +08:00
假如 User 的字段是 username ,Department 的字段是 departmentName ,前端需要在一次请求中返回 username 和 departmentName ,你需要做的是再封装一个 vo ,字段是 username 和 departmentName ,把 vo 作为返回值,而不是在 User 里面塞一个 Department 对象。

至于怎么为 Vo 填充数据,一句话能不要 left join 就不要 left join 。
Suddoo
2022-07-28 10:14:25 +08:00
@james2013 那还不如写 SQL ,他那个封装的看不到生成的 SQL 语句,后期业务逻辑变更,改动量更大更麻烦
LeegoYih
2022-07-28 10:16:55 +08:00
实体应该是独立的,不应该直接关联另一个实体,不同实体应该划分好边界,也就是 domain 的概念,通过关联表间接关联。

> user
> department
> user_department_relational
hahaFck
2022-07-28 10:24:08 +08:00
@LeegoYih 有这方面好的开源框架么学习学习。
hahaFck
2022-07-28 10:26:05 +08:00
@youngforever 这样的话,有的时候一次能查询出来的数据就要 2-3 次去查数据库了,不知道哪个总时间用的更少。
hahaFck
2022-07-28 10:33:42 +08:00
@LeegoYih 这样感觉也不是很好吧,如果我一个方法需要 user ,department ,organization 三个参数,那就应该建一个 user_department_ organization_relational 类了,这样的话这种类会很多。
sundev
2022-07-28 10:46:17 +08:00
性能的话肯定是直接 SQL 好,但是论扩展性、可复用性的话还是不如多次取值好的
wxf666
2022-07-28 10:47:50 +08:00
怎么感觉有的在说数据库的设计,有的在说 API 的设计……
zhao1014
2022-07-28 10:50:59 +08:00
@hahaFck 假如都像你这样写,且不说业务与数据库混淆的问题,你想拿一个 User ,却需要联表查询其他的表,按你说的,“如果我一个方法需要 user ,department ,organization”,难道要在 User 里塞 department 和 organization ?假如需要的参数更多呢?岂不是要联十几张表?那你这查询得花多长时间?你这么做就算是你只想要 User 不想要其他得东西,你也得联表查。

底层得东西越简单,上层越容易复用,你如果为了一个方法去造一个融合怪,那岂不是会为了更多得方法造更多得融合怪?结果就是冗余一堆垃圾代码,重复得东西到处都是。另外为什么宁愿多次单表也不要联表得问题网上解答多的是。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/869153

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX