轉(zhuǎn)自:http://blog.csdn.net/sinat_30474567/article/details/51395247
一羽德、前言
數(shù)據(jù)庫(kù)操作怎能少了INSERT操作呢?下面記錄MyBatis關(guān)于INSERT操作的筆記迅办,以便日后查閱宅静。
二、 insert元素 屬性詳解
其屬性如下:
- parameterType 站欺,入?yún)⒌娜薅?lèi)名或類(lèi)型別名
- keyColumn 坏为,設(shè)置數(shù)據(jù)表自動(dòng)生成的主鍵名。對(duì)特定數(shù)據(jù)庫(kù)(如PostgreSQL)镊绪,若自動(dòng)生成的主鍵不是第一個(gè)字段則必須設(shè)置
- keyProperty 匀伏,默認(rèn)值unset,用于設(shè)置getGeneratedKeys方法或selectKey子元素返回值將賦值到領(lǐng)域模型的哪個(gè)屬性中
- useGeneratedKeys 蝴韭,取值范圍true|false(默認(rèn)值)够颠,設(shè)置是否使用JDBC的getGenereatedKeys方法獲取主鍵并賦值到keyProperty設(shè)置的領(lǐng)域模型屬性中。MySQL和SQLServer執(zhí)行auto-generated key field榄鉴,因此當(dāng)數(shù)據(jù)庫(kù)設(shè)置好自增長(zhǎng)主鍵后履磨,可通過(guò)JDBC的getGeneratedKeys方法獲取蛉抓。但像Oralce等不支持auto-generated key field的數(shù)據(jù)庫(kù)就不能用這種方法獲取主鍵了
- statementType ,取值范圍STATEMENT,PREPARED(默認(rèn)值),CALLABLE
- flushCache 剃诅,取值范圍true(默認(rèn)值)|false巷送,設(shè)置執(zhí)行該操作后是否會(huì)清空二級(jí)緩存和本地緩存
- timeout ,默認(rèn)為unset(依賴(lài)jdbc驅(qū)動(dòng)器的設(shè)置)矛辕,設(shè)置執(zhí)行該操作的最大時(shí)限笑跛,超時(shí)將拋異常
- databaseId ,取值范圍Oracle|mysql等聊品,表示數(shù)據(jù)庫(kù)廠家飞蹂,元素內(nèi)部可通過(guò)
<if test="_databaseId = '[oracle](http://lib.csdn.net/base/oracle)'">
來(lái)為特定數(shù)據(jù)庫(kù)指定不同的sql語(yǔ)句
三、一般的INSERT操作——返回值為插入的記錄數(shù)目
mapper接口代碼:
/**
* 添加學(xué)生信息
* @param student 學(xué)生實(shí)例
* @return 成功操作的記錄數(shù)目
*/
int add(EStudent student);
mapper.xml:
<insert id="add" parameterType="EStudent">
insert into TStudent(name, age) values(#{name}, #{age})
</insert>
四翻屈、執(zhí)行INSERT操作后獲取記錄主鍵
mapper接口代碼:
/**
* 添加學(xué)生信息
* @param student 學(xué)生實(shí)例
* @return 成功操作的記錄數(shù)目
*/
int add(EStudent student);
至于mapper.xml則分為兩種情況了陈哑,一種是數(shù)據(jù)庫(kù)(如MySQL,SQLServer)支持auto-generated key field,另一種是數(shù)據(jù)庫(kù)(如Oracle)不支持auto-generated key field的伸眶。
1.數(shù)據(jù)庫(kù)(如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>
由于手段②獲取主鍵的方式依賴(lài)數(shù)據(jù)庫(kù)本身惊窖,因此推薦使用手段①。
2. 數(shù)據(jù)庫(kù)(如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接口返回值依然是成功插入的記錄數(shù)厘贼,但不同的是主鍵值已經(jīng)賦值到領(lǐng)域模型實(shí)體的id中了界酒。
五、 selectKey子元素 詳解
作用:在insert元素和update元素中插入查詢(xún)語(yǔ)句涂臣。
其屬性如下:
- keyProperty ,默認(rèn)值unset售担,用于設(shè)置getGeneratedKeys方法或selectKey子元素返回值將賦值到領(lǐng)域模型的哪個(gè)屬性中
- resultType 赁遗,keyPropety所指向的屬性類(lèi)全限定類(lèi)名或類(lèi)型別名
- order屬性 ,取值范圍BEFORE|AFTER族铆,指定是在insert語(yǔ)句前還是后執(zhí)行selectKey操作
- statementType 岩四,取值范圍STATEMENT,PREPARED(默認(rèn)值),CALLABLE
注意:selectKey操作會(huì)將操作查詢(xún)結(jié)果賦值到insert元素的parameterType的入?yún)?shí)例下對(duì)應(yīng)的屬性中。并提供給insert語(yǔ)句使用
六哥攘、批量插入
方式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>
上述方式相當(dāng)語(yǔ)句逐條INSERT語(yǔ)句執(zhí)行剖煌,將出現(xiàn)如下問(wèn)題:1. mapper接口的add方法返回值將是最一條INSERT語(yǔ)句的操作成功的記錄數(shù)目(就是0或1),而不是所有INSERT語(yǔ)句的操作成功的總記錄數(shù)目2. 當(dāng)其中一條不成功時(shí)逝淹,不會(huì)進(jìn)行整體回滾耕姊。
方式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中的問(wèn)題。但該方式僅限于MSSQL
方式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則采用
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 FROM DUAL
</foreach>