MyBatis insert
1. 前言
本小節(jié),我們將一起學(xué)習(xí) MyBatis insert。
在 MyBatis 中,insert 標(biāo)簽對(duì)應(yīng)于 SQL 語(yǔ)句中的 insert 插入;與 select 相比,insert 要簡(jiǎn)單許多,只有當(dāng)需要返回主鍵時(shí),才會(huì)麻煩一些,我們將從簡(jiǎn)單到復(fù)雜來(lái)依次介紹。
2. 定義
慕課解釋?zhuān)篿nsert 標(biāo)簽用于映射 SQL 中的
插入
語(yǔ)句
3. 實(shí)例
3.1 xml 實(shí)例
下面是一個(gè)簡(jiǎn)單的 insert 標(biāo)簽。
<insert id="insertUser" parameterType="com.imooc.mybatis.model.User">
INSERT INTO imooc_user(id,username,age,score) VALUES (#{id},#{username},#{age},#{score})
</insert>
同 select 一樣,每一個(gè) insert 標(biāo)簽都必須有一個(gè)唯一的 id 和可選的 parameterType。標(biāo)簽里面則是真正的 SQL 語(yǔ)句,該語(yǔ)句共有 4 個(gè)參數(shù),分別對(duì)應(yīng) User 類(lèi)的四個(gè)屬性。
3.2 注解實(shí)例
如果不使用 xml 的方式,使用注解也可取得同樣的效果,如下:
@Insert("INSERT INTO imooc_user(username,age,score) VALUES (#{username},#{age},#{score})")
int insertUser(User user);
4. insert 屬性
insert 標(biāo)簽也支持諸多屬性來(lái)改變語(yǔ)句的行為。
其中常見(jiàn)且重要的屬性如下表:
屬性 | 描述 |
---|---|
id | 在命名空間中的唯一標(biāo)識(shí)符 |
parameterType | 語(yǔ)句的參數(shù)類(lèi)型,默認(rèn)可選,MyBatis 會(huì)自動(dòng)推斷 |
flushCache | 設(shè)置為 true 后,只要語(yǔ)句被調(diào)用,都會(huì)導(dǎo)致本地緩存和二級(jí)緩存被清空,默認(rèn)為 false |
timeout | 設(shè)置超時(shí)時(shí)間 |
statementType | STATEMENT,PREPARED 或 CALLABLE 中的一個(gè),默認(rèn)為 PREPARED(預(yù)處理) |
useGeneratedKeys | 取出由數(shù)據(jù)庫(kù)自動(dòng)生成的主鍵,僅對(duì)支持主鍵自動(dòng)生成的數(shù)據(jù)庫(kù)有效,默認(rèn)為 false |
keyProperty | 主鍵的名稱(chēng),必須與useGeneratedKeys 一起使用,默認(rèn)未設(shè)置 |
5. 返回主鍵
select 標(biāo)簽在需要返回被添加記錄的主鍵時(shí),會(huì)稍微復(fù)雜一點(diǎn)。
5.1 自增主鍵
5.1.1 xml 方式
如果使用的數(shù)據(jù)庫(kù),如 MySQL,PostgreSQL,這些數(shù)據(jù)庫(kù)支持自增主鍵,那么得到返回的主鍵只需添加上 useGeneratedKeys 和 keyProperty 兩個(gè)屬性即可。如下:
<insert id="insertUserNoId" useGeneratedKeys="true" keyProperty="id"
parameterType="com.imooc.mybatis.model.User">
INSERT INTO imooc_user(username,age,score) VALUES (#{username},#{age},#{score})
</insert>
在 insertUserNoId 中,我們并未添加上 id 參數(shù),而是使用了數(shù)據(jù)庫(kù)自增主鍵的特性,keyProperty 屬性值對(duì)應(yīng) id 字段的名稱(chēng),這樣當(dāng)語(yǔ)句執(zhí)行成功后,對(duì)象的 id 字段會(huì)被自動(dòng)設(shè)置為返回的 id 值。
5.1.2 注解方式
使用下面的注解方式,同樣可以實(shí)現(xiàn)同樣的效果:
@Insert("INSERT INTO imooc_user(username,age,score) VALUES (#{username},#{age},#{score})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUser(User user);
MyBatis 提供了 Options 注解來(lái)指定方法調(diào)用的行為。
5.2 selectKey 標(biāo)簽
5.2.1 xml 方式
如果使用的數(shù)據(jù)庫(kù)不支持主鍵自增,如 Oracle,MyBatis 提供了 selectKey 標(biāo)簽來(lái)通過(guò) SQL 語(yǔ)句獲得主鍵。
例如:
<insert id="insertUserNoId" parameterType="com.imooc.mybatis.model.User">
INSERT INTO imooc_user(username,age,score) VALUES (#{username},#{age},#{score})
<selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
selectKey 標(biāo)簽必須在 insert 標(biāo)簽里面,selectKey 有 4 個(gè)屬性,它們的作用如下表:
屬性 | 描述 |
---|---|
keyColumn | 數(shù)據(jù)庫(kù)字段名,對(duì)應(yīng)返回結(jié)果集中的名稱(chēng) |
keyProperty | 目標(biāo)字段名稱(chēng),對(duì)應(yīng)Java 對(duì)象的字段名 |
resultType | id字段的類(lèi)型 |
order | 執(zhí)行的順序,在 insert 之前調(diào)用為 BEFORE,之后為 AFTER |
注意,selectKey 中的語(yǔ)句其實(shí)就是 SQL 語(yǔ)句,不同數(shù)據(jù)庫(kù)得到主鍵的語(yǔ)句均不一樣。
5.2.2 注解方式
@Insert("INSERT INTO imooc_user(username,age,score) VALUES (#{username},#{age},#{score})")
@SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "id", before = false, resultType = Long.class)
int insertUser(User user);
selectKey 也有相應(yīng)的注解,不過(guò)配置屬性略有不同,statement 屬性對(duì)應(yīng)標(biāo)簽中的 SQL 語(yǔ)句,而 before 屬性則對(duì)應(yīng)標(biāo)簽中的 order 屬性,若 before 為 false,則 order 對(duì)應(yīng)為 AFTER。
6. 實(shí)踐
下面,我們一起來(lái)實(shí)操鞏固一下。
6.1 例1. 插入用戶(hù)
請(qǐng)使用 MyBatis 完成在 imooc_user 表中插入用戶(hù)的功能。
分析:
按照 MyBatis 的開(kāi)發(fā)模式,先在對(duì)應(yīng) UserMapper.xml 文件中添加插入用戶(hù)的 insert 標(biāo)簽,然后在 UserMapper.java 中增加上對(duì)應(yīng)的方法即可。
步驟:
使用 MyBatis 向數(shù)據(jù)庫(kù)中插入用戶(hù)。由于我們使用的數(shù)據(jù)庫(kù)是 MySQL,因?yàn)橹苯邮褂?useGeneratedKeys 得到自增主鍵。
首先,我們?cè)?UserMapper.xml 文件中添加上對(duì)應(yīng)的 insert 標(biāo)簽:
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id"
parameterType="com.imooc.mybatis.model.User">
INSERT INTO imooc_user(username,age,score) VALUES (#{username},#{age},#{score})
</insert>
然后在 UserMapper.java 中添加對(duì)應(yīng)的方法:
package com.imooc.mybatis.mapper;
import com.imooc.mybatis.model.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
int insertUser(User user);
}
結(jié)果:
通過(guò)如下代碼,我們運(yùn)行 insertUser 方法:
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setUsername("insert test");
user.setAge(100);
user.setScore(100000);
int rows = userMapper.insertUser(user);
System.out.println(rows);
// 一定要提交
session.commit();
session.close();
TIPS: 注意,這里必須通過(guò) commit 方法提交會(huì)話(huà),語(yǔ)句才會(huì)生效。
7. 小結(jié)
- 絕大多數(shù)情況下,我們都不會(huì)在插入時(shí)指定 id 的值,而是通過(guò)數(shù)據(jù)庫(kù)自動(dòng)去生成。
- 不同數(shù)據(jù)庫(kù)獲得主鍵的 SQL 語(yǔ)句也不同,如果通過(guò) selectKey 獲得主鍵,那么一定要注意數(shù)據(jù)庫(kù)廠商之間的差異性。