MyBatis insert 返回主键的方法(oracle和mysql)

本文介绍在MyBatis中使用不同数据库时的主键生成策略,包括Oracle的sequence、MySQL和SQLServer的自增主键以及使用uuid()等数据库函数生成唯一主键的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

参考:

1.http://liuqing9382.iteye.com/blog/1574864

2.http://blog.youkuaiyun.com/ultrani/article/details/9351573

3.mybatis中文文档

 

作者前言:

使用Mybatis时,对于不同数据库比如Oracle、SQL Server、Mysql,它们的主键生成策略是不同的:

1. Oracle自增主键必须得配一个sequence;

2. SQL Server和Mysql的自增使用自动自增设置的;

3. 对于非自增的主键,项目也可以使用数据库函数来产生唯一主键,比如uuid()。
插入操作: 
1. 对于类似mysql、SQL Server这样自增主键的表,插入可以不配置插入的主键列(在sql中显式的写出该id);

2. 类似Oracle这类使用sequence或者uuid()这种数据库函数产生唯一主键,如果不做触发器之类的设置的话,一般需要在sql中写出主键列的。

获取主键

mybatis针对以上的不同生成策略以及不同的sql主键配置类型,将插入数据返回主键的解决方案分为一下几个情况:

1. 如果使用的数据库支持自动生成主键(如:MySQL 和 SQL Server),那么您就可以简单地将 useGeneratedKeys 设置为”true”,然后使用 keyProperty 设置你希望自动生成主键的字段就可以了

例如,如果 Author 表使用一个字段自动生成主键,那么配置语句就可以修改为:

<insert id="insertAuthor" parameterType="domain.blog.Author" useGeneratedKeys=”true” keyProperty=”id”>
  insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio})
</insert>

对于useGeneratedKeys和keyProperty属性的说明如下图

2. MyBatis 还有另外一种方式为不支持自动生成主键的数据库及 JDBC 驱动来生成键值,下面展示一个能够随机生成 ID 的例子(也许你不会这么做,这仅仅是演示 MyBatis 的功能,文档的词语,意思像是说至于你做不做,反正我做了):

