20

我没有找到匹配的注释<selectkey>(请参阅这个未解决的问题)我该如何继续?

查看 mybatis 代码可以发现,它INSERT是通过 实现UPDATE的,并且总是返回插入的行数!所以......除非我在这里完全遗漏了一些东西,否则没有办法使用当前的(3.0.3)实现来做到这一点。

4

4 回答 4

32

实际上,可以通过@Options注释来做到这一点(前提是您在数据库中使用 auto_increment 或类似的东西):

@Insert("insert into table3 (id, name) values(null, #{name})") 
@Options(useGeneratedKeys=true, keyProperty="idName")
int insertTable3(SomeBean myBean); 

请注意,keyProperty="idName"如果 SomeBean 中的 key 属性名为“id”,则该部分不是必需的。还有一个keyColumn属性可用,用于 MyBatis 自己找不到主键列的罕见情况。另请注意,通过使用@Options,您将方法提交给一些默认参数;查阅文档很重要(链接如下——当前版本的第 60 页)!

(旧答案)(相当新的)@SelectKey注释可用于更复杂的密钥检索(序列,身份()函数......)。以下是MyBatis 3 用户指南(pdf) 提供的示例:

此示例显示使用 @SelectKey 注释在插入之前从序列中检索值:

@Insert("insert into table3 (id, name) values(#{nameId}, #{name})") 
@SelectKey(statement="call next value for TestSequence", keyProperty="nameId", before=true, resultType=int.class) 
int insertTable3(Name name); 

此示例显示使用 @SelectKey 注释在插入后检索标识值:

@Insert("insert into table2 (name) values(#{name})")
@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
int insertTable2(Name name);
于 2011-06-23T13:31:48.697 回答
16

<insert>和语句返回受影响的行数,这在数据库 API 中很<update>常见。<delete>

如果为插入的行生成了一个新 ID,它会反映在您作为参数传递的对象中。因此,例如,如果您在带注释的插入方法中调用 mapper.insert(someObject) ,则在插入后,您可以调用 someObject.getId (或类似的)来检索它。

使用 的选项<insert>,您可以调整生成或检索 id 的方式(通过提供 SQL 语句)和时间(在实际插入之前或之后),以及它在对象中的放置位置。

使用MyBatis 生成器从数据库模式生成类并了解如何处理插入和更新可能会很有启发性。具体来说,生成器生成“示例”类,这些类用作临时容器来传递数据。

于 2010-11-30T14:10:22.513 回答
2

您可以从保存方法中获取生成的 id,比如说一个具有 ID 和 name 属性的 bean,

bean.setName("xxx");
mapper.save(bean);
// here is your id
logger.debug(bean.getID);
于 2010-12-13T09:24:15.547 回答
0

我不喜欢我在网上找到的大多数返回生成密钥的答案,因为

  1. 我发现的所有解决方案都称为入站对象的“setter”
  2. 没有一个解决方案从该方法返回生成的列

我想出了以下解决方案,它解决了上面的第 1 点和第 2 点

  1. 将两个参数传递给 mybatis "in" & "out"(mybatis 不会改变 "in",它会在 "out" 上调用 setter)
  2. 在接口上需要一个额外的默认方法来返回值
public interface MyMapper {
   /**
    * this method is used by the mybatis mapper
    * I don't call this method directly in my application code   
    */
   @Insert("INSERT INTO MY_TABLE (FOO) VALUES ({#in.foo})")
   @Options(useGeneratedKeys=true, keyColumn="ID", keyProperty = "out.value")
   void insert(@Param("in") MyTable in, @Param("out") LongReference out);

   /**
     * this "default method" is called in my application code and returns the generated id.
     */
   default long insert(MyTable tableBean) {
      LongReference idReference = new LongReference();
      insert(tableBean, idReference);
      return idReference.getValue();
   }
}

这需要一个额外的类,将来可以在类似的方法上重复使用

public class LongReference {
    private Long value;

    // getter & setter
}

于 2021-08-27T10:43:44.203 回答