MyBatis insert 預設返回影響行數,無法直接獲取資料庫生成的主鍵值。需透過配置實現主鍵回寫至實體物件。
MySQL AUTO_INCREMENT、PostgreSQL SERIAL、SQL Server IDENTITY
<insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="User">
INSERT INTO users (username, email) VALUES (#{username}, #{email})
</insert>
useGeneratedKeys="true":啟用 JDBC getGeneratedKeys()keyProperty="id":將生成的主鍵設回實體的 id 屬性keyProperty="id1,id2" keyColumn="col1,col2"Oracle、PostgreSQL、DB2、H2
<insert id="insert" parameterType="User">
<selectKey keyProperty="id" resultType="long" order="BEFORE">
SELECT seq_users.NEXTVAL FROM dual
</selectKey>
INSERT INTO users (id, username, email) VALUES (#{id}, #{username}, #{email})
</insert>
order="BEFORE":先查 Sequence 再插入resultType:Sequence 返回型別<insert id="insert" parameterType="User">
<selectKey keyProperty="id" resultType="string" order="BEFORE">
SELECT REPLACE(UUID(), '-', '') -- MySQL
-- SELECT SYS_GUID() FROM dual -- Oracle
</selectKey>
INSERT INTO users (id, username, email) VALUES (#{id}, #{username}, #{email})
</insert>
<insert id="insertOrder" useGeneratedKeys="true" keyProperty="orderId" keyColumn="order_id">
INSERT INTO orders (customer_id, total) VALUES (#{customerId}, #{total})
</insert>
<insert id="insertOrderItem" parameterType="OrderItem">
INSERT INTO order_items (order_id, product_id, qty)
VALUES (#{orderId}, #{productId}, #{qty})
</insert>
@Insert("INSERT INTO users (username, email) VALUES (#{username}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
Long insert(User user);
ExecutorType.BATCH 時 useGeneratedKeys 可能不支援(視驅動而定)IDENTITY COLUMN,可改用 useGeneratedKeyskeyColumn 指定資料庫欄位名,避免映射錯誤MyBatis 採用 JDBC PreparedStatement.getGeneratedKeys() 或 selectKey 子查詢,在 DefaultResultSetHandler 階段將生成鍵值透過 MetaObject 回填至參數物件。
掌握主鍵回寫配置,是 MyBatis 從「會用」到「用好」的關鍵技能之一。