1. 程式人生 > >MyBatis的學習(五)——關聯對映之主鍵對映

MyBatis的學習(五)——關聯對映之主鍵對映

一、主鍵對映的作用

當資料插入操作不關心插入後資料的主鍵(唯一標識),那麼建議使用 不返回自增主鍵值 的方式來配置插入語句,這樣可以避免額外的SQL開銷.

當執行插入操作後需要立即獲取插入的自增主鍵值,比如一次操作中儲存一對多這種關係的資料,那麼就要使用插入後獲取自增主鍵值的方式配置.

mybatis進行插入操作時,如果表的主鍵是自增的,針對不同的資料庫相應的操作也不同。基本上經常會遇到的就是Oracle SequeceMysql 自增主鍵,解釋如下

二、自動遞增返回主鍵

一對多的那種表結構,在插入多端資料時,需要獲取剛剛儲存了的一端的主鍵。那麼這個時候,上述的配置就無法滿足需要了。為此我們需要使用mybatis提供的<selectKey />來單獨配置針對自增逐漸的處理。

①Oracle Sequence配置

<sql id='TABLE_NAME'>TEST_USER</sql>
	
	<sql id='TABLE_SEQUENCE'>SEQ_TEST_USER_ID.nextval</sql>
	
	<!-- 注意這裡需要先查詢自增主鍵值 -->
	<insert id="insertOrcle" parameterType="User">
		<selectKey keyProperty="id" resultType="int" order="BEFORE">
			select
			<include refid="TABLE_SEQUENCE" />
			from dual
		</selectKey>
		insert into
		<include refid="TABLE_NAME" />
		(ID,NAME,AGE) values ( #{id}, #{name}, #{age} )
	</insert>

當使用了<selectKey />後,在實際的插入操作時,mybatis會執行以下兩句SQL:

在執行插入 語句2 之前,會先執行 語句1 以獲取當前的ID值,然後mybatis使用反射呼叫User物件的setId方法,將 語句1 查詢出的值儲存在User物件中,然後才執行 語句2 這樣就保證了執行完插入後

@Test
	public void testInsertOracle(){
		User u=new User("小毛", 18);
		int count = mapper.insertOrcle(u);
		System.out.println(count>0?"新增成功":"新增失敗");
		System.out.println("新增主鍵是:"+u.getId());
	}

②Mysql自增主鍵配置

針對於Mysql這種自己維護主鍵的資料庫,可以直接使用以下配置在插入後獲取插入主鍵

<sql id='TABLE_NAME'>TEST_USER</sql>
	
	<insert id="insertMySql" useGeneratedKeys="true" keyProperty="id" parameterType="User">
		insert into
		<include refid="TABLE_NAME" />
		( NAME, AGE ) values ( #{name}, #{age} )
	</insert>

當然,由於Mysql的自增主鍵可以通過SQL語句

 select LAST_INSERT_ID();

來獲取的。因此針對Mysql,Mybatis也可配置如下:

<sql id='TABLE_NAME'>TEST_USER</sql>
	
	<!-- 注意這裡需要先查詢自增主鍵值 -->
	<insert id="insertMySql" parameterType="User">
		<selectKey keyProperty="id" resultType="int" order="AFTER"> 
		  SELECT LAST_INSERT_ID()
		</selectKey>
		insert into
		<include refid="TABLE_NAME" />
		(ID,NAME,AGE) values ( #{id}, #{name}, #{age} )
	</insert>

只不過該中配置需要額外的一條查詢SQL!

三、關聯對映作用

在現實的專案中進行資料庫建模時,我們要遵循資料庫設計正規化的要求,會對現實中的業務模型進行拆分,封裝在不同的資料表中,表與表之間存在著一對多或是多對多的對應關係。進而,我們對資料庫的增刪改查操作的主體,也就從單表變成了多表。那麼Mybatis中是如何實現這種多表關係的對映呢?

查詢結果集ResultMap

resultMap元素是 MyBatis中最重要最強大的元素。它就是讓你遠離90%的需要從結果 集中取出資料的JDBC程式碼的那個東西,而且在一些情形下允許你做一些 JDBC 不支援的事 情。     

有人會問,之前的示例中我沒有用到結果集,不是也可以正確地將資料表中的資料對映到Java物件的屬性中嗎?是的。這正是resultMap元素設計的初衷,就是簡單語句不需要明確的結果對映,而很多複雜語句確實需要描述它們的關係。

resultMap元素中,允許有以下直接子元素:

  • constructor - 類在例項化時,用來注入結果到構造方法中(本文中暫不講解)
  • id - 作用與result相同,同時可以標識出用這個欄位值可以區分其他物件例項。可以理解為資料表中的主鍵,可以定位資料表中唯一一筆記錄
  • result - 將資料表中的欄位注入到Java物件屬性中
  • association - 關聯,簡單的講,就是“有一個”關係,如“使用者”有一個“帳號”
  • collection - 集合,顧名思議,就是“有很多”關係,如“客戶”有很多“訂單”
  • discriminator(鑑別器) - 使用結果集決定使用哪個結果對映(暫不涉及)

每個元素的用法及屬性我會在之後的部落格中結合使用進行講解。