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 和列都可以復用了.

進階三

還沒有想到, 有什么好想法, 歡迎留言.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM