Mybatis中selectKey的使用
|Word count:746|Reading time:3min|Post View:
本篇介绍一下Mybatis中selectKey的使用。
在开发过程中,CRUD是免不了的,在插入数据时,通常我们只需要返回受影响行数
即可,但也有些场景需要返回插入数据后的主键ID,在Mybatis中只需要使用selectKey
即可实现。
自增主键使用示例
通常我们会将SQL写在MyBatis的*Mapper.xml
文件中,本次示例也是如此
创建表
1 2 3 4 5 6 7
| 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
|
插入数据并返回自增主键
1 2 3 4 5 6 7 8 9 10 11 12
| <?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
来实现的自增。
创建表
1 2 3 4
| create table t_grade( gid number(6) primary key, --主键 gradeName varchar2(20) not null -- 年级名称 );
|
创建sequence
1 2 3 4 5 6
| CREATE SEQUENCE g_seq INCREMENT BY 1 -- 每次加几个 START WITH 1 -- 从1开始计数 NOMAXvalue -- 不设置最大值 NOCYCLE -- 一直累加,不循环 CACHE 10;
|
插入数据并返回自增序列
1 2 3 4 5 6 7 8 9 10 11 12
| <?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
类里面了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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)
的返回值。