本篇介绍一下Mybatis中selectKey的使用。
在开发过程中,CRUD是免不了的,在插入数据时,通常我们只需要返回受影响行数
即可,但也有些场景需要返回插入数据后的主键ID,在Mybatis中只需要使用selectKey
即可实现。
自增主键使用示例
通常我们会将SQL写在MyBatis的*Mapper.xml
文件中,本次示例也是如此
创建表
CREATE TABLE `t_user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'UserId', `username` varchar(80) NOT NULL COMMENT 'username', `password` varchar(80) NOT NULL COMMENT 'password', `create_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 'create_time', PRIMARY KEY (`id`) ) ENGINE=InnoDB
插入数据并返回自增主键
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="xyz.cco.sm.mapper.UserMapper"> <insert id="saveUser" parameterType="xyz.cco.sm.mapper.entity.UserEntity"> insert into t_user (username,password) values (#{username},#{password}) <selectKey keyProperty="id" order="AFTER" resultType="Long"> SELECT LAST_INSERT_ID() </selectKey> </insert> </mapper>
selectKey
会将SELECT LAST_INSERT_ID()
的结果存放在传入的UserEntity
中的id属性中。keyProperty
的值是UserEntity
中主键的属性名,本次的值是id
。order
,它的值有两种,AFTER
和BEFORE
:AFTER
表示SELECT LAST_INSERT_ID()
在insert
语句执行之后执行,多用与自增主键(例如MySQL)BEFORE
表示SELECT LAST_INSERT_ID()
在insert
语句执行之前执行,多用于主键不自增(例如Oracle的sequence)
resultType
主键的类型。
非自增主键使用示例
这里主要指Oracle,Oracle没有MySQL那种自增主键,通常都是使用sequence
来实现的自增。
创建表
create table t_grade( gid number(6) primary key, --主键 gradeName varchar2(20) not null -- 年级名称 );
创建sequence
CREATE SEQUENCE g_seq INCREMENT BY 1 -- 每次加几个 START WITH 1 -- 从1开始计数 NOMAXvalue -- 不设置最大值 NOCYCLE -- 一直累加,不循环 CACHE 10;
插入数据并返回自增序列
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="xyz.cco.sm.mapper.GradeMapper"> <insert id="saveUser" parameterType="xyz.cco.sm.mapper.entity.GradeEntity"> <selectKey keyProperty="gid" order="BEFORE" resultType="Long"> SELECT G_SEQ.NEXTVAL FROM dual </selectKey> insert into t_grade (gid,gradeName) values (#{gid},#{gradeName}) </insert> </mapper>
orader
的值一定是BEFORE
- insert语句必须要将主键ID加上去
业务层逻辑
上面两个分部介绍了MySQL自增ID的用法,以及Oracle的序列用法,刚开始我以为返回值就是插入数据的主键ID,结果测试发现每次都是1,没仔细阅读文档,实际上它是将主键ID设置在了传入的Entity
类里面了。
public class UserServiceImpl implements UserService { private final UserMapper userMapper; public UserServiceImpl(UserMapper userMapper) { this.userMapper = userMapper; } @Override public Long insertUserAndGetPrimaryKey(UserBo userBo) { UserEntity entity = new UserEntity(); BeanUtils.copyProperties(userBo, entity); userMapper.saveUser(entity); return entity.getId(); } }
注意return的是entity.getId()
,而不是userMapper.saveUser(entity)
的返回值。