MyBatis XML映射复杂关联模型:重复对象与标签失效问题
MyBatis高级结果映射问题解答
问题1:为何生成不同的Author对象,如何实现共享同一对象?
MyBatis默认在结果映射时,每处理一条关联数据就会创建新的对象实例——它默认没规则识别需要复用同一对象。
要让Blog和Post共享堆内存中同一个Author对象,按以下方式配置即可:
- 先给
Author定义带id属性的resultMap,这个id对应Author的唯一标识字段(比如author_id),MyBatis会依据这个标识缓存、复用对象:
<resultMap id="AuthorResultMap" type="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> <!-- 其他字段映射 --> </resultMap>
- 之后在Blog和Post的
resultMap里,都通过association标签引用这个AuthorResultMap,而非单独定义映射:
<!-- Blog的resultMap --> <resultMap id="BlogResultMap" type="Blog"> <id property="id" column="blog_id"/> <association property="author" resultMap="AuthorResultMap"/> <collection property="posts" resultMap="PostResultMap"/> </resultMap> <!-- Post的resultMap --> <resultMap id="PostResultMap" type="Post"> <id property="id" column="post_id"/> <association property="author" resultMap="AuthorResultMap"/> <!-- 其他字段映射 --> </resultMap>
当查询结果中author_id相同时,MyBatis会复用之前创建的Author对象,确保Blog和Post的Author指向堆内存中的同一个实例。
问题2:官网示例中的<association property="author" javaType="Author"/>标签为何无法生效?
官网示例里的这个标签只是声明了关联属性的类型,但没提供任何数据映射规则——MyBatis不知道该从查询结果的哪些列取Author数据,也不知道怎么把这些数据映射到Author对象的属性上。
要让标签生效,必须补充映射配置:
- 如果是嵌套结果映射(从同一条SQL结果里取关联数据),要指定
resultMap属性关联到Author的完整映射,或者在association标签内部定义具体的<id>、<result>映射; - 如果是嵌套查询(通过额外SQL查询关联数据),要指定
select属性指向查询Author的SQL语句ID,同时用column属性传递查询参数。
只写<association property="author" javaType="Author"/>相当于只告诉MyBatis“这个属性是Author类型”,但没说怎么填充数据,所以Post的Author会是null。
内容的提问来源于stack exchange,提问作者mindw0rk
相关产品推荐
相关产品推荐

