mybatis插入数据后主键回填的几种方式

主键回填一般是插入一条数据,id设为自增,当插入一条记录时,并返回该记录id值

一、JDBC原生写法:

public int insert(Person person) {
  Connection con = null;
  PreparedStatement ps = null;
  ResultSet rs = null;
  con = DBUtils.getConnection();
  ps = con.prepareStatement("INSERT INTO person(username,password,money) VALUES(?,?,?)", PreparedStatement.RETURN_GENERATED_KEYS);
  ps.setObject(1, person.getUsername());
  ps.setObject(2, person.getPassword());
  ps.setObject(3, person.getMoney());
  int i = ps.executeUpdate();
  rs = ps.getGeneratedKeys();
  int id = -1;
  if (rs.next()) {
    id = rs.getInt(1);
  }
  return id;
}

和普通的插入 SQL 不同之处主要体现在两个地方:

  • 第一个是构造 PreparedStatement 时,多了一个参数,指定了需要主键回填。
  • 在更新操作执行完成之后,调用 getGeneratedKeys ,然后又会获取到一个 ResultSet 对象,从这个游标集中就可以获取到刚刚插入数据的id。

二、mybatis方式:

1、 方式一

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
	insert into t_user (name,age) values (#{name},#{age});
</insert>

这种方式就是在插入节点上添加 useGeneratedKeys 属性,同时设置接收回传主键的属性。配置完成后,我们执行一个插入操作,插入时传入一个对象,插入完成后,这个对象的 id 就会被自动赋值,值就是刚刚插入成功的id。

2、方式二

<insert id="insertUser">
  <selectKey keyProperty="id" resultType="java.lang.Integer">
    SELECT LAST_INSERT_ID()
  </selectKey>
  insert into t_user (name,age) values (#{name},#{age});
</insert>

这种方式是在 insert 节点中添加 selectKey 来实现主键回填,实际上这种方式的功能更加丰富,因为 selectKey 节点中的 SQL 我们既可以在插入之前执行,也可以在插入之后执行(通过设置节点的 Order 属性为 AFTER 或者 BEFORE 可以实现),具体什么时候执行,还是要看具体的需求,如果是做主键回填,我们当然需要在插入 SQL 执行之后执行 selectKey 节点中的 SQL。

注意第二种方式一样也要通过设置 keyProperty 来指定将查询到的数据绑定到哪个属性上。

三、注解的方式:

注解可用于mapper接口方法上

1、@Options注解

@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")

useGeneratedKeys:开启主键回填
keyProperty:表示对象中的成员变量
keyColumn:表示数据库中的列名

2、@SelectKey注解

@SelectKey(statement = "select last_insert_id()", keyProperty = "id", before = false, resultType = long.class)

statement是要运行的SQL语句,它的返回值通过resultType来指定
before:指select语句是否在insert之前执行
select last_insert_id()也可以换成@@identity,效果一样

四、扩展:

@Options注解:

  • 使用场景一:缓存
    @Options(useCache = true, flushCache = Options.FlushCachePolicy.FALSE, timeout = 1000)
    useCache = true表示将会缓存本次查询结果,以提高下次查询速度
    flushCache = Options.FlushCachePolicy.FALSE表示查询时不刷新缓存
    timeout = 10000表示查询结果缓存10000秒
  • 使用场景二:主键回填
posted @ 2021-06-15 18:39  少爷晚安。  阅读(1607)  评论(0)    收藏  举报