MyBatis 增刪改操作核心在於映射檔中 <insert>、<update>、<delete> 標籤的編寫,以及 Java 介面方法的對應。本文詳細講解參數傳遞、主鍵回填、動態 SQL 片段等實戰技巧。
<mapper namespace="com.example.mapper.UserMapper">
<insert id="insertUser" parameterType="com.example.po.User">
INSERT INTO user (username, birthday, sex, address)
VALUES (#{username}, #{birthday}, #{sex}, #{address})
</insert>
</mapper>
關鍵點:parameterType 指向 POJO,#{property} 使用 OGNL 取值,防 SQL 注入。
<insert id="insertUser" parameterType="com.example.po.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (username, birthday, sex, address)
VALUES (#{username}, #{birthday}, #{sex}, #{address})
</insert>
useGeneratedKeys="true":啟用 JDBC getGeneratedKeys。keyProperty="id":將生成的主鍵回填到 POJO 的 id 屬性。keyColumn)。
<insert id="insertUser" parameterType="com.example.po.User">
<selectKey keyProperty="id" resultType="long" order="BEFORE">
SELECT seq_user.nextval FROM dual
</selectKey>
INSERT INTO user (id, username, ...) VALUES (#{id}, #{username}, ...)
</insert>
order="BEFORE":先查序列再插入。keyProperty 對應 POJO 屬性。
public interface UserMapper {
int insertUser(User user);
}
// 測試
@Test
public void testInsert() {
SqlSession session = factory.openSession();
User user = new User();
user.setUsername("mybatis");
user.setSex("1");
user.setBirthday(new Date());
session.insert("com.example.mapper.UserMapper.insertUser", user);
session.commit();
System.out.println("回填 ID:" + user.getId()); // 已回填
session.close();
}
<update id="updateUser" parameterType="com.example.po.User">
UPDATE user
SET username = #{username},
sex = #{sex},
birthday = #{birthday},
address = #{address}
WHERE id = #{id}
</update>
@Test
public void testUpdate() {
SqlSession session = factory.openSession();
User user = new User();
user.setId(27);
user.setUsername("updated");
user.setSex("0");
user.setBirthday(new Date());
user.setAddress("new addr");
session.update("com.example.mapper.UserMapper.updateUser", user);
session.commit();
session.close();
}
<delete id="deleteUser" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
@Test
public void testDelete() {
SqlSession session = factory.openSession();
session.delete("com.example.mapper.UserMapper.deleteUser", 27);
session.commit();
session.close();
}
<update id="updateSelective" parameterType="com.example.po.User">
UPDATE user
<set>
<if test="username != null">username = #{username},</if>
<if test="sex != null">sex = #{sex},</if>
<if test="birthday != null">birthday = #{birthday},</if>
<if test="address != null">address = #{address}</if>
</set>
WHERE id = #{id}
</update>
<set> 會自動移除最後一個逗號,配合 <if> 實現「只更新非空欄位」。
| 場景 | 建議 |
|---|---|
| 批次新增 | 使用 ExecutorType.BATCH + <foreach> 批次插入 |
| 大量更新 | 分批提交,避免長事務鎖表 |
| 異常回滾 | Spring 整合時加 @Transactional,手動管理需 try-catch-finally 中 rollback() |
| 參數型別 | 優先用 POJO,簡單參數用 @Param 或 Map |
| SQL 注入 | 一律用 #{},${} 僅用於表名、排序欄位等不可參數化場景 |
useGeneratedKeys、keyProperty、資料庫是否為自增。WHERE 條件、commit() 是否呼叫、參數名稱是否與 POJO 屬性一致。String 給 int)。MyBatis 增刪改核心:映射檔標籤 + 參數綁定 + 事務提交。掌握主鍵回填(useGeneratedKeys/selectKey)、動態 SQL(set/if/foreach)與批次操作,能應對 90% 的業務場景。