标题不知道怎么叙述,就这样吧。
需求:
解决:
1、新建表
CREATE TABLE `man_busi_code` (
`busi_type` int(11) NOT NULL COMMENT '类型id',
`busi_desc` varchar(255) DEFAULT NULL COMMENT '描述',
`prefix` varchar(255) DEFAULT NULL COMMENT '前缀',
`suffix` varchar(255) DEFAULT NULL COMMENT '后缀',
`granularity` int(11) NOT NULL DEFAULT '0' COMMENT '时间粒度 0 不按时间 1 日 2 月 3 季 4 年',
`gen_time` date DEFAULT NULL COMMENT '时间',
`gen_val` int(11) NOT NULL DEFAULT '1' COMMENT '序列',
`extent` int(11) NOT NULL DEFAULT '1' COMMENT '填充位数'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
注:类型id:区分字段。比如现在要的是申报流水号,可以统一定为 1。下一次你需要采购流水号 你可以定为2,这样多个需求共用。
前缀、后缀:会自动拼接在返回的流水号前后。我这里为空。
时间粒度:表示是按日从0开始还是按月等等。比如当是1时,我第二天第一次操作返回地数000000重新开始。
填充位数:也就是你要返回数的长度。比如我要的时六位的流水号,此时这个值就是6。
2、在数据库创建函数:
(存储过程?)
CREATE PROCEDURE `f_generator_busi_code`(IN i_busi_type int, OUT v_code varchar(50))
BEGIN
DECLARE v_cnt int DEFAULT 0;
DECLARE v_granularity int;
DECLARE v_fmt varchar(50);
set v_code='';
START TRANSACTION;
select count(*)
into v_cnt
from man_busi_code
where busi_type = i_busi_type;
if v_cnt > 0 then
select distinct granularity
into v_granularity
from man_busi_code
where busi_type = i_busi_type;
case v_granularity
when 0 then
select CONCAT( IFNULL(t.prefix,''), lpad(t.gen_val + 1, t.extent, '0'),IFNULL(t.suffix,''))
into v_code
from man_busi_code t
where t.busi_type = i_busi_type ;
update man_busi_code t
set t.gen_val = t.gen_val + 1
where t.busi_type = i_busi_type;
when 1 then
SET v_fmt='%Y%m%d';
when 2 then
SET v_fmt='%Y%m';
when 3 then
select CONCAT( IFNULL(t.prefix,''), DATE_FORMAT(now(),'%Y'),quarter(now()),lpad(t.gen_val + 1, t.extent, '0'),IFNULL(t.suffix,''))
into v_code
from man_busi_code t
where
CONCAT(DATE_FORMAT(t.gen_time,'%Y'),quarter(t.gen_time))=CONCAT(DATE_FORMAT(now(), '%Y'),quarter(now()))
and t.busi_type = i_busi_type LIMIT 1;
if LENGTH(v_code)>0 then
update man_busi_code t
set t.gen_val = t.gen_val + 1
where CONCAT(DATE_FORMAT(t.gen_time,'%Y'),quarter(t.gen_time))=CONCAT(DATE_FORMAT(now(), '%Y'),quarter(now()))
and t.busi_type = i_busi_type;
else
select CONCAT( IFNULL(t.prefix,''), DATE_FORMAT(now(),'%Y'),quarter(now()),lpad(1, t.extent, '0'),IFNULL(t.suffix,''))
into v_code
from man_busi_code t
where t.busi_type = i_busi_type LIMIT 1;
insert into man_busi_code(
busi_type, busi_desc, prefix, suffix, granularity, gen_time, gen_val, extent
) select t.busi_type ,t.busi_desc,t.prefix ,t.suffix,t.granularity,NOW(),1,t.extent from man_busi_code t
where t.busi_type=i_busi_type LIMIT 1;
end if;
when 4 then
SET v_fmt='%Y';
end case;
if v_granularity != 3 and v_granularity != 0 then
select CONCAT( IFNULL(t.prefix,''), DATE_FORMAT(now(),v_fmt),lpad(t.gen_val + 1, t.extent, '0'),IFNULL(t.suffix,''))
into v_code
from man_busi_code t
where
DATE_FORMAT(t.gen_time,v_fmt)=DATE_FORMAT(now(), v_fmt )
and t.busi_type = i_busi_type LIMIT 1;
if LENGTH(v_code)>0 then
update man_busi_code t
set t.gen_val = t.gen_val + 1
where DATE_FORMAT(t.gen_time,v_fmt)=DATE_FORMAT(now(), v_fmt ) and t.busi_type = i_busi_type;
else
select CONCAT( IFNULL(t.prefix,''), DATE_FORMAT(now(),v_fmt),lpad(1, t.extent, '0'),IFNULL(t.suffix,''))
into v_code
from man_busi_code t
where t.busi_type = i_busi_type limit 1;
insert into man_busi_code(
busi_type, busi_desc, prefix, suffix, granularity, gen_time, gen_val, extent
) select t.busi_type ,t.busi_desc,t.prefix ,t.suffix,t.granularity,NOW(),1,t.extent from man_busi_code t
where t.busi_type=i_busi_type LIMIT 1;
end if;
end if;
end if;
COMMIT;
if LENGTH(v_code)=0 then
set v_code='没有找到代码';
end if;
END
在下面可以拼接你要返回的值,比如我在中间加了DATE_FORMAT(now(),v_fmt),返回的数据在中间会拼上当前的年数(此时v_fmt =‘%Y’)
3、java程序调用:
我用的基于注解的方式:
mapper层:
@Select(value = "{call f_generator_busi_code( #{input, mode=IN, jdbcType=INTEGER}, #{output, mode=OUT, jdbcType=VARCHAR} )}")
@Options(statementType = StatementType.CALLABLE)
public void getShenpin(Map map);
service层:
@Transactional(readOnly = false, rollbackFor = Exception.class)
public Map test(Map map){
map.put("input", 1);
map.put("output", "");
tbRegistInfoMapper.getShenpin(map);
return map;
}
参数input,就是上面的类型id,代表当前时审批流水号。output为返回地数。调用过tbRegistInfoMapper.getShenpin(map);之后,调用map.get("output")就返回了你要的值。
4、在使用之前,需要在数据表里加上一个种子,也就是加上一条数据,以后就不用管了。
我们架构师教我的一种方法,现学现卖,哈哈!