1、Mybatis配置java
<insert id="insert" parameterType="com.test.TestDO"
keyProperty="id" useGeneratedKeys="true">
useGeneratedKeys=「true」時 , mybatis會將自增ID值 填充到 TestDO對象中的 id (keyProperty指定)屬性。mysql
2、JDBCsql
java.sql.Statement對象 執行 executeUpdate 數據庫
int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException;
其中, returnGenerateKeys 的枚舉定義在java.sql.Statement中 服務器
int RETURN_GENERATED_KEYS = 1;
int NO_GENERATED_KEYS = 2;
指定爲 RETURN_GENERATED_KEYS時,JDBC 協議要求JDBC實現能返回 自增主鍵的值。mybatis
經過java.sql.Statement對象的 getGeneratedKeys()方法能夠取得 包含自增主鍵值的 ResultSet對象。server
3、Mysql對象
Mysql JDBC 在執行 executeUpdate 時, 接口
mysql server服務器返回的數據包(ResultSetImpl對象)中 包含了兩個相關的值:get
/** How many rows were affected by UPDATE/INSERT/DELETE? */
protected long updateCount;
/** Value generated for AUTO_INCREMENT columns */
protected long updateId = -1; //這次插入的第一個自增ID值(單條插入,批量插入相同)
有了這兩個值, 在getGeneratedKeys()時, 從updateId 開始 ,加 updateCount 次,便獲得了這次
插入的全部自增ID值。
好比: 數據庫自增ID 當前是 99, 經過JDBC批量插入5條數據,執行插入後,updateId值爲100, updateCount爲5;
那麼getGeneratedKeys()返回的ResultSet對象中包含的自增ID 爲 100,101,102,103,104 。
單條插入的好理解一點,對於批量插入的如何理解 值的連續性呢 ?
對於Mysql, 包含自增主鍵的表 對 有一個特殊的表鎖,能夠理解爲自增主鍵列鎖,insert語句執行前須要獲取該鎖(不影響update操做),
也就是當批量插入(insert ..values 形式 或 Statement.executeBatch() )時,不會有別的插入操做會進來,因此能夠保證 批量插入的自增ID值是連續的。
4、Mybatis
Mybatis 利用 JDBC協議中 該機制,在批量插入(接收List<TestDO>對象) 時,根據getGeneratedKeys()的返回接口,順序寫入List中的TestDO對象中。
時間比較倉促,寫的比較粗糙,不夠詳細,不過 大體 原理邏輯 理清楚了。
至於JDBC爲什麼要規定單獨接口獲取自增主鍵ID, 又爲什麼在executeUpdate中將 是否返回自增主鍵值 做爲附加參數,
Mysql 如何封裝JDBC協議數據包, 如何實現自增主鍵的表級鎖等等,還請見諒。
文中有不當之處,還望各位大佬斧正。