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协议数据包, 如何实现自增主键的表级锁等等,还请见谅。
文中有不当之处,还望各位大佬斧正。