• Mybatis useGeneratedKeys 填充自增主键值(使用Mysql)的原理分析


    一、Mybatis配置

    <insert id="insert" parameterType="com.test.TestDO"
    keyProperty="id" useGeneratedKeys="true">

    useGeneratedKeys=“true”时 , mybatis会将自增ID值 填充到 TestDO对象中的 id (keyProperty指定)属性。

    二、JDBC

    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实现能返回 自增主键的值。

    通过java.sql.Statement对象的 getGeneratedKeys()方法可以取得 包含自增主键值的 ResultSet对象。

    三、Mysql

    Mysql  JDBC 在执行 executeUpdate 时, 

    mysql server服务器返回的数据包(ResultSetImpl对象)中 包含了两个相关的值:

    /** 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值是连续的。

    四、Mybatis

    Mybatis 利用 JDBC协议中 该机制,在批量插入(接收List<TestDO>对象) 时,根据getGeneratedKeys()的返回接口,顺序写入List中的TestDO对象中。

    时间比较仓促,写的比较粗糙,不够详细,不过 大致 原理逻辑 理清楚了。

    至于JDBC为何要规定单独接口获取自增主键ID, 又为何在executeUpdate中将 是否返回自增主键值 作为附加参数,

    Mysql 如何封装JDBC协议数据包, 如何实现自增主键的表级锁等等,还请见谅。

    文中有不当之处,还望各位大佬斧正。

    
    
  • 相关阅读:
    C# 函数参数object sender, EventArgs e
    Winform中利用委托实现窗体之间的传值
    Web前端学习笔记——Canvas
    js 删除 按钮所在的行
    box-sizing
    前端中关于HTML标签的属性for的理解
    apply和call的用法总结
    target 确定元素是谁??
    css3过渡和动画
    处理两端极限值的小技巧
  • 原文地址:https://www.cnblogs.com/selfchange/p/10771655.html
Copyright © 2020-2023  润新知