天天看點

MyBatis關聯映射

書接上文。

在實際使用資料庫過程中,使用最多的應該就是查詢了,還一些複雜的查詢。比如,表的内連結(INNER JOIN),交叉連接配接(CROSS JOIN),自連接配接,左外連接配接(LEFT OUTER JOIN),右外連接配接(RIGHT OUTER JOIN), 全外連接配接(FULL OUTER JOIN)。這些查詢的資料如何用MyBatis進行顯示呢?

ResultMap元素是MyBatis中最重要的最強大的元素,它的作用是告訴MyBatis,從結果集中取出的資料要怎樣安置。就像是JDBC中ResultSet中取出的一個元組,使用哪些變量去存儲其中的每一個屬性值。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0 //EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="qiqihaer.mybatis.mapper.PersonMapper">
	<!-- 根據id查詢Person 傳回ResultMap -->
	<select id="selectPersonById" parameterType="int" resultMap="personMap">
		SELECT * FROM t_person WHERE id = #{id}
	</select>
	
	<resultMap id="personMap" type="qiqihaer.mybatis.domain.Person">
		<id property="id" column="id"/>
		<result property="name" column="name"/>
		<result property="sex" column="sex"/>
		<result property="age" column="age"/>
		<!-- 關聯映射,一對一 -->
		<association property="card" column="card_id" 
			select="qiqihaer.mybatis.mapper.CardMapper.selectCardById"
			javaType="qiqihaer.mybatis.domain.Card"/>
	</resultMap>
</mapper>
           

看到第一條的select沒有了屬性resultType取而代之的是resultMap,表示查詢傳回的資料存儲到一個Map集合。集合的内容是接下來的resultMap标簽對應的内容。resultMap裡面的 資料通過get()和set()方法将資料封裝成type屬性中指定的類型。resultMap标簽裡面的id标簽标示資料庫表的主鍵。result用來标記其他的屬性,property表示type指定的傳回類型 的屬性。column就是資料庫中的類型。

就這條語句來說就是,把sql語句select查詢的内容封裝成Person對象,Person對象中的id屬性對應資料庫表中查詢出的主鍵值,資料庫中查詢到的name,sex,age屬性分别對應Person中的name,sex,age屬性。則個特别适合資料庫表中的資料名和封裝類型屬性名不比對的情況。

resultMap中還有一個association标簽。這就是關聯映射的一個例子,Person對象中有一個屬性是身份證Card,Card是一個對象。在資料庫中存儲的時候,顯然,t_person中隻是存儲一個外鍵,指向 t_card的主鍵。但是我們生成Person的時候是想要一個完整的Card對象的。associate就是解決這個問題的,像是在查詢中再次嵌套一層查詢。property,column功能不變,select指向嵌套的查詢的語句,javaType表示,嵌套查詢結果封裝的類型。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0 //EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="qiqihaer.mybatis.mapper.CardMapper">
	<!-- 根據id查詢card,傳回的是 Card對象 -->
	<select id="selectCardById" parameterType="int" resultType="qiqihaer.mybatis.domain.Card">
		SELECT * FROM t_card WHERE id = #{id}
	</select>
</mapper>
           

qiqihaer.mybatis.mapper.CardMapper中也就隻有這麼一個selectCardById 查詢語句。

還有一種情況,需要使用關聯映射。

資料庫中有一張班級表和一張學生表,很明顯,班級表中的一個班級号,在學生表中對應多名學生。對應到Clazz類中學生屬性應該是使用一個集合存儲的。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0 //EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="qiqihaer.mybatis.mapper.ClazzMapper">
	<!-- 根據id查詢班級的資訊,傳回的是resultMap -->
	<select id="selectClazzById" parameterType="int" resultMap="clazzResultMap">
		SELECT * FROM tb_clazz WHERE id = #{id}
	</select>
	<resultMap id="clazzResultMap" type="qiqihaer.mybatis.domain.Clazz">
		<id property="id" column="id"/>
		<result property="code" column="code"/>
		<result property="name" column="name"/>
		<!-- 一對多關聯映射:fetchType="lazy"表示懶加載 
		這裡的column是id,也就是使用資料庫中查詢到的 班級id當作參數傳遞-->
		<collection property="students" column="id" 
			javaType="ArrayList" ofType="qiqihaer.mybatis.domain.Student"
			select="qiqihaer.mybatis.mapper.StudentMapper.selectStudentByClazzId"
			fetchType="lazy">
			<!-- <id property="id" column="id"/>
			<result property="name" column="name"/>
			<result property="sex" column="sex"/>
			<result property="age" column="age"/>	 -->
		</collection>
	</resultMap>
</mapper>
           

這裡就是把上面的的associate标簽程式設計了collection标簽,javaType屬性由javaType和ofType組合代替,javaType表示存儲使用的集合類型,ofType表示集合中的值。select指明集合中的值如何擷取。fetchType屬性取值由lazy和eager,eager表示立即加載,lazy表示懶加載,其不會立即發送sql語句去查詢,而是等到需要的時候采取查詢,正常這樣的一對多的都是用懶加載。

源碼已經上傳資源。

繼續閱讀