简体   繁体   English

从 MyBatis @Insert 返回不可变的 id object

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

I have an immutable object Card:我有一张不可变的 object 卡:

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

And a mapper file with an insert statement:以及带有插入语句的映射器文件:

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

And a table in a MySQL 8 database:以及 MySQL 8 数据库中的一个表:

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

I would like addDeck to return the id of the deck it creates.我希望addDeck返回它创建的牌组的 ID。 Normally, the way I would do this is either @Options(useGeneratedKeys=true) , or @SelectKey , but both solutions attempt to modify the underlying deck record, rather than just returning the id.通常,我会这样做的方式是@Options(useGeneratedKeys=true)@SelectKey ,但这两种解决方案都试图修改底层甲板记录,而不仅仅是返回 id。 This causes an exception because the object is immutable and therefore doesn't have a setter for id.这会导致异常,因为 object 是不可变的,因此没有 id 的 setter。

We encountered the same problem.我们遇到了同样的问题。 MyBatis could update the id of our immutable object, but we didn't want to mutate immutable objects. MyBatis 可以更新不可变 object 的 id,但我们不想改变不可变对象。 The caller of our method has no reason to expect the immutable object to be mutated.我们方法的调用者没有理由期望不可变的 object 发生变异。 What we ended up doing was to use a wrapper class.我们最终做的是使用包装器 class。

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

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

In our db code we had a method that was something like this:在我们的数据库代码中,我们有一个类似这样的方法:

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

We then used useGeneratedKeys=true as normal and accessed the parameters of whatever we inserted by using wrapper.propertyA in the SQL. We did not use annotations though, but a similar solution should be possible.然后,我们像往常一样使用useGeneratedKeys=true并通过在 SQL 中使用wrapper.propertyA访问我们插入的任何参数。虽然我们没有使用注释,但类似的解决方案应该是可能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM