有时候我们不仅仅是通过返回 int 影响行数来确定数据是否插入成功就行了,因为我们总是会用到这个刚刚插入的自增主键,比如主子表入库,子表需要主表的 id,那这个时候我们再去数据库查就显得有点 low 了~

关于数据库中主键的生成无非就两种,一种是 int 类型的自增,一种是 varchar 类型的非自增(例如:UUID)。

Mybatis 中,提供了 selectKey 来帮我们获取新增的主键,同时通过 selectKey 可以很容易的实现自增还是非自增规则的需求。

首先看一下 MybatisselectKey 的属性说明:

属性 描述
keyProperty selectKey 语句结果应该被设置的目标属性(也就是自增的主键字段,比如id)。
resultType 结果的类型,比如java.lang.Integer,java.lang.String等。MyBatis 通常可以算出来,但是写上也没有问题。MyBatis 允许任何简单类型用作主键的类型,包括字符串。
order 这可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素-这和如 Oracle 数据库相似,可以在插入语句中嵌入序列调用。
statementType 和前面的相同,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 语句的映射类型,分别代表 PreparedStatement 和 CallableStatement 类型。

下面从 OracleMySQL 分别举例说明。

1. Oracle

<insert id="insertUserInfo" parameterType="club.sscai.entity.UserInfo">
    <selectKey keyProperty="id" resultType="java.lang.Integer" order="BEFORE">
        select SEQ_T_USER_INFO.NEXTVAL from dual
    </selectKey>
    insert into "T_USER_INFO"
    <trim prefix="(" suffix=")" suffixOverrides=",">
        ID,USER_NAME,PASSWORD,PHONE,STATUS,
        <if test="remark != null">
            REMARK,
        </if>
        CREATE_TIME,UPDATE_TIME,UPDATE_BY
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
        #{id,jdbcType=DECIMAL}, #{userName,jdbcType=VARCHAR},
        #{PASSWORD,jdbcType=VARCHAR},#{PHONE,jdbcType=VARCHAR},#{status,jdbcType=CHAR},
        <if test="remark != null">
            #{remark,jdbcType=VARCHAR},
        </if>
        #{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP}, #{updateBy,jdbcType=VARCHAR}
    </trim>
</insert>

如上代码主要是向 T_USER_INFO 表插入用户数据,parameterType 值传入的是实体对象,这里也可以是 map 或者是其他对象。

其中 的 keyProperty 值对应生成主键的字段,resultType 表示要返回的主键的类型,在这里我用的 Integer 类型,你也可以用 String,只要跟实体的字段对应即可。order 属性需要注意一下,不同于支持自增类型的 MySQL 等数据库,Oracle 需要设置设置为 after 才能取到正确的值,但是如果要从序列化中取值,则需要设置为 befor,否则会报错,我上边的代码是从序列中取值所以设置为 befor

标签内的 SEQ_T_USER_INFO 表示该表的序列化,关于创建表序列化代码如下(SEQ_T_USER_INFO 名称随便起,尽量规范即可):

create sequence SEQ_T_USER_INFO
minvalue 1
maxvalue 9999999999999999999999999999
start with 1
increment by 1
cache 20;

字符串 uuid 类型非自增主键, selectKey 如下:

<selectKey keyProperty="id" resultType="java.lang.String" order="BEFORE">
    select sys_guid() from dual
</selectKey>

2. MySQL

