第 3 章 · 结果出:结果映射与关联缝合 章节摘要:本章跟着手术的出口走——数据库吐回的二维结果集,如何被缝合成立体的对象图。从 resultType 的自动映射边界讲起,到 ResultMap 的手工对应表,再到一对一 association 与一对多 collection 两类关联缝合术,收在"结果去重与分页错位"两个经典翻车点。读完你能把任何形状的查询结果干净地收进对象。 一条主线 前两章我们把参数送进了手术台。现在把镜头转到另一端:数据库执行完 SQL,还回来的是一张二维表——行、列、值,仅此而已。而业务代码想要的是对象:一个 User 里面挂着一张 IdCard,一个 Customer 名下挂着 List 形式的订单。从平面到立体,这段路就是结果映射要走的。
章节摘要:本章跟着手术的出口走——数据库吐回的二维结果集,如何被缝合成立体的对象图。从 resultType 的自动映射边界讲起,到 ResultMap 的手工对应表,再到一对一 association 与一对多 collection 两类关联缝合术,收在"结果去重与分页错位"两个经典翻车点。读完你能把任何形状的查询结果干净地收进对象。
前两章我们把参数送进了手术台。现在把镜头转到另一端:数据库执行完 SQL,还回来的是一张二维表——行、列、值,仅此而已。而业务代码想要的是对象:一个 User 里面挂着一张 IdCard,一个 Customer 名下挂着 List 形式的订单。从平面到立体,这段路就是结果映射要走的。
本章的病例是一个电商系统里最普通的查询需求:查用户时顺带出证件(一对一),查客户时顺带出订单列表(一对多)。3.1 先弄清自动映射的边界——列名与属性名对得上时框架替你干,对不上时(下划线列名、复杂类型)就得请出 ResultMap 手工对表;3.2 做一对一缝合,比较"一次 join"与"分步查询"两种术式;3.3 做一对多缝合,重点讲透两个坑:不写 id 元素导致对象重复、join 之后分页把数据截丢。
一句金句:ResultMap 是列与属性的对应表,id 元素是去重的手术标记——标记没画准,一张订单就可能被缝成两份。
第一个转折点在 3.1:resultType 不是"能跑就行"的偷懒选项,而是有明确边界的自动机制——边界内它比 ResultMap 更简洁,边界外它静默给你 null 字段。分清边界,才谈得上选型。
第二个转折点在 3.3 的去重实验:很多人第一次遇到"订单列表里同一张订单出现两次"时,直觉去改 SQL,实际上病根在 ResultMap 漏了 id 元素。框架按主键合并重复行的机制一旦讲透,这类问题的排查方向就固定了。
到这里,单条 SQL 的进与出都通了。但真实的查询条件往往在运行期才知道:筛选面板有的字段填了、有的没填。下一章进入手术台的中段——动态 SQL 拼装,讲条件片段如何按需缝合、如何修剪多余的前后缀。