參考:
1.http://liuqing9382.iteye.com/blog/1574864
2.http://blog.csdn.net/ultrani/article/details/9351573
3.mybatis中文文檔
作者前言:
使用Mybatis時,對於不同數據庫比如Oracle、SQL Server、Mysql,它們的主鍵生成策略是不同的:
1. Oracle自增主鍵必須得配一個sequence;
2. SQL Server和Mysql的自增使用自動自增設置的;
3. 對於非自增的主鍵,項目也可以使用數據庫函數來產生唯一主鍵,比如uuid()。
插入操作:
1. 對於類似mysql、SQL Server這樣自增主鍵的表,插入可以不配置插入的主鍵列(在sql中顯式的寫出該id);
2. 類似Oracle這類使用sequence或者uuid()這種數據庫函數產生唯一主鍵,如果不做觸發器之類的設置的話,一般需要在sql中寫出主鍵列的。
獲取主鍵:
mybatis針對以上的不同生成策略以及不同的sql主鍵配置類型,將插入數據返回主鍵的解決方案分為一下幾個情況:
1. 如果使用的數據庫支持自動生成主鍵(如:MySQL 和 SQL Server),那么您就可以簡單地將 useGeneratedKeys 設置為”true”,然后使用 keyProperty 設置你希望自動生成主鍵的字段就可以了。
例如,如果 Author 表使用一個字段自動生成主鍵,那么配置語句就可以修改為:
<insert id="insertAuthor" parameterType="domain.blog.Author" useGeneratedKeys=”true” keyProperty=”id”> insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio}) </insert>
對於useGeneratedKeys和keyProperty屬性的說明如下圖:
2. MyBatis 還有另外一種方式為不支持自動生成主鍵的數據庫及 JDBC 驅動來生成鍵值,下面展示一個能夠隨機生成 ID 的例子(也許你不會這么做,這僅僅是演示 MyBatis 的功能,文檔的詞語,意思像是說至於你做不做,反正我做了):
<insert id="insertAuthor" parameterType="domain.blog.Author"> <selectKey keyProperty="id" resultType="java.lang.integer" order="BEFORE"> select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1 </selectKey> insert into Author (id, username, password, email,bio, favourite_section) values (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR}) </insert>
注意:上面的語句中標紅的文字,添加了selectKey標簽,首先解釋如下圖:
正如上面的解釋我們只要把握住order的設置,在sql語句執行前(BEFORE)或者執行后(AFTER),執行selectKey 語句來獲得主鍵就可以了,如上面例子selectKey首先執行,生成隨機的主鍵,這時候Author對象中的id首先被賦值了,然后才會調用insert 語句。這相當於在您的數據庫中自動生成鍵值,不需要編寫復雜的 java 代碼。
當然,是否需要配置<selectKey>根據情況,只要能保證記錄有主鍵即可,一旦配置了<selectKey>,就可以在執行插入操作時獲取到新增記錄的主鍵。
注意:如果沒有配置<selectKey>那么保存后的對象的主鍵依舊為null。
小結:
通過上面的方案:
1. 我們針對uuid()函數的主鍵返回應該如下:
<insert id="insertTestRole" parameterType="hashmap" > <selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id"> SELECT uuid() </selectKey> insert into testRole(id,name) values(#{id},#{name}) </insert>
2. oracle針對Sequence主鍵而言,隱式主鍵插入前必須指定一個主鍵值給要插入的記錄:
<insert id="AltName.insert" parameterType="AltName"> <selectKey resultType="long" keyProperty="id"> SELECT SEQ_TEST.NEXTVAL FROM DUAL </selectKey> insert into altname(primaryName,alternateName,type)values(#{primaryName},#{alternateName},#{type}) </insert>
或者顯式主鍵:
<insert id="insertEnterprise" parameterType="hashmap"> <selectKey resultType="integer" order="AFTER" keyProperty="ENTERPRISE_ID"> select sq_enterprise.currval from dual </selectKey> insert into m_enterprise (ENTERPRISE_ID,ENTERPRISE_NAME,ENTERPRISE_ADDRESS,ENTERPRISE_INTRODUCTION,ENTERPRISE_ZIP,ENTERPRISE_PHONE,ENTERPRISE_NUMBER) values (sq_enterprise.nextval,#{enterprise_name},#{address},#{introduction},#{zip},#{phone},#{enterprise_number}) </insert>
3. MySql、sql server自增主鍵而言,這類表在插入時不需要主鍵,而是在插入過程自動獲取一個自增的主鍵:
<insert id="AltName.insert" parameterType="AltName"> <selectKey resultType="long" keyProperty="id"> SELECT LAST_INSERT_ID() </selectKey> insert into altname(primaryName,alternateName,type)values(#{primaryName},#{alternateName},#{type}) </insert>
根據獲得自增主鍵的方法,我們還可以:
<insert id="AltName.insert" parameterType="AltName">
<selectKey resultType="long" keyProperty="id">
SELECT @@IDENTITY
</selectKey> insert into altname(primaryName,alternateName,type)values(#{primaryName},#{alternateName},#{type}) </insert>
但是參考http://blog.csdn.net/ultrani/article/details/9351573 中四種獲得自增主鍵的方法利弊分析,作者推薦使用useGeneratedKeys屬性設置來利用JDBC的getGeneratedKeys方法獲得自增主鍵。