一、前言
數據庫操作怎能少了INSERT操作呢?下面記錄MyBatis關於INSERT操作的筆記,以便日后查閱。
二、 insert元素 屬性詳解
其屬性如下:
parameterType ,入參的全限定類名或類型別名
keyColumn ,設置數據表自動生成的主鍵名。對特定數據庫(如PostgreSQL),若自動生成的主鍵不是第一個字段則必須設置
keyProperty ,默認值unset,用於設置getGeneratedKeys方法或selectKey子元素返回值將賦值到領域模型的哪個屬性中
useGeneratedKeys ,取值范圍true|false(默認值),設置是否使用JDBC的getGenereatedKeys方法獲取主鍵並賦值到keyProperty設置的領域模型屬性中。MySQL和SQLServer執行auto-generated key field,因此當數據庫設置好自增長主鍵后,可通過JDBC的getGeneratedKeys方法獲取。但像Oralce等不支持auto-generated key field的數據庫就不能用這種方法獲取主鍵了
statementType ,取值范圍STATEMENT,PREPARED(默認值),CALLABLE
flushCache ,取值范圍true(默認值)|false,設置執行該操作后是否會清空二級緩存和本地緩存
timeout ,默認為unset(依賴jdbc驅動器的設置),設置執行該操作的最大時限,超時將拋異常
databaseId ,取值范圍oracle|mysql等,表示數據庫廠家,元素內部可通過`<if test="_databaseId = 'oracle'">`來為特定數據庫指定不同的sql語句
三、一般的INSERT操作——返回值為插入的記錄數目
mapper接口代碼:
-
/**
-
* 添加學生信息
-
* @param student 學生實例
-
* @return 成功操作的記錄數目
-
*/
-
int add(EStudent student);
mapper.xml:
-
<insert id=
"add" parameterType=
"EStudent">
-
insert into TStudent(name, age)
values(
#{name}, #{age})
-
<
/insert
四、執行INSERT操作后獲取記錄主鍵
mapper接口代碼:
-
/**
-
* 添加學生信息
-
* @param student 學生實例
-
* @return 成功操作的記錄數目
-
*/
-
int add(EStudent student);
至於mapper.xml則分為兩種情況了,一種是數據庫(如MySQL,SQLServer)支持auto-generated key field,另一種是數據庫(如Oracle)不支持auto-generated key field的。
1. 數據庫(如MySQL,SQLServer)支持auto-generated key field的情況
手段①(推薦做法):
-
<insert id=
"add" parameterType=
"EStudent" useGeneratedKeys=
"true" keyProperty=
"id">
-
insert into TStudent(name, age)
values(
#{name}, #{age})
-
<
/insert>
手段②:
-
<insert id=
"add" parameterType=
"EStudent">
-
// 下面是SQLServer獲取最近一次插入記錄的主鍵值的方式
-
<selectKey resultType=
"_long" keyProperty=
"id" order=
"AFTER">
-
select @@IDENTITY
as id
-
</selectKey>
-
insert into TStudent(name, age) values(#{name}, #{age})
-
</insert>
由於手段②獲取主鍵的方式依賴數據庫本身,因此推薦使用手段①。
2. 數據庫(如Oracle)不支持auto-generated key field的情況
-
<insert id=
"add" parameterType=
"EStudent">
-
<selectKey keyProperty=
"id" resultType=
"_long"
order=
"BEFORE">
-
select CAST(RANDOM *
100000
as
INTEGER) a
FROM SYSTEM.SYSDUMMY1
-
</selectKey>
-
insert
into TStudent(id, name, age) values(
#{id}, #{name}, #{age})
-
</insert>
注意:mapper接口返回值依然是成功插入的記錄數,但不同的是主鍵值已經賦值到領域模型實體的id中了。
五、 selectKey子元素 詳解
作用:在insert元素和update元素中插入查詢語句。
其屬性如下:
keyProperty ,默認值unset,用於設置getGeneratedKeys方法或selectKey子元素返回值將賦值到領域模型的哪個屬性中
resultType ,keyPropety所指向的屬性類全限定類名或類型別名
order屬性 ,取值范圍BEFORE|AFTER,指定是在insert語句前還是后執行selectKey操作
statementType ,取值范圍STATEMENT,PREPARED(默認值),CALLABLE
注意:selectKey操作會將操作查詢結果賦值到insert元素的parameterType的入參實例下對應的屬性中。並提供給insert語句使用
六、批量插入
方式1:
-
<insert id="add" parameterType="EStudent">
-
<foreach collection="list" item="item" index="index" separator=";">
-
INSERT INTO TStudent(name,age) VALUES(#{item.name}, #{item.age})
-
</foreach>
-
</insert>
上述方式相當語句逐條INSERT語句執行,將出現如下問題:
1. mapper接口的add方法返回值將是最一條INSERT語句的操作成功的記錄數目(就是0或1),而不是所有INSERT語句的操作成功的總記錄數目
2. 當其中一條不成功時,不會進行整體回滾。
方式2(僅限於MSSQL):
-
<insert id=
"add" parameterType=
"EStudent">
-
WITH R
AS
-
<foreach collection=
"list" item=
"item" index=
"index" open=
"(" close=
")" separator=
"union all">
-
SELECT
#{item.name} as a, #{item.age} as b
-
</foreach>
-
INSERT
INTO TStudent(name,age)
SELECT a, b
FROM R
-
</insert>
上述方式解決了方式1中的問題。但該方式僅限於MSSQL
方式3(通用解決方法)方式3(MSSQL):
-
INSERT
INTO TStudent(
name,age)
-
<foreach collection=
"list" item=
"item"
index=
"index"
open=
"("
close=
")" separator=
"union all">
-
SELECT #{item.name}
as a, #{item.age}
as b
-
</foreach>
該方式與方式2效果一樣,若為Oracle則采用
七、總結
關於MyBatis的INSERT操作就總結到這里吧。
尊重原創,轉載來自:http://www.cnblogs.com/fsjohnhuang/p/4078659.html ^_^肥仔John
八、參考
http://mybatis.github.io/mybatis-3/zh/dynamic-sql.html
如果您覺得本文的內容有趣就掃一下吧!捐贈互勉!