SoFunction
Updated on 2025-03-01

Mybatis's own id acquisition method after inserting data

need

We need to return the id after inserting the data (generated by the database primary key) so that we can operate the next time.

like this

/**
  * Get id after test insertion
  */
@Test
public void testinsertStudentCacheId(){
    Student student=new Student("helloworld",17,85);
    ("Before insertion:student="+student);
    (student);
    ("After insertion: student codeview">
<?xml version="1.0" encoding="UTF-8" ?>   
<!DOCTYPE mapper   
PUBLIC "-////DTD Mapper 3.0//EN"  
"/dtd/"> 

<!-- mapper as root element node, onenamespace对应onedao -->
<!-- 
Mapper元素只有one属性namespace,It has two functions:`First, it is used to distinguish differentmapper`(In differentmapperIn the file,child elementsidCan be the same,mybatispassnamespaceandchild elementsidJoint distinction),`The second is to be associated with the interface`(应用程序passinterface访问mybatishour,mybatispassinterfaceof完整名称查找对应ofmapperConfiguration,thereforenamespaceBe careful to name an interface with the same name)。
-->
<mapper namespace="">
    
    <!-- 
    cache- Configuration本定命名空间of缓存。
        type- cacheImplementation Class,Default isPERPETUAL,CustomizablecacheImplementation Class(Alias ​​or complete class names are available)
        eviction- Recycling algorithm,Default isLRU,Optional algorithms are:
            LRU– The least used recently:移除最长hour间不被useof对象。
            FIFO– First in first out:Remove objects in the order in which they enter the cache。
            SOFT– Soft Quotations:移除基于垃圾回收器状态andSoft Quotations规则of对象。
            WEAK– Weak quotes:更积极地移除基于垃圾收集器状态andWeak quotes规则of对象。
        flushInterval- Refresh interval,Default is1个小hour,Unit milliseconds
        size- Cache size,Default size1024,Unit is reference number
        readOnly- Read only
    -->
    <cache type="PERPETUAL" eviction="LRU" flushInterval="60000"  
        size="512" readOnly="true" />
    
    <!-- 
    cache-ref–从其他命名空间引用缓存Configuration。
        If you don't want to define your owncache,Availablecache-refQuote something elsecache。Because everycacheAllnamespaceforid,socache-ref只需要ConfigurationonenamespaceThe attributes are fine。It should be noted that,ifcache-refandcache都Configuration了,bycachefor准。
    -->
    <cache-ref namespace=""/>
    
    <insert
      <!-- 1. id (必须Configuration)
        idis a unique identifier in the namespace,Can be used to represent this statement。 
        one命名空间(namespace) 对应onedaointerface, 
        thisidIt should also corresponddaoSome method inside(Implementation of the method),thereforeid It should be consistent with the method name -->
      
      
      
      <!-- 2. parameterType (可选Configuration, Default ismybatisAutomatic selection processing)
        Fully qualified class name or alias for the arguments to be passed in, if不Configuration,mybatis会passParameterHandler Select the appropriate one by default according to the parameter typetypeHandlerPerform processing
        parameterType Mainly specify parameter types,可by是int, short, long, stringTypes of,也可by是复杂类型(Like object) -->
      
      parameterType=""
      
      <!-- 3. flushCache (可选Configuration,defaultConfigurationfortrue)
        将其设置for true,任何hour候只要语句被调用,都会导致本地缓存and二级缓存都会被清空,default value:true(Corresponding insertion、更新and删除语句) -->
      
      flushCache="true"
      
      <!-- 4. statementType (可选Configuration,defaultConfigurationforPREPARED)
        STATEMENT,PREPARED or CALLABLE ofone。This will make MyBatis Use separately Statement,PreparedStatement or CallableStatement,default value:PREPARED。 -->
      
      statementType="PREPARED"
      
      <!-- 5. keyProperty (可选Configuration, Default isunset)
        (Just right insert and update it works)唯一标记one属性,MyBatis 会pass getGeneratedKeys of返回值or者pass insert Statement selectKey Set its key value for child elements,default:unset。if希望得到多个生成of列,也可by是逗号分隔of属性名称列表。 -->
      
      keyProperty=""
      
      <!-- 6. keyColumn     (可选Configuration)
        (Just right insert and update it works)pass生成of键值设置表中of列名,this设置仅在某些数据库(picture PostgreSQL)is required,当主键列不是表中of第一列ofhour候需要设置。if希望得到多个生成of列,也可by是逗号分隔of属性名称列表。 -->
      
      keyColumn=""
      
      <!-- 7. useGeneratedKeys (可选Configuration, Default isfalse)
        (Just right insert and update it works)This will make MyBatis use JDBC of getGeneratedKeys 方法来取出由数据库内部生成of主键(for example:picture MySQL and SQL Server 这样of关系数据库管理系统of自动递增字段),default value:false。  -->
      
      useGeneratedKeys="false"
      
      <!-- 8. timeout  (可选Configuration, Default isunset, Depend on drivers)
        this设置是在抛出异常之前,驱动程序等待数据库返回请求结果of秒数。default valuefor unset(Depend on drivers)。 -->
      timeout="20">

    <update
      
      parameterType=""
      flushCache="true"
      statementType="PREPARED"
      timeout="20">

    <delete
      
      parameterType=""
      flushCache="true"
      statementType="PREPARED"
      timeout="20">
</mapper>

It's obvious that the three properties of keyProperty, keyColumn, and useGeneratedKeys are the entry point for us to implement our requirements.

Begin to implement

Method 1 useGeneratedKeys Set the primary key to increase automatically

    <insert  useGeneratedKeys="true" keyProperty="id" parameterType="Student">
        insert into student(name,age,score) values(#{name},#{age},#{score})
    </insert>

Things to note:

  • useGeneratedKeys="true" means that the setting attribute is increased by itself, and the database table field needs to be set
  • keyProperty="id" sets the field of the primary key
  • parameterType="Student" sets the type passed in
  • Note: Although there is a return type, we do not need to manually set the returned type. This is implemented by the framework for us, so the corresponding interface method also has no return value. It will automatically modify the object we inserted and set the id value. Therefore, the mapper return value affects the number of rows.
  • The id attribute field in the entity class must require set and get methods

Method 2 selectKey query primary key

selectKey Introduction

&lt;selectKey
        &lt;!-- selectKey The target attributes that the statement result should be set。If you want to get multiple generated columns,It can also be a comma-separated list of attribute names。 --&gt;
        keyProperty="id"
        &lt;!-- Type of result。MyBatis It can usually be calculated,But there will be no problem writing in order to be more certain。MyBatis Types that allow any simple type to be used as primary key,Include strings。If you want to act on multiple generated columns,You can use a Object Or a Map。 --&gt;
        resultType="int"
        &lt;!-- This can be set to BEFORE or AFTER。If set to BEFORE,Then it will first select the primary key,set up keyProperty Then execute the insert statement。If set to AFTER,Then execute the insert statement first,Then selectKey element - It's like Oracle The database is similar,There may be an embedded index call inside the insert statement。 --&gt;
        order="BEFORE"
        &lt;!-- Same as before,MyBatis support STATEMENT,PREPARED and CALLABLE The mapping type of the statement,Representative PreparedStatement and CallableStatement type。 --&gt;
        statementType="PREPARED"&gt;
  • selectKey gives you a simple behavior in your database to handle automatically generated primary keys without complicating your Java code.
  • The KeyGenerator generated by the selectKey node is higher than the KeyGenerator object generated by the useGeneratedKeys property of the statement node. That is to say, if the SelectKey child node is configured, the useGeneratedKey property is no longer necessary.

Get primary key operation

    &lt;insert  parameterType="Student"&gt;
        insert into student(name,age,score) values(#{name},#{age},#{score})
        &lt;!-- Specify the result typeresultType,keyPropertyIt's an attribute,Automatically return to propertiesidmiddle,orderIt's order,afterIt means obtainingidIt's after insertion --&gt;
        &lt;selectKey resultType="int" keyProperty="id" order="AFTER"&gt;
            select @@identity
        &lt;/selectKey&gt;
    &lt;/insert&gt;

or

    &lt;insert  parameterType="Student"&gt;
        insert into student(name,age,score) values(#{name},#{age},#{score})
        &lt;!-- Specify the result typeresultType,keyPropertyIt's an attribute,Automatically return to propertiesidmiddle,orderIt's order,afterIt means obtainingidIt's after insertion --&gt;
        &lt;selectKey resultType="int" keyProperty="id" order="AFTER"&gt;
            select LAST_INSERT_ID()
        &lt;/selectKey&gt;
    &lt;/insert&gt;

Note the key points:

  • The outermost layer does not have a return attribute (resultType), but the inside has a return value type.
  • order="AFTER" means that the insertion is performed first, and then the selectkey statement is executed.
  • Both select @@identity and select LAST_INSERT_ID() indicate the id of the last data that has just been inserted.
  • The id attribute field in the entity class must require set and get methods
  • At this time, there is still no need for a return value in the interface. The framework will automatically inject the value into the object we insert, and we can use it directly.

Similarly, there can be a return value in our interface, but this return value is not an id, but represents the number of rows affected after insertion. At this time, SQL is still the same as above, and there is no need to write the return value.

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.