开发者社区> 技术小阿哥> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

MySQL实现序列(Sequence)效果以及在Mybatis中如何使用这种策略

简介:
+关注继续查看

前言:

在oracle中一般使用序列(Sequence)来处理主键字段,在MySQL中是没有序列的,但是MySQL有提供了自增长(increment)来实现类似的目的,但也只是自增,而不能设置步长、开始索引、是否循环等。最重要的是一张表只能设置一个字段使用自增,但有的时候我们需要两个或两个以上的字段实现自增(单表多字段自增),MySQL本身是实现不了的,但我们可以用创建一个序列表,使用函数来获取序列的值

一 MySQL中序列的实现

(1)新建一个测试表:

1
2
3
4
5
6
7
8
9
10
11
12
DROP TABLE IF EXISTS `article`;
CREATE TABLE `article` (
  `id` int(11) NOT NULL,
  `namevarchar(100) DEFAULT NULL,
  `author` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of article
-- ----------------------------
INSERT INTO `article` VALUES ('1''程序猿的自我修养''zifangsky');

注意,这里并没有设置主键自增

(2)添加序列表并添加测试数据:

1
2
3
4
5
6
7
8
9
10
11
12
DROP TABLE IF EXISTS `sequence`;
CREATE TABLE `sequence` (
  `seq_name` varchar(50) NOT NULL,
  `current_val` int(11) NOT NULL,
  `increment_val` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`seq_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of board_event_success
-- ----------------------------
INSERT INTO `sequenceVALUES ('seq_article''0''1');
  • “seq_name”字段表示一个表的的序列,起名最好跟表的名字相关,并且每个表一条数据

  • “current_val”字段表示“seq_name”字段所对应的表的当前最大ID(主键ID)

  • “increment_val”字段表示“seq_name”字段所对应的表的主键ID增长的步长(也就是每次自增+1、+2等)

(3)创建一个用于获取一个表当前最大ID的函数:

1
2
3
4
5
6
7
8
9
10
11
DROP FUNCTION IF EXISTS `currval`;
DELIMITER ;;
CREATE FUNCTION `currval`(v_seq_name VARCHAR(50)) RETURNS int(11)
begin     
    declare value integer;       
    set value = 0;       
    select current_val into value from sequence where seq_name = v_seq_name; 
   return value; 
end
;;
DELIMITER ;

从代码可以看出,这个函数的逻辑很简单,就是根据“seq_name”查询“sequence”这个表的“current_val”这个字段的值

测试:

1
mysql> select currval('seq_article');

很显然,现在输出为0

(4)创建一个用于获取一个表下一个ID的函数:

1
2
3
4
5
6
7
8
9
DROP FUNCTION IF EXISTS `nextval`;
DELIMITER ;;
CREATE FUNCTION `nextval`(v_seq_name VARCHAR(50)) RETURNS int(11)
begin
    update sequence set current_val = current_val + increment_val where seq_name = v_seq_name;
    return currval(v_seq_name);
end
;;
DELIMITER ;

这个函数的逻辑也很简单,先是更新“sequence”这个表中的某一个表的序列值,然后再次查询该序列值作为插入数据时的主键ID

测试:

1
mysql> select nextval('seq_article');

很显然,执行这个函数的结果是1,同时“sequence”这个表中的对应的记录也增加了1

二 Mybatis中的序列使用

使用插件生成一个表对应的Mapper.xml文件时需要修改其生成策略,具体来说就是修改generatorConfig.xml文件,修改一个表的基本数据的生成策略:

1
2
3
4
<table tableName="article" domainObjectName="Article" enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="false" enableUpdateByExample="false">
    <property name="ignoreQualifiersAtRuntime" value="false"/>
    <generatedKey column="id" sqlStatement="select nextval('seq_article');"/>
</table>

然后运行插件,最后我们可以看到生成的insert方法是这样的:

1
2
3
4
5
6
7
8
9
  <insert id="insert" parameterType="cn.zifangsky.model.Article" >
    <selectKey resultType="java.lang.Integer" keyProperty="id" order="BEFORE" >
      select nextval('seq_article');
    </selectKey>
    insert into article (id, name, author
      )
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{author,jdbcType=VARCHAR}
      )
  </insert>

也就是说使用Mybatis插入数据时,它先是通过 nextval 函数查出待插入数据的主键ID之后,再进行数据的插入




本文转自 pangfc 51CTO博客,原文链接:http://blog.51cto.com/983836259/1889590,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Mybatis动态SQL语句查询,实现一个参数 可查询多个字段。
Mybatis动态SQL语句查询,实现一个参数 可查询多个字段。
0 0
MyBatis使用PageHelper实现分页查询
MyBatis使用PageHelper实现分页查询
0 0
springboot使用mybatis多数据源动态切换的实现
springboot使用mybatis多数据源动态切换的实现
0 0
Mybatis中sql拦截增强-AOP+interceptor实现分页和排序
基于interceptor可以实现sql的完整打印,除了实现打印之外。其实还可以实现分页和排序,下面的分页和排序基于aop+mybatis的interceptor实现。其本质还是对mappedStament的boundSql进行增强。 下面的项目来源于github,通过这个我们可以很好的学习mybatis中插件interceptor的使用。
0 0
基于JSP+Mybatis实现的CRM客户关系管理系统
基于JSP+Mybatis实现的CRM客户关系管理系统
0 0
MyBatis的优点和缺点以及MyBatis 实现一对一的方式介绍
1、什么是 MyBatis,2、MyBatis 的优点和缺点,3、#{}和${}的区别是什么,4、当实体类中的属性名和表中的字段名不一样 ,怎么办?, 5、MyBatis 实现一对一有几种方式?具体怎么操作的,(联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在 resultMap 里面配置 association 节点配置一对一的类就可以完成;)
0 0
SpringBoot+Vue+Mybatis+Redis实现汽车租赁系统【毕设专用、源码、数据库设计】
SpringBoot+Vue+Mybatis+Redis实现汽车租赁系统【毕设专用、源码、数据库设计】
0 0
详解mybatis实现crud
详解mybatis实现crud
0 0
springboot03、实现mybatis
springboot03、实现mybatis
0 0
【Mybatis】学习笔记02:实现简单的查
【Mybatis】学习笔记02:实现简单的查
0 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Java Spring Boot开发实战系列课程【第6讲】:Spring Boot 2.0实战MyBatis与优化(Java面试题)
立即下载
从理论到实践,深度解析MySQL Group Replication
立即下载
MySQL表和索引优化实战
立即下载