前面進行了 Mybatis 的工具類的抽取,主要提取的是建立 SqlSession 的代碼部分。java
如今來介紹一下 Mybatis 的 update、delete、insert 操做。web
update 操做sql
編寫修改用戶 id 爲 2 的用戶信息的測試類:數據庫
@Test
void testUpdate(){
SqlSession session = MybatisUtil.getSession();
User userUpdate = new User();
userUpdate.setId(2L);
userUpdate.setName("用戶2-afterUpdate");
userUpdate.setSalary(new BigDecimal(100));
session.update("com.mxz.mybatis.mapper.UserMapper.update", userUpdate);
session.close();
}
複製代碼
update 方法的兩個參數含義分別是:session
第一個是經過 mapper.xml 映射文件的命名空間(namespace)+ SQL 元素 id,來找到對應的更新 SQL 語句。mybatis
第二個是傳入該 SQL 語句中要更新的用戶信息的對象。app
在 UserMapper 映射文件中編寫相應的 SQL 語句:dom
<update id="update" parameterType="com.mxz.mybatis.domain.User">
UPDATE t_user SET name = #{name}, salary = #{salary} WHERE id = #{id}
</update>
複製代碼
這裏有兩點要注意:工具
0、update 元素的 parameterType 屬性能夠不用寫,Mybatis 能夠自動推斷出傳入的參數類型。學習
一、#{name}、#{salary}、#{id} 這些 OGNL 表達式中的名稱要跟 User 對象的屬性名稱一致,否則會報錯說反射異常,在 User 類中找不到對應的 getter 方法。
運行測試用例後能夠看到控制檯打印的日誌 SQL:
DEBUG [main] - ==> Preparing: update t_user set name = ?, salary = ? where id = ?
DEBUG [main] - ==> Parameters: 用戶2-afterUpdate(String), 10000(BigDecimal), 2(Long)
DEBUG [main] - <== Updates: 1
複製代碼
第一行是生成的帶有佔位符的預編譯處理語句。
第二行是與佔位符對應的傳入的參數值。
第三行是 DML 語句結果顯示,說明受影響的行數爲 1 行。
執行成功後,可是發現數據庫中對應的數據並無更新,爲何呢?
很明顯是事務沒有提交的問題致使的。
其中緣由是咱們在建立 SqlSession 的時候沒有開啓自動提交事務。
須要開啓的話,在 openSession() 方法中傳入ture 就能夠了:
public class MybatisUtil {
private static SqlSessionFactory factory;
static {
InputStream in = null;
try {
in = Resources.getResourceAsStream("mybatis-config.xml");
} catch (IOException e) {
e.printStackTrace();
}
factory = new SqlSessionFactoryBuilder().build(in);
}
// 返回一個SqlSession對象
public static SqlSession getSession(){
return factory.openSession(true);
}
}
複製代碼
或者測試用例中手動提交事務:
@Test
void testUpdate(){
SqlSession session = MybatisUtil.getSession();
User userUpdate = new User();
userUpdate.setId(2L);
userUpdate.setName("用戶2-afterUpdate");
userUpdate.setSalary(new BigDecimal(100));
session.update("com.mxz.mybatis.mapper.UserMapper.update", userUpdate);
// 提交事務
session.commit();
session.close();
}
複製代碼
delete 操做
編寫刪除用戶 id 爲 1 的用戶信息的測試類:
@Test
void testDelete(){
SqlSession session = MybatisUtil.getSession();
session.delete("com.mxz.mybatis.mapper.UserMapper.delete", 1L);
session.commit();
session.close();
}
複製代碼
對應的 SQL 爲:
<delete id="delete">
delete from t_user where id = #{id}
</delete>
複製代碼
parameterType 屬性能夠不用寫,Mybatis 能夠自動推斷出。
刪除操做傳入的參數爲基本類型,因此 SQL 語句中的 OGNL 表達式 #{id} 的內容能夠亂寫成任意內容,如 #{ooxx},但爲了規範,見名知意,咱們通常寫對應的屬性名稱。
insert 操做
編寫新增一個用戶的測試類:
@Test
void testSave(){
SqlSession session = MybatisUtil.getSession();
User u = new User();
u.setName("用戶-新增");
u.setSalary(new BigDecimal(100));
System.out.println(u);
session.insert("com.mxz.mybatis.mapper.UserMapper.save", u);
session.commit();
session.close();
System.out.println(u);
}
複製代碼
對應的 SQL 爲:
<insert id="save">
insert into t_user (name, salary) values (#{name}, #{salary})
</insert>
複製代碼
insert 元素中的 parameterType 屬性能夠不寫,以及 OGNL 表達式中的內容要與 User 類中的屬性名稱一致,由於傳入的參數爲 User 類對象。
對於 insert 操做,在開發中通常有以下需求:
保存一條新增的數據以後,須要獲得剛剛保存數據生成的主鍵的值。
由於咱們在設計數據庫表的時候,主鍵通常是作成自動生成自動遞增的,並且程序中業務邏輯每每比較多,須要拿到該條數據的主鍵進行其餘的操做。
那如何來獲取自動生成的主鍵呢?
回憶一下,咱們在使用 JDBC 的時候,使用 Connection 建立 prepareStatement,有兩種方式,一種是 connection.prepareStatement(String sql);只傳入一個參數 SQL 語句的建立預編譯處理語句的方法。
還有一種是 connection.prepareStatement(String sql, int autoGenKeyIndex);須要傳入 SQL 語句,和是否應該返回自動生成的鍵的標誌。
使用第二種方法返回自動生成的主鍵以後,而後經過 getGeneratedKeys() 來獲取主鍵的值。
那在 Mybatis 中如何操做呢?
很簡單,看 Mybatis 官方文檔的說明:
使用 useGeneratedKeys 和 keyProperty 兩個屬性。
<insert id="save" useGeneratedKeys="true" keyProperty="id">
insert into t_user (name, salary) values (#{name}, #{salary})
</insert>
複製代碼
useGeneratedKeys 屬性:是否須要返回自動生成的主鍵。
keyProperty 屬性:把自動生成的主鍵值設置到對象的哪一個屬性上。
執行成功後,打印傳入的 User 對象,看到屬性 id 已經有值了,而後經過 getId() 方法就能夠獲取主鍵的值了。
tips:查看官方文檔是學習一門新語言最有效的方法。
系列預告:Mybatis 系列 8:Mybatis 的 typeAlias 別名配置。