知识卡片

表数据入口返回多行数据的技巧性权衡

普通读书笔记卡

内容

表数据入口接口本身很简单——几个查找方法加上更新/插入/删除方法,每个方法把输入参数映射成一次SQL调用;因为只管数据读写不涉及领域状态,通常是无状态的。真正有技巧性的地方在于查询该怎么把结果返回出去:即使是根据ID的简单查询也可能对应多个数据项,而很多语言的方法只能返回单值,逼着你在”怎么打包多行结果”上做选择。方案一:返回一个简单的映射(map)结构——能解决问题,但破坏了编译时类型检查,接口也不够显式,字段名拼写错了只能等运行时才报错。方案二:用数据传输对象——需要多创建一个类,但换来类型安全和清晰的接口,而且这个DTO类往往在别处也用得上。方案三:直接返回SQL查询产生的记录集——好处是省事、在.NET这类记录集生态发达的环境下特别顺手,代价是会带来概念混乱(理想情况下内存对象根本不该知道SQL这回事),而且一旦以后想用文件代替数据库,记录集这层依赖会成为障碍。可迁移启发:设计一个跨越技术边界的接口时,”怎么把批量结果传出去”这个看似琐碎的返回值形状问题,往往比接口本身的方法签名更能决定这层封装到底封装得干不干净。

参考来源

- 位置:《企业应用架构模式》第二部分"模式"之"第10章 数据源架构模式"之"10.1 表数据入口"(源文件:_epub-src/OEBPS/Text/000075.html) - 结论依据:原文说明"一种方法是返回某种简单数据结构,如映射……用映射来传递数据不是一种好方法,因为它破坏编译时检查……一种更好的方法是采用数据传输对象……为了保存全部结果,可以返回由SQL查询得到的记录集。这会带来概念上的混乱,因为在理想情况下内存中的对象根本不需要知道SQL接口",直接支撑本卡结论。 - 原始内容:为了保存全部结果,可以返回由SQL查询得到的记录集。这会带来概念上的混乱,因为在理想情况下内存中的对象根本不需要知道SQL接口。另外,如果不容易在自己的代码中创建记录集,那么也很难用文件代替数据库。