• Mybatis主键自动生成


    Mybatis主键自动生成

    在MyBatis中,允许设置名称为“useGeneratedKeys”参数存在3个位置:

    • xml映射器中设置useGeneratedKeys参数

    • 在接口映射器中设置useGeneratedKeys参数

    • 在settings元素中设置useGeneratedKeys参数

    在不同位置设置的useGeneratedKeys参数,最终结果相同,但是影响范围不同。

    官方的说法是该参数的作用是:“允许JDBC支持自动生成主键,需要驱动兼容”,如何理解这句话的意思?

    其本意是说:对于支持自动生成记录主键的数据库,如:MySQL,SQL Server,此时设置useGeneratedKeys参数值为true,在执行添加记录之后可以获取到数据库自动生成的主键ID。

    在xml映射器中配置useGeneratedKeys参数

    
    <insert id="insertOneTest" parameterType="org.x.Test" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into test(name,descr,url,create_time,update_time) 
        values(#{name},#{descr},#{url},now(),now())
    insert>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    xml映射器中配置的useGeneratedKeys参数只会对xml映射器产生影响

    在接口映射器中设置useGeneratedKeys参数

    // 设置useGeneratedKeys为true,返回数据库自动生成的记录主键id
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    @Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())")
    Integer insertOneTest(Test test);
    
    • 1
    • 2
    • 3
    • 4

    注意: 在接口映射器中设置的useGeneratedKeys参数会覆盖在元素中设置的对应参数值。

    在settings元素中设置useGeneratedKeys参数

    实际上,在settings元素中设置useGeneratedKeys是一个全局参数,但是只会对接口映射器产生影响,对xml映射器不起效。

    <settings>
    
    <setting name="useGeneratedKeys" value="true" />
    settings>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    此时,在接口映射中添加记录之后将返回主键ID。

    public interface TestMapper {
        // 受全局useGeneratedKeys参数控制,添加记录之后将返回主键id
        @Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())")
        Integer insertOneTest(Test test);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    但是,请注意如果此时在接口映射器中又明确设置了useGeneratedKeys参数,那么注解映射器中的useGeneratedKeys参数值将覆盖settings元素中设置的全局useGeneratedKeys参数值。
    举个例子:先在settings元素中设置全局useGeneratedKeys参数值为true,再在接口映射器中设置useGeneratedKeys参数值为false,添加记录之后将不能返回注解ID。

    // 在接口映射器中设置的useGeneratedKeys参数值将会覆盖在settings元素中设置全局useGeneratedKeys参数值
    @Options(useGeneratedKeys = false, keyProperty = "id", keyColumn = "id")
    @Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())")
    Integer insertOneTest(Test test);
    
    • 1
    • 2
    • 3
    • 4

    注意项

    Mybatis 配置文件配置useGeneratedKeys 参数只针对 insert 语句生效,默认为 false。且需要数据库支持自动生成主键

    在INSERT语句中,我们为可以自动生成(auto-generated)主键的列 STUD_ID 插入值。我们可以使用useGeneratedKeys和keyProperty属性让数据库生成auto_increment列的值,并将生成的值设置到其中一个输入对象属性内,如下所示:

    <insert id="insertStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="studId">  
        INSERT INTO STUDENTS(NAME, EMAIL, PHONE) VALUES(#{name},#{email},#{phone})  
    insert> 
    
    • 1
    • 2
    • 3

    这里STUD_ID列值将会被数据库自动生成(如mysql),并且生成的值会被设置到student对象的studId属性上。

    但是有些数据库如Oracle并不支持AUTO_INCREMENT列,其使用序列(SEQUENCE)来生成主键值。假设我们有一个名为my_seq的序列来生成SUTD_ID主键值。使用如下代码来生成主键:

    drop sequence my_seq;

    create sequence my_seq;

    <insert id="insertStudent" parameterType="Student">  
        <selectKey keyProperty="studId" resultType="int" order="BEFORE">  
            SELECT my_seq.nextval FROM DUAL  
        selectKey>  
        INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL, PHONE)  
            VALUES(#{studId},#{name},#{email},#{phone})  
    insert>         
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这里我们使用了子元素来生成主键值,并将值保存到Student对象的studId 属性上。属性order=“before”表示MyBatis将取得序列的下一个值作为主键值,并且在执行INSERT语句之前将值设置到studId属性上。

    注: SelectKey需要注意order属性,像MySQL、SQLServer等一类支持自动增长类型的数据库中,order需要设置为after才会取到正确的值。
    像Oracle这样取序列的情况,需要设置为before,否则会报错。

  • 相关阅读:
    UGUI交互组件ScrollView
    IDA Script
    xml文件报错 ORA-00907: 缺失右括号
    RabbitMQ快速上手以及RabbitMQ交换机的四种模式
    centos 8.2 配置 go 项目开发环境
    Node.js躬行记(20)——KOA源码分析(下)
    Qt5开发从入门到精通——第十一篇三节(Qt5 事件处理及实例——事件过滤及实例)
    Java 线程池调度周期性任务“异常“探究
    媲美有线操作,支持4KHz响应和无线充电的游戏鼠标,雷柏VT3S上手
    python爬取数据再次出错
  • 原文地址:https://blog.csdn.net/qq_35987023/article/details/132908502