1. 程式人生 > 其它 >mybatis插入資料後主鍵回填的幾種方式

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秒
  • 使用場景二:主鍵回填