簡體   English   中英

從 MyBatis @Insert 返回不可變的 id object

[英]Return id from MyBatis @Insert for immutable object

我有一張不可變的 object 卡:

public record Card(int id, int deck_id, int count, String name) {}

以及帶有插入語句的映射器文件:

@Mapper
public interface DeckMapper {
    @Insert(value = "INSERT INTO deck (name) VALUES (#{name})")
    public int addDeck(Deck deck);
}

以及 MySQL 8 數據庫中的一個表:

+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| name  | varchar(255) | YES  |     | NULL    |                |
| id    | int          | NO   | PRI | NULL    | auto_increment |
+-------+--------------+------+-----+---------+----------------+

我希望addDeck返回它創建的牌組的 ID。 通常,我會這樣做的方式是@Options(useGeneratedKeys=true)@SelectKey ,但這兩種解決方案都試圖修改底層甲板記錄,而不僅僅是返回 id。 這會導致異常,因為 object 是不可變的,因此沒有 id 的 setter。

我們遇到了同樣的問題。 MyBatis 可以更新不可變 object 的 id,但我們不想改變不可變對象。 我們方法的調用者沒有理由期望不可變的 object 發生變異。 我們最終做的是使用包裝器 class。

public class Wrapper<T>
{
  Wrapper(T data){
    this.data = data;
  }

  T data;
  long id;
  // getters and setters
}

在我們的數據庫代碼中,我們有一個類似這樣的方法:

public int insertAndReturnId<T>(string statement, T data)
{
  var wrappedData = Wrapper(data);
  sqlSessionTemplate.insert(statement, wrappedData);
  return wrappedData.id
}

然后,我們像往常一樣使用useGeneratedKeys=true並通過在 SQL 中使用wrapper.propertyA訪問我們插入的任何參數。雖然我們沒有使用注釋,但類似的解決方案應該是可能的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM