念念不忘
必有回响

世界,您好!

admin阅读(156)

欢迎使用WordPress。这是您的第一篇文章。编辑或删除它,然后开始写作吧!

 

mybatis中selectKey的使用

admin阅读(64)

在开发过程中,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,它的值有两种,AFTERBEFORE:
    • 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)的返回值。