如何在mysql中使用mybatis在带有注解的插入中返回id

wko9yo5t  于 2023-06-21  发布在  Mysql
关注(0)|答案(4)|浏览(159)
  • See this related question用于Postgres。出于某种原因,这个解决方案对我不起作用--insert语句的返回值总是“1”。
  • 请参阅XML based solution的其他问题。我想在没有XML的情况下做同样的事情--插入一条记录并找到我刚刚插入的记录的新的自动生成的id。

我没有找到与<selectkey>匹配的注解(请参阅此open issue)如何继续?
检查mybatis代码可以发现INSERT是通过UPDATE实现的,并且总是返回插入的行数!所以...除非我在这里完全遗漏了什么,否则使用当前的(3.0.3)实现是没有办法做到这一点的。

cfh9epnr

cfh9epnr1#

实际上,可以使用@Options注解(假设您在数据库中使用auto_increment或类似的东西):

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

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

(旧答案)(最近的)@SelectKey注解可用于更复杂的密钥检索(sequences,identity()函数...)。以下是MyBatis 3 User Guide(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);
n53p2ov0

n53p2ov02#

<insert><update><delete>语句返回受影响的行数,这与数据库API相同。
如果为插入的行生成了新的ID,则该ID将反映在作为参数传递的对象中。例如,如果在带注解的insert方法中调用mapper.insert(someObject),在插入之后,可以调用someObject.getId(或类似的方法)来检索它。
使用<insert>的选项,您可以调整如何(通过提供SQL语句)和何时(在实际插入之前或之后)生成或检索id,以及将其放置在对象中的位置。
使用MyBatis generator从数据库模式生成类并了解如何处理插入和更新可能会有所启发。具体来说,生成器生成“示例”类,这些类用作传递数据的临时容器。

ijxebb2r

ijxebb2r3#

你可以从保存方法中得到你生成的id,比如说一个有ID和name属性的bean,

bean.setName("xxx");
mapper.save(bean);
// here is your id
logger.debug(bean.getID);
polhcujo

polhcujo4#

我不喜欢我在网上找到的大多数返回生成的密钥的答案,因为
1.我找到的所有解决方案都在入站对象上称为“setter”
1.没有一个解决方案返回从方法生成的列
我提出了以下解决方案,解决了上面的1和2点。
1.传递两个参数给mybatis“in”&“out”(mybatis不改变“in”,它在“out”上调用一个setter)
1.需要在接口上添加一个default method才能返回值

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
}

相关问题