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

背景

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

实体类关系, 如下:

每个实体有自己的 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 和列都可以复用了.

进阶三

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

猜你喜欢

转载自www.cnblogs.com/hsnotebook/p/10651633.html