MyBatis insert
1. 前言
本小節,我們將一起學習 MyBatis insert。
在 MyBatis 中,insert 標簽對應于 SQL 語句中的 insert 插入;與 select 相比,insert 要簡單許多,只有當需要返回主鍵時,才會麻煩一些,我們將從簡單到復雜來依次介紹。
2. 定義
慕課解釋:insert 標簽用于映射 SQL 中的
插入
語句
3. 實例
3.1 xml 實例
下面是一個簡單的 insert 標簽。
<insert id="insertUser" parameterType="com.imooc.mybatis.model.User">
INSERT INTO imooc_user(id,username,age,score) VALUES (#{id},#{username},#{age},#{score})
</insert>
同 select 一樣,每一個 insert 標簽都必須有一個唯一的 id 和可選的 parameterType。標簽里面則是真正的 SQL 語句,該語句共有 4 個參數,分別對應 User 類的四個屬性。
3.2 注解實例
如果不使用 xml 的方式,使用注解也可取得同樣的效果,如下:
@Insert("INSERT INTO imooc_user(username,age,score) VALUES (#{username},#{age},#{score})")
int insertUser(User user);
4. insert 屬性
insert 標簽也支持諸多屬性來改變語句的行為。
其中常見且重要的屬性如下表:
屬性 | 描述 |
---|---|
id | 在命名空間中的唯一標識符 |
parameterType | 語句的參數類型,默認可選,MyBatis 會自動推斷 |
flushCache | 設置為 true 后,只要語句被調用,都會導致本地緩存和二級緩存被清空,默認為 false |
timeout | 設置超時時間 |
statementType | STATEMENT,PREPARED 或 CALLABLE 中的一個,默認為 PREPARED(預處理) |
useGeneratedKeys | 取出由數據庫自動生成的主鍵,僅對支持主鍵自動生成的數據庫有效,默認為 false |
keyProperty | 主鍵的名稱,必須與useGeneratedKeys 一起使用,默認未設置 |
5. 返回主鍵
select 標簽在需要返回被添加記錄的主鍵時,會稍微復雜一點。
5.1 自增主鍵
5.1.1 xml 方式
如果使用的數據庫,如 MySQL,PostgreSQL,這些數據庫支持自增主鍵,那么得到返回的主鍵只需添加上 useGeneratedKeys 和 keyProperty 兩個屬性即可。如下:
<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 參數,而是使用了數據庫自增主鍵的特性,keyProperty 屬性值對應 id 字段的名稱,這樣當語句執行成功后,對象的 id 字段會被自動設置為返回的 id 值。
5.1.2 注解方式
使用下面的注解方式,同樣可以實現同樣的效果:
@Insert("INSERT INTO imooc_user(username,age,score) VALUES (#{username},#{age},#{score})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUser(User user);
MyBatis 提供了 Options 注解來指定方法調用的行為。
5.2 selectKey 標簽
5.2.1 xml 方式
如果使用的數據庫不支持主鍵自增,如 Oracle,MyBatis 提供了 selectKey 標簽來通過 SQL 語句獲得主鍵。
例如:
<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 標簽必須在 insert 標簽里面,selectKey 有 4 個屬性,它們的作用如下表:
屬性 | 描述 |
---|---|
keyColumn | 數據庫字段名,對應返回結果集中的名稱 |
keyProperty | 目標字段名稱,對應Java 對象的字段名 |
resultType | id字段的類型 |
order | 執行的順序,在 insert 之前調用為 BEFORE,之后為 AFTER |
注意,selectKey 中的語句其實就是 SQL 語句,不同數據庫得到主鍵的語句均不一樣。
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 也有相應的注解,不過配置屬性略有不同,statement 屬性對應標簽中的 SQL 語句,而 before 屬性則對應標簽中的 order 屬性,若 before 為 false,則 order 對應為 AFTER。
6. 實踐
下面,我們一起來實操鞏固一下。
6.1 例1. 插入用戶
請使用 MyBatis 完成在 imooc_user 表中插入用戶的功能。
分析:
按照 MyBatis 的開發模式,先在對應 UserMapper.xml 文件中添加插入用戶的 insert 標簽,然后在 UserMapper.java 中增加上對應的方法即可。
步驟:
使用 MyBatis 向數據庫中插入用戶。由于我們使用的數據庫是 MySQL,因為直接使用 useGeneratedKeys 得到自增主鍵。
首先,我們在 UserMapper.xml 文件中添加上對應的 insert 標簽:
<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 中添加對應的方法:
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);
}
結果:
通過如下代碼,我們運行 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: 注意,這里必須通過 commit 方法提交會話,語句才會生效。
7. 小結
- 絕大多數情況下,我們都不會在插入時指定 id 的值,而是通過數據庫自動去生成。
- 不同數據庫獲得主鍵的 SQL 語句也不同,如果通過 selectKey 獲得主鍵,那么一定要注意數據庫廠商之間的差異性。