<insert id="insertUserInfo" parameterType="club.sscai.entity.UserInfo" >
    <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.string">
        select uuid()
    </selectKey>
    insert into T_USER_INFO 
        (id, user_name, PASSWORD,PHONE,STATUS,REMARK,CREATE_TIME,UPDATE_TIME,UPDATE_BY)
    values 
    (#{id},#{userName},#{password},#{phone},#{status},省略...)
</insert>

上方是 MySQL 通过 select uuid() 就能得到 uuid 字符串,实现 UUID 字符串形式的主键生成。如果需要 int 类型则如下所示:

<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
    select LAST_INSERT_ID()
</selectKey>

至此,关于主键生成基本已经完事了,再额外补充关于 order = befor、after 的应用。

如果你使用的是 UUID() 这种形式的,建议选择 order = befor,而 order = after 更适合返回自增(int)类型的主键。


我创建了一个用来记录自己学习之路的公众号,感兴趣的小伙伴可以关注一下微信公众号:niceyoo

Mybatis「MySQL-Oracle」 中主键自动生成 <selectKey> 序列化的更多相关文章

  1. hibernate主键自动生成

    Entity类中,主键尽量使用可以为null值的类型,比如Integer,Long,String等,不要用int,long等.因为如果主键为null,则表示该实体类还没有保存到数据库,是一个临时状态( ...

  2. mybatis与mysql插入时返回主键id的值

    <insert id="insertCharge" parameterType="com.bb.bean.Rechargerecord"> < ...

  3. mybatis用mysql数据库自增主键,插入一条记录返回新增记录的自增主键ID

    今天在敲代码的时候遇到一个问题,就是往数据库里插入一条记录后需要返回这个新增记录的ID(自增主键), 公司框架用的是mybatis的通用Mapper接口,里面的插入方法貌似是不能把新纪录的ID回填到对 ...

  4. MySql主键自动生成,表、实体、C#调用方法

    1.表:mysql建表语句 DROP TABLE IF EXISTS `keycode`; CREATE TABLE `keycode` ( `Id` ) NOT NULL AUTO_INCREMEN ...

  5. SQL Server主键自动生成_表and存储过程

    主键表: CREATE TABLE [dbo].[KEYCODE]( [KeyName] [varchar](12) NOT NULL, [KeyTableName] [varchar](40) NU ...

  6. Entity Framework Code First 遭遇主键自动生成问题

    4.0后就没有去跟踪后面的版本了.现在直接开始用5.0没想到在做User的GURD时就遭遇insert不进数据问题. ISet<User>.Add(user);_context.SaveC ...

  7. Oracle主键自动生成_表and存储过程

    -- Create table create table T_EB_SYS_DN_SEQUENCE_CONFIG ( sequence_id VARCHAR2(36) default sys_guid ...

  8. mysql insert一条记录后怎样返回创建记录的主键id,last_insert_id(),selectkey

    mysql插入数据后返回自增ID的方法 mysql和oracle插入的时候有一个很大的区别是,oracle支持序列做id,mysql本身有一个列可以做自增长字段,mysql在插入一条数据后,如何能获得 ...

  9. MyBatis插入时获取自增长主键

    在某些场景下,我们需要使用mybatis返回生成的主键值.Mybatis在insert和update标签中就提供了这种功能. 方法1: <insert id=”indetifyId” useGe ...

随机推荐

  1. enum一个最不像class的class

    enum一个最不像class的classjava枚举类型是jdk5出现的.它的出现主要为了解决一些有特殊意义,已经确定的,长度不会改变的集合. //月份描述 public class Month { ...

  2. IntelliJ IDEA 创建java application

    1.打开IntelliJ IDEA,选择File——New——Project... 2.选择左侧的java,然后在右侧的Project SDK 中添加 java 环境目录,点击Next 3. 在下面的 ...

  3. [转帖]k8s 中的服务如何沟通

    k8s 中的服务如何沟通 https://www.jianshu.com/p/9fae09876eb7 本文将介绍 k8s 中的服务如何相互访问,例如后端服务访问数据库,不同类型的服务间的相互访问.并 ...

  4. Spring Cloud灰度发布之Nepxion Discovery

    <蓝绿部署.红黑部署.AB测试.灰度发布.金丝雀发布.滚动发布的概念与区别> 最近公司项目在做架构升级,升级为 Spring Cloud,我们希望能够做到服务的灰度发布,根据访问量逐渐切换 ...

  5. win10系统优化

    1.服务:关闭 windows update\ windows search \ windows 备份 2.系统:高级系统设置->性能最优,同事修改虚拟内存如下 3.任务管理器:关闭多余的启动项 ...

  6. keyword:react native bridge

    js engine native react native bridge https://cn.bing.com/images/search?view=detailV2&id=AAF39636 ...

  7. 【LeetCode】230. Kth Smallest Element in a BST

    Difficulty: Medium  More:[目录]LeetCode Java实现 Description https://leetcode.com/problems/kth-smallest- ...

  8. thinkphp3.2.3集成phpexcel1.8导出设置单元格合并

    1 到这里下载classes里面的文件 https://github.com/PHPOffice/PHPExcel 2 然后放到 thinkphp的vendor 新建一个文件夹 Phpexcel  然 ...

  9. Java-Iterator遍历集合

    import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Ite ...

  10. Web API 2 的操作结果

    这是msdn原文文档!明天用,留存. Web API 控制器操作可以返回以下任何内容: void HttpResponseMessage IHttpActionResult 其他类型 根据返回的这种情 ...