原理:
利用redis的RedisAtomicLong类实现该功能:
让其每天第一次放置一个新的自增的值(一天过期)
然后和每天的日期相加就可以了
例子: 20180901 + 001 ;当天就是 20180901 + 002
如果要多少个0,可以自己配置(工具类中)
一、pom.xml配置
redis.clients
jedis
2.9.0
org.springframework.data
spring-data-redis
1.7.2.RELEASE
二、redisTemplate配置
importcom.fasterxml.jackson.annotation.JsonAutoDetect;importcom.fasterxml.jackson.annotation.PropertyAccessor;importcom.fasterxml.jackson.databind.ObjectMapper;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.data.redis.connection.RedisConnectionFactory;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;importorg.springframework.data.redis.serializer.StringRedisSerializer;
@Configurationpublic classRedisConfig {/*** retemplate相关配置
*@paramfactory
*@return
*/@Beanpublic RedisTemplateredisTemplate(RedisConnectionFactory factory) {
RedisTemplate template = new RedisTemplate<>();//配置连接工厂
template.setConnectionFactory(factory);//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om= newObjectMapper();//指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);//指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om);//值采用json序列化
template.setValueSerializer(jacksonSeial);//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(newStringRedisSerializer());//设置hash key 和value序列化模式
template.setHashKeySerializer(newStringRedisSerializer());
template.setHashValueSerializer(jacksonSeial);
template.afterPropertiesSet();returntemplate;
}
}
三、代码实现
importjava.util.Set;importjava.util.concurrent.TimeUnit;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.core.StringRedisTemplate;importorg.springframework.data.redis.support.atomic.RedisAtomicLong;importorg.springframework.stereotype.Component;
@Componentpublic classCacheService {//这里因为有其他的template,所以名字起得不好看
@Autowired
RedisTemplateObjectRedisTemplate;publicLong getIncrementNum(String key) {//不存在准备创建 键值对
RedisAtomicLong entityIdCounter = newRedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long counter=entityIdCounter.incrementAndGet();if ((null == counter || counter.longValue() == 1)) {//初始设置过期时间
System.out.println("设置过期时间为1天!");
entityIdCounter.expire(1, TimeUnit.DAYS);//单位天
}returncounter;
}
}
四、工具类(可以直接添加方法)
public classSequenceUtils {static final int DEFAULT_LENGTH = 3;public static String getSequence(longseq) {
String str=String.valueOf(seq);int len =str.length();if (len >= DEFAULT_LENGTH) {//取决于业务规模,应该不会到达3
returnstr;
}int rest = DEFAULT_LENGTH -len;
StringBuilder sb= newStringBuilder();for (int i = 0; i < rest; i++) {
sb.append('0');
}
sb.append(str);returnsb.toString();
}
}
五、测试
String currentDate = new SimpleDateFormat("yyyyMMdd").format(newDate());
Long num= cacheService.getIncrementNum("demo_get_the_new_" + "test3_"+currentDate);
String flowCode=SequenceUtils.getSequence(num);
logger.info("流水号: " + flowCode);
六、控制台输出
设置过期时间为1天!流水号0001
设置过期时间为1天!流水号0002