复制代码
<insert id="insertAuthor" parameterType="domain.blog.Author">
  <selectKey keyProperty="id" resultType="java.lang.integer" order="BEFORE">
    select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
  </selectKey>
  insert into Author (id, username, password, email,bio, favourite_section)
    values (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>
复制代码

注意:上面的语句中标红的文字,添加了selectKey标签,首先解释如下图:

正如上面的解释我们只要把握住order的设置,在sql语句执行前(BEFORE)或者执行后(AFTER),执行selectKey 语句来获得主键就可以了,如上面例子selectKey首先执行,生成随机的主键,这时候Author对象中的id首先被赋值了,然后才会调用insert 语句。这相当于在您的数据库中自动生成键值,不需要编写复杂的 java 代码。

当然,是否需要配置<selectKey>根据情况,只要能保证记录有主键即可,一旦配置了<selectKey>,就可以在执行插入操作时获取到新增记录的主键。 
注意:如果没有配置<selectKey>那么保存后的对象的主键依旧为null。

 

小结:

通过上面的方案:

1. 我们针对uuid()函数的主键返回应该如下:

复制代码
    <insert id="insertTestRole" parameterType="hashmap" >
        <selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id"> 
        SELECT uuid()
        </selectKey>
        insert into
        testRole(id,name)
        values(#{id},#{name})
    </insert>
复制代码

2. oracle针对Sequence主键而言,隐式主键插入前必须指定一个主键值给要插入的记录: 

<insert id="AltName.insert" parameterType="AltName">  
     <selectKey resultType="long" keyProperty="id">  
       SELECT SEQ_TEST.NEXTVAL FROM DUAL   
     </selectKey>  
     insert into altname(primaryName,alternateName,type)values(#{primaryName},#{alternateName},#{type})   
 </insert> 

或者显式主键:

复制代码
    <insert id="insertEnterprise" parameterType="hashmap">
        <selectKey resultType="integer" order="AFTER" keyProperty="ENTERPRISE_ID">
            select sq_enterprise.currval from dual
        </selectKey>
            insert into
                m_enterprise
                (ENTERPRISE_ID,ENTERPRISE_NAME,ENTERPRISE_ADDRESS,ENTERPRISE_INTRODUCTION,ENTERPRISE_ZIP,ENTERPRISE_PHONE,ENTERPRISE_NUMBER)
            values
                (sq_enterprise.nextval,#{enterprise_name},#{address},#{introduction},#{zip},#{phone},#{enterprise_number})
    </insert>
复制代码

3. MySql、sql server自增主键而言,这类表在插入时不需要主键,而是在插入过程自动获取一个自增的主键: 

     <insert id="AltName.insert" parameterType="AltName">
        <selectKey resultType="long" keyProperty="id">
          SELECT LAST_INSERT_ID()
        </selectKey>
        insert into altname(primaryName,alternateName,type)values(#{primaryName},#{alternateName},#{type})
    </insert>

根据获得自增主键的方法,我们还可以:

     <insert id="AltName.insert" parameterType="AltName">
        <selectKey resultType="long" keyProperty="id">
          SELECT @@IDENTITY
        </selectKey>
        insert into altname(primaryName,alternateName,type)values(#{primaryName},#{alternateName},#{type})
    </insert>

但是参考http://blog.youkuaiyun.com/ultrani/article/details/9351573 中四种获得自增主键的方法利弊分析,作者推荐使用useGeneratedKeys属性设置来利用JDBC的getGeneratedKeys方法获得自增主键。

 

 
 
 
<think>好的,我现在需要帮助用户了解如何在MyBatis的XML配置中设置返回插入记录的主键ID。首先,我需要回忆一下MyBatis的相关知识,尤其是关于主键返回的部分。根据用户提供的引用,特别是引用[3]引用[4],提到了使用useGeneratedKeysselectKey标签的方法。 首先,用户可能是在使用支持自增主键数据库,比如MySQL。这时候,最常用的方法应该是useGeneratedKeys属性。根据引用[3],useGeneratedKeys设置为true,并指定keyProperty为实体类中对应的主键字段。比如在插入语句中,配置这两个属性,这样插入操作完成后,主键值会自动回填到传入的实体对象中。 但是,如果数据库支持自增主键,比如Oracle,这时候可能需要使用selectKey标签来获取序列生成的主键。引用[4]提到使用selectKey标签,在执行插入之前或之后获取主键值。这时候需要编写查询序列的SQL,并设置order属性为BEFORE或AFTER,具体取决于数据库的要求。 接下来,我需要考虑如何将这些信息组织成清晰的步骤,并给出示例。可能需要分两种情况来说明:支持自增主键支持的。同时,要确保示例代码正确,比如在XML映射文件中正确配置insert标签,以及对应的属性。 另外,用户可能需要知道keyProperty的作用,即告诉MyBatis将获取到的主键值设置到哪个属性中。比如,如果实体类有一个id字段,那么keyProperty应该是"id"。 还需要注意,同的数据库同的处理方式,比如MySQL的自增Oracle的序列,可能需要同的配置方法。因此,在回答中应该区分这两种情况,并提供相应的示例。 最后,要确保引用的正确使用,比如在适当的地方添加引用标记,如引用[3]引用[4]。同时,生成的相关问题需要与主键返回相关,可能涉及其他配置方式或者常见问题的解决方法,比如如何在使用注解时返回主键,或者处理复合主键的情况等。</think>在MyBatis的XML配置中返回插入记录的主键ID,主要通过以下两种方式实现: ### 一、使用`useGeneratedKeys`属性(推荐,适用于自增主键数据库) ```xml <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user(name, age) VALUES(#{name}, #{age}) </insert> ``` - **`useGeneratedKeys="true"`**:声明使用数据库生成的主键[^3] - **`keyProperty="id"`**:将生成的主键值注入到参数对象的`id`属性中 - 适用于MySQL、SQL Server等支持自增主键数据库 ### 二、使用`<selectKey>`标签(适用于非自增主键数据库) ```xml <insert id="insertOrder" parameterType="Order"> <selectKey keyProperty="id" resultType="long" order="BEFORE"> SELECT order_seq.nextval FROM dual </selectKey> INSERT INTO orders(id, order_no) VALUES(#{id}, #{orderNo}) </insert> ``` - **`order="BEFORE"`**:在插入语句执行前获取序列值(Oracle场景) - **`order="AFTER"`**:在插入语句执行后获取自增值(PostgreSQL场景) - 适用于Oracle等使用序列生成主键数据库[^4] ### 使用验证 插入操作后,主键值会自动填充到传入的实体对象中: ```java User user = new User("张三", 25); mapper.insertUser(user); System.out.println(user.getId()); // 输出自动生成的主键ID ``` ### 注意事项 1. MySQL配置示例需要确保表主键设置为`AUTO_INCREMENT` 2. Oracle配置需预先创建序列`order_seq` 3. 复合主键场景需要特殊处理 4. 批量插入时需注意主键回填方式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值