以前写过一篇关于DAO职责的文章,近来发现不对,我错了,在反复阅读了《阿里巴巴java开发手册》后,我重构了自己对这部分知识的认知。内容如下:
关于返回值
-
从dao返回的数据,要么是基本数据类型,要么是DO实体。
-
从service返回的数据,要么是基本数据类型,要么是DTO实体。
DAO如何工作
每个DAO应该有一个主表,围绕这个主表产生DO,同时尽量避免联表。
《高性能Mysql》中有这样一段话:
无论如何排序都是一个成本很高的操作,所以从性能角度考虑,应尽可能避免排序或者尽可能避免对大量数据进行排序。
如果 ORDER BY 子句中的所有列来都来自关联的第一个表,那么mysql在关联处理第一个表的时候就进行文件排序。除此之外的所有情况,mysql都会先将关联的结果放到一个临时表中,然后在所有的关联都结束后,再进行文件排序。
仅供参考:我认为思考某段sql应该进入哪个DAO的时候,你需要思考这段SQL的主表是谁,而上面给出的信息,是思考这个问题的一个很不错的提示。
一些小细节
-
mapper的查询条件如果使用枚举来映射数据库表中的字段,不应该在枚举中添加数据库没有的数值,比如用某个数来表示“全部”这个概念(但其实数据库中并没有一个状态值和它对应)。如果你这么做,你会发现当你需要使用集合来配合IN查询的时候,多出来的数值会成为你的麻烦。
-
下层为上层服务,以目标为导向。上层(业务逻辑层)需要什么,下层(数据访问层)就提供什么。而不是下层(数据访问层)有什么,上层(业务逻辑层)使用什么。
-
dao层不提供计算属性,只提供真实存在的属性。(虽然上层看不出来dao提供的属性是真实存在的还是计算出来的,但遵守这一点可以让你的sql与业务逻辑有效隔离。)
-
dao层有两个部分,一是承载实际代码的mapper.xml,一是提供接口的mapper.java。mapper.java要提供清晰明确的参数列表和返回值,禁止使用Map做参数和返回值。
-
任何NEP问题,都由数据使用者来保证。(你要假设任何基本数据类型外的数据都有可能为NULL,并对出现NULL的情况做出处理)
-
对数据库的操作要聚合到特定的接口上,数据查询则不需要。这样有助于控制数据的修改。