Mybatis插入时返回生成的主键

导读:本篇文章讲解 Mybatis插入时返回生成的主键,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

实体类

/**
 * mybatis-sql语句测试实体类
 * @Author: chenyang
 * @Date: 2021/11/23 15:18
 * @Description: 测试实体类
 */
public class Human {

    /**
     * 主键id
     */
    private Integer id;
    /**
     * 用户名称
     */
    private String name;
    /**
     * 性别 1 男, 2 女
     */
    private String sex;
    /**
     * 个人介绍
     */
    private String introduce;
    /**
     * 脸型
     */
    private Integer face;

    private Integer type;

    private String createTime;

    private String updateTime;
}

当插入数据之后,mybatis再次查询mysql数据库,获得了自增id,然后填充到human对象的id属性的。

添加单一记录时返回主键ID(方法一)

在定义xml映射器时设置属性useGeneratedKeys值为true,并分别指定属性keyPropertykeyColumn为对应的数据库记录主键字段与Java对象的主键属性。

 <insert id="insertHuman" parameterType="Human" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into m_human
        <if test="type == 1">
            (name, sex, createtime, type)
            values (#{name}, #{sex}, now(), #{type})
        </if>
        <if test="type == 2">
            (introduce, face, createtime, type)
            values (#{introduce}, #{face}, now(), #{type})
        </if>
    </insert>

useGeneratedKeys=”true” 表示给主键设置自增长

keyProperid” 表示将自增长后的Id赋值给实id字段。

parameterType=”Human” 这个属性指向传递的参数实体类

这里提醒下,<insert></insert> 中没有resultType属性,不要乱加。 实体类中id 要有getter() and setter()方法

使用注解

    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    @Insert("")
    int insertHuman(Human human);

在MyBatis中添加操作返回的是记录数并非记录主键id。因此,如果需要获取新添加记录的主键值,需要在执行添加操作之后,直接读取Java对象的主键属性。

@Test
public void test2(){
    Human human = new Human();
    human.setType(2);
    human.setIntroduce("msg");
    human.setFace(5);
    human.setName("test");
    System.out.println(humanDao.insertHuman(human));// 1 添加操作返回记录数
    System.out.println(human.getId());// 16019 执行添加操作后通过Java对象获取主键属性值
}

使用原生SQL语句方式

    <insert id="insertHuman" parameterType="Human">
        insert into m_human(name, sex, createtime, type)
            values (#{name}, #{sex}, now(), #{type})
     
        <selectKey resultType="int" order="AFTER" keyProperty="id">
            select LAST_INSERT_ID()
        </selectKey>
    </insert>

代码说明:

(1)SELECT LAST_INSERT_ID(): 获取刚刚插入的主键;

(2)keyProperty:表示将返回的值设置到某一列,此处为id;

(3)order:表明此代码相对于insert语句的执行顺序,BEFORE(适用于Oralce等取序列的数据库)/ARTER(适用于MySQL等支持自增长的数据库);order=”AFTER” 表示先执行插入语句,之后再执行查询语句。如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。 (4)resultType:返回的类型;

    @Test
    public void test2(){
        Human human = new Human();
        human.setType(2);
        human.setIntroduce("msgSS");
        human.setFace(5);
        human.setName("tesSSS");
        System.out.println(humanDao.insertHuman(human)); // 1

        System.out.println(human.getId()); // 16020
    }

注解方式

    @SelectKey(keyProperty="id", before=false, resultType=int.class) 
    @Insert("")
    int insertHuman(Human human);

问题:

在高并发多个数据表都有写入的情况下,这个语句返回的就有可能是另外一张表刚刚写入的记录id,这样根据这个id去查询就返回没有这个记录了。

解决方案:用这个user表的唯一索引user_id去重新查一次user表来获取这个id,这种重新去查的方法基本可以满足大部分场景需要

在用Spring管理事务时,SelectKey和插入在同一事务当中,因而Mysql这样的情况由于数据未插入到数据库中,所以是得不到自动增长的Key。取消事务管理就不会有问题。

用在已经被 @Insert 或 @InsertProvider 或 @Update 或 @UpdateProvider 注解了的方法上。若在未被上述四个注解的方法上作 @SelectKey 注解则视为无效。如果你指定了 @SelectKey 注解,那么 MyBatis 就会忽略掉由 @Options 注解所设置的生成主键或设置(configuration)属性。

属性有:

statement 填入将会被执行的 SQL 字符串数组,

keyProperty 填入将会被更新的参数对象的属性的值,

before 填入 true 或 false 以指明 SQL 语句应被在插入语句的之前还是之后执行。

resultType 填入 keyProperty 的 Java 类型

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/95925.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!