公司数据库用的oracle,但是个人开发和自己写东西一般用mysql,觉得序列这个东西还是蛮好用的,但是mysql本身却没有这个功能,于是想自己试着写一下,以后要是啥项目用得上也方便。
网上的有很多,但是有些是会报错,有些很啰嗦,其实没那么复杂。
先说下我的计划需求
1.可以有多个,分开维护不同的序列*(原因是,可能有多个表,也许不想用同一个序列)】
2.可以设置跳的步数,既每下次加几*(一般是+1,但是万一呢)
3.我需要到一个数以后,重新归零,或者到一个设置的值*(这个功能很多人都没写)
我的需求很简单,直接上代码吧。
sql表建表如下:
DROP TABLE IF EXISTS `TB_SEQUENCE`;
CREATE TABLE `TB_SEQUENCE` (
`name` varchar(30) NOT NULL,
`current_value` int(11) NOT NULL,
`increment` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
两个方法,一个方法是获取当前值,一个方法是对数据进行累加和归零判断
CREATE FUNCTION nextval (seq_name VARCHAR(50))
RETURNS BIGINT
CONTAINS SQL
BEGIN
DECLARE value INTEGER;
SET value = 0;
SELECT current_value INTO value
FROM TB_SEQUENCE
WHERE name = seq_name ;
RETURN value;
END
CREATE FUNCTION nextval (seq_name VARCHAR(50))
RETURNS BIGINT
CONTAINS SQL
BEGIN
SELECT current_value INTO @current_value FROM TB_SEQUENCE WHERE name = seq_name;
UPDATE TB_SEQUENCE
SET current_value = current_value + increment
WHERE name = seq_name;
if(@current_value>=1) then
UPDATE TB_SEQUENCE
SET current_value = 0
WHERE name = seq_name;
end if;
RETURN currval(seq_name);
END
@current_value>=1这行代码根据自己需要改,我这里是方便测试写的>=1.也就是当序列大于等于一时,归零。
来测一下吧。
加一条数据
INSERT INTO `TB_SEQUENCE` (`name`, `current_value`, `increment`) VALUES ('default', '0', '1');
SELECT nextval('default');
成功。
java 端调用和测试如下
@current_value>=1这行,改成999999试试。
完美,收工!
其实,如果说还有别的要求是可以把这个更完善的,比如把,归零判断值和归零还是归成别的数,都放在表里维护,这样更灵活。
思路就是,把表扩展一下,加一个max_value 保存最大值,加一个initValue,保存最小值。修改一下nextval就好了。