场景:springboot+mybatis项目中,需要获取自增id作为表单数据自增id主键,则可以通过自定义nextval函数来进行调用。

一、数据库准备:定义序列表与nextval自增id函数 

--定义序列表TPL_SEQ_PROPERTY_S
DROP TABLE IF EXISTS TPL_SEQ_PROPERTY_S;
CREATE TABLE `TPL_SEQ_PROPERTY_S`(
`ID` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, 
`SEQ_NAME` CHAR(20) NOT NULL DEFAULT 'SEQ',
PRIMARY KEY(`ID`) ) AUTO_INCREMENT=1;---设置起点从1开始
---UNSIGNED :无符号整数,非负数,可以扩大正数的范围,如有符号的TINYINT类型能表示-128至128,而无符号(unsigned)的TINYINT类型就可以表示0至256了

--定义函数NEXTVAL
CREATE DEFINER=`root`@`%` FUNCTION `NEXTVAL`() RETURNS BIGINT(20) DETERMINISTIC
BEGIN
DECLARE current BIGINT;
INSERT INTO TPL_SEQ_PROPERTY_S(SEQ_NAME) VALUES ('SEQ');
SELECT LAST_INSERT_ID() INTO current;
RETURN current;
END

 LAST_INSERT_ID():MySQL内置函数,获取MySQL生成的最后一个插入id的值

二、创建dao层接口与对应的数据映射文件XML

后台数据库的工作做好之后,接着就到springboot项目中resources目录下的IpowerDao.xml进行函数调用(xml文件在resources目录下,创建路径与对应的dao层一致),在此之前先创建好dao层接口类IpowerDao.java,如下:

package com.power.it.app.dao;

import org.springframework.stereotype.Repository;

@Repository
public interface IpowerDao{

//获取自增ID序列
public int getSeq();
}

IpowerDao.xml如下: 

<?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="com.power.it.app.dao.IpowerDao">
    <select id="getSeq" resultType="java.lang.Integer" useCache="false" flushCache="true">
        SELECT SCHEMA.NEXTVAL();
    </select>
</mapper>

这里有个问题需要重点注意,我们springboot项目一般都有做事务管理,而这个自增ID函数的实现逻辑是先插入序列表一条件数据,ID字段则会自增长,再通过调用LAST_INSERT_ID()内置函数取到最后插入的数据的ID值,事务还未提交完成(当全部程序执行完成才会提交),调用内置函数取值则会一直取到最后插入之前的那个ID值,需要通过设置两个参数进行清空缓存。否则就无法取到自增ID值。 

(1)当为select语句时:

flushCache默认false,本条语句被调用后不会清空本地缓存和二级缓存。

useCache默认true,会把本条语句的结果进行二级缓存。

(2)当为insert、update、delete语句时:

flushCache默认true,本条语句被调用后会导致本地缓存和二级缓存被清空。

(3)select语句的时候,如果没有去配置flushCache、useCache,那么默认是启用缓存的,所以需要人工修改配置使其清空缓存,修改结果类似下面:

    <select id="getSeq" resultType="java.lang.Integer" flushCache="true" useCache="false">         SELECT SCHEMA.NEXTVAL();
    </select>  

(4)update语句设置 flushCache="false",则当你更新后,查询的数据数据还是老的数据。

service 层与 controller层则根据业务具体需求来进行调用dao层的数据接口即可

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