• MyBatis 使用另一个 mapper 中的 resultMap 和 sql


    官方文档: http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html

    官方文档很有用, 一定要仔细看.

    背景

    在查询过程中,经常会遇到关联查询的情况.

    实体类关系, 如下:

    每个实体有自己的 mapper 文件.

    目的

    查询 Blog 时, 把 Author 也一块查出来.

    Blog 不复用 Author 中的配置

    AuthorMapper.xml :

    <mapper namespace="org.hsnotebook.mapper.AuthorMapper">
    	<resultMap id="authorResultMap" type="org.hsnotebook.entity.Author">
    		<id property="id" column="id" />
    		<result property="name" column="name" />
    	</resultMap>
    
    	<select id="selectAuthor" resultMap="authorResultMap">
    		select
    			a.id,
    			a.name,
    		from
    			t_author a
    	</select>
    </mapper>
    

    BlogMapper.xml :

    <mapper namespace="org.hsnotebook.mapper.BlogMapper">
    	<resultMap id="blogResultMap" type="org.hsnotebook.entity.Blog">
    		<id property="id" column="id" />
    		<result property="title" column="title" />
    		<association property="author" javaType="Author">
    			<id property="id" column="a_id" />
    			<result property="name" column="a_name" />
    		</association>
    	</resultMap>
    
    	<select id="selectBlog" resultMap="blogResultMap">
    		select
    			b.id,
    			b.title,
    			b.author_id,
    			a.id as a_id,
    			a.name as a_name,
    		from
    			t_blog b left join t_author a on a.id = b.author_id
    	</select>
    </mapper>
    

    问题

    重复就是最大的问题, Author 加个字段, 这两个 mapper 都需要改.
    这个例子比较简单, 改也好改, 但是:

    • 如果 Author 字段非常多呢?
    • 如果 Blog 还有个联合作者, 叫 CoAuthor 呢?
    • 如果还有另的实体也要对 Author 进行关联查询呢?

    那重复的就不是一次两次的了, 到时候您就改去吧.

    进阶一: 复用 Author 的 resultMap

    association 有两个属性:

    • resultMap 使用这个结果映射
    • columnPrefix

    columnPrefix 的官方说明:

    当连接多个表时,你可能会不得不使用列别名来避免在 ResultSet 中产生重复的列名。指定 columnPrefix 列名前缀允许你将带有这些前缀的列映射到一个外部的结果映射中.

    使用这两个属性, 我们就可以使用 AuthorMapper.xml 中的 resutlMap 了.

    BlogMapper.xml 改成下面这样:

    <mapper namespace="org.hsnotebook.mapper.BlogMapper">
    	<resultMap id="blogResultMap" type="org.hsnotebook.entity.Blog">
    		<id property="id" column="id" />
    		<result property="title" column="title" />
    		<association property="author" resultMap="org.hsnotebook.mapper.AuthorMapper.authorResultMap" columnPrefix="a_">
    		</association>
    	</resultMap>
    
    	<select id="selectBlog" resultMap="blogResultMap">
    		select
    			b.id,
    			b.title,
    			b.author_id,
    			a.id as a_id,
    			a.name as a_name,
    		from
    			t_blog b left join t_author a on a.id = b.author_id
    	</select>
    </mapper>
    

    注意 associationresultMap 中加上了命名空间, 不然是找不到的.

    进阶二: 复用 Author 的 列

    上面只是 resultMap 省了, 可是对应的列还是要一遍一遍地一遍一遍地一遍一遍地...写.

    还好 MyBatis 中可定义 sql 片段, 还可以传变量. 将 Author 的列提取出一个 sql 片段,并定义适当的变量.

    AuthorMapper.xml 改成如下:

    <mapper namespace="org.hsnotebook.mapper.AuthorMapper">
    	<resultMap id="authorResultMap" type="org.hsnotebook.entity.Author">
    		<id property="id" column="id" />
    		<result property="name" column="name" />
    	</resultMap>
    
    	<sql id='authorColumns'>
    		${alias}.id as ${prefix}id,
    		${alias}.name as ${prefix}name
    	</sql>
    
    	<select id="selectAuthor" resultMap="authorResultMap">
    		select
    			<include refid="authorColumns">
    				<property name="alias" value="a" />
    				<property name="prefix" value=""/>
    			</include>
    		from
    			t_author a
    	</select>
    </mapper>
    

    BlogMapper.xml :

    <mapper namespace="org.hsnotebook.mapper.BlogMapper">
    	<resultMap id="blogResultMap" type="org.hsnotebook.entity.Blog">
    		<id property="id" column="id" />
    		<result property="title" column="title" />
    		<association property="author" resultMap="org.hsnotebook.mapper.AuthorMapper.authorResultMap" columnPrefix="a_">
    		</association>
    	</resultMap>
    
    	<select id="selectBlog" resultMap="blogResultMap">
    		select
    			b.id,
    			b.title,
    			b.author_id,
    			<include refid="org.hsnotebook.mapper.AuthorMapper.authorColumns">
    				<property name="alias" value="a" />
    				<property name="prefix" value="a_"/>
    			</include>
    		from
    			t_blog b left join t_author a on a.id = b.author_id
    	</select>
    </mapper>
    

    哒哒! 这样 Author 的 resultMap 和列都可以复用了.

    进阶三

    还没有想到, 有什么好想法, 欢迎留言.

  • 相关阅读:
    ES6 Promise 用法转载
    移动端滚动性能优化
    Python之禅
    Day01~15
    Python
    第一章 Java起源
    IMP-00009: 导出文件异常结束 imp
    浏览器访问网页的详细内部过程
    数据库连接池
    连接数据库 六大步骤
  • 原文地址:https://www.cnblogs.com/hsnotebook/p/10651633.html
Copyright © 2020-2023  润新知