MyBatis的學習(五)——關聯對映之主鍵對映
一、主鍵對映的作用
當資料插入操作不關心插入後資料的主鍵(唯一標識),那麼建議使用 不返回自增主鍵值 的方式來配置插入語句,這樣可以避免額外的SQL開銷.
當執行插入操作後需要立即獲取插入的自增主鍵值,比如一次操作中儲存一對多這種關係的資料,那麼就要使用插入後獲取自增主鍵值的方式配置.
mybatis進行插入操作時,如果表的主鍵是自增的,針對不同的資料庫相應的操作也不同。基本上經常會遇到的就是Oracle Sequece 和 Mysql 自增主鍵,解釋如下
二、自動遞增返回主鍵
一對多的那種表結構,在插入多端資料時,需要獲取剛剛儲存了的一端的主鍵。那麼這個時候,上述的配置就無法滿足需要了。為此我們需要使用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(鑑別器) - 使用結果集決定使用哪個結果對映(暫不涉及)
每個元素的用法及屬性我會在之後的部落格中結合使用進行講解。