• 使用redisTemplate根据key生成自增ID值:RedisAtomicLong


    使用步骤

    1、引入依赖

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <dependencies>
            <!-- SpringBoot redis -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <!-- jackson -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-json</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>

    2、自增ID生成类

    import org.springframework.data.redis.core.*;
    import org.springframework.data.redis.support.atomic.RedisAtomicLong;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import java.io.Serializable;
    import java.util.Date;
    import java.util.List;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    
    
    @Service
    public class RedisUtilService {
    
    
        @Resource
        private RedisTemplate redisTemplate;
    
        /**
         * @Title: generate
         * @Description: Atomically increments by one the current value.
         * @param key
         * @return
         */
        public long generate(String key) {
            RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
            return counter.incrementAndGet();
        }
    
        /**
         * @Title: generate
         * @Description: Atomically increments by one the current value.
         * @param key
         * @return
         */
        public long generate(String key,Date expireTime) {
            RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
            counter.expireAt(expireTime);
            return counter.incrementAndGet();
        }
    
        /**
         * @Title: generate
         * @Description: Atomically adds the given value to the current value.
         * @param key
         * @param increment
         * @return
         */
        public long generate(String key,int increment) {
            RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
            return counter.addAndGet(increment);
        }
    
        /**
         * @Title: generate
         * @Description: Atomically adds the given value to the current value.
         * @param key
         * @param increment
         * @param expireTime
         * @return
         */
        public long generate(String key,int increment,Date expireTime) {
            RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
            counter.expireAt(expireTime);
            return counter.addAndGet(increment);
        }
    
        /**
         * 刷新缓存时间
         * @param key
         * @param expireTime
         * @param timeUnit
         * @return
         */
        public boolean expire(final String key, Long expireTime ,TimeUnit timeUnit) {
            boolean result = false;
            try {
                ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    
        /**
         * 写入缓存
         * @param key
         * @param value
         * @return
         */
        public boolean set(final String key, Object value) {
            boolean result = false;
            try {
                ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
                operations.set(key, value);
    //            System.out.println("11"+operations.get(key));
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
        /**
         * 写入缓存设置时效时间
         * @param key
         * @param value
         * @return
         */
        public boolean set(final String key, Object value, Long expireTime ,TimeUnit timeUnit) {
            boolean result = false;
            try {
                ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
                operations.set(key, value);
                redisTemplate.expire(key, expireTime, timeUnit);
    //            System.out.println("11"+operations.get(key));
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
        /**
         * 批量删除对应的value
         * @param keys
         */
        public void remove(final String... keys) {
            for (String key : keys) {
                remove(key);
            }
        }
    
        /**
         * 批量删除key
         * @param pattern
         */
        public void removePattern(final String pattern) {
            Set<Serializable> keys = redisTemplate.keys(pattern);
            if (keys.size() > 0){
                redisTemplate.delete(keys);
            }
        }
        /**
         * 删除对应的value
         * @param key
         */
        public void remove(final String key) {
            if (exists(key)) {
                redisTemplate.delete(key);
            }
        }
        /**
         * 判断缓存中是否有对应的value
         * @param key
         * @return
         */
        public boolean exists(final String key) {
            return redisTemplate.hasKey(key);
        }
        /**
         * 读取缓存
         * @param key
         * @return
         */
        public Object get(final String key) {
            Object result = null;
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            result = operations.get(key);
            return result;
        }
    
        /**
         * 哈希 添加
         * @param key
         * @param hashKey
         * @param value
         */
        public void hmSet(String key, Object hashKey, Object value){
            HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
            hash.put(key,hashKey,value);
        }
    
        /**
         * 哈希获取数据
         * @param key
         * @param hashKey
         * @return
         */
        public Object hmGet(String key, Object hashKey){
            HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
            return hash.get(key,hashKey);
        }
    
        /**
         * 列表添加
         * @param k
         * @param v
         */
        public void lPush(String k,Object v){
            ListOperations<String, Object> list = redisTemplate.opsForList();
            list.rightPush(k,v);
        }
    
        /**
         * 列表获取
         * @param k
         * @param l
         * @param l1
         * @return
         */
        public List<Object> lRange(String k, long l, long l1){
            ListOperations<String, Object> list = redisTemplate.opsForList();
            return list.range(k,l,l1);
        }
    
        /**
         * 集合添加
         * @param key
         * @param value
         */
        public void add(String key,Object value){
            SetOperations<String, Object> set = redisTemplate.opsForSet();
            set.add(key,value);
        }
    
        /**
         * 集合获取
         * @param key
         * @return
         */
        public Set<Object> setMembers(String key){
            SetOperations<String, Object> set = redisTemplate.opsForSet();
            return set.members(key);
        }
    
        /**
         * 有序集合添加
         * @param key
         * @param value
         * @param scoure
         */
        public void zAdd(String key,Object value,double scoure){
            ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
            zset.add(key,value,scoure);
        }
    
        /**
         * 有序集合获取
         * @param key
         * @param scoure
         * @param scoure1
         * @return
         */
        public Set<Object> rangeByScore(String key,double scoure,double scoure1){
            ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
            return zset.rangeByScore(key, scoure, scoure1);
        }
    }

    3、RedisTemplate配置

    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.interceptor.KeyGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.listener.RedisMessageListenerContainer;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    
    
    import java.lang.reflect.Method;
    
    
    @Configuration
    @EnableCaching
    public class RedisConfig extends CachingConfigurerSupport {
        @Bean
        public KeyGenerator wiselyKeyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(target.getClass().getName());
                    sb.append(method.getName());
                    for (Object obj : params) {
                        sb.append(obj.toString());
                    }
                    return sb.toString();
                }
            };
        }
    
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
            StringRedisTemplate template = new StringRedisTemplate(factory);
            setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口
            template.afterPropertiesSet();
            return template;
        }
    
        /**
         * TODO 监听 Redis键过期事件
         * @author zhuzhen
         * @date 14:38 2018/12/21
         * @param factory
         * @return org.springframework.data.redis.listener.RedisMessageListenerContainer
         */
        @Bean
        RedisMessageListenerContainer container(RedisConnectionFactory factory) {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(factory);
            return container;
        }
    
        private void setSerializer(StringRedisTemplate template) {
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            template.setValueSerializer(jackson2JsonRedisSerializer);
        }
    }

    4、SerialNumber序列号生成工具类

    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class SerialNumber {
        static final int DEFAULT_LENGTH = 4;
    
    
        /**
         *
         * @param prefix (前缀)
         * @param redisKey (redis key)
         * @return
         */
        public static String generate(String prefix,String data, long redisKey) {
            //** 自增 *//*
            String seq = getSequence(redisKey);
            StringBuilder sb = new StringBuilder();
            sb.append(prefix).append(data).append(seq);
            String serial = sb.toString();
            return serial;
        }
    
        /**
         * 填充000
         *
         * @param seq
         * @return
         */
        public static String getSequence(long seq) {
            String str = String.valueOf(seq);
            int len = str.length();
            if (len >= DEFAULT_LENGTH) {// 取决于业务规模,应该不会到达4
                return str;
            }
            int rest = DEFAULT_LENGTH - len;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < rest; i++) {
                sb.append('0');
            }
            sb.append(str);
            return sb.toString();
        }
    
    
        /**
         * 得到系统当前日期
         * "yyyyMMdd"
         */
        public static String getCurentDate() {
            SimpleDateFormat tempDate = new SimpleDateFormat("yyyyMMdd");
            String datetime = tempDate.format(new Date());
            return datetime;
        }
    }

    5、测试类

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = Application.class)
    public class RedisAtomicLongTest {
        @Autowired
        private RedisUtilService redisUtilService;
        @Test
        public void test1(){
            String curentDate = SerialNumber.getCurentDate();
            String key = "serial.number.ghpc:" + curentDate;
            long generate = redisUtilService.generate(key,getTodayEndTime());
            System.out.println(generate);
            String ghpcNumber = SerialNumber.generate("", curentDate, generate);
            System.out.println(ghpcNumber);
        }
        private static Date getTodayEndTime() {
            Calendar todayEnd = Calendar.getInstance();
            todayEnd.set(Calendar.HOUR_OF_DAY, 23);
            todayEnd.set(Calendar.MINUTE, 59);
            todayEnd.set(Calendar.SECOND, 59);
            todayEnd.set(Calendar.MILLISECOND, 999);
            return todayEnd.getTime();
        }
    
    }

    注意:由于key为当天的,故最好设置过期时间,否则该键值对会永久存在。该自增ID缓存的key为“serial.number.ghpc:8位日期”,并且该缓存在当天23:59:59:999时会自动过期,过期后会重置为0。

    第一次运行的结果为:

    1
    202202280001

    第二次运行的结果:

    2
    202202280002

    第三次运行的结果:

    3
    202202280003
  • 相关阅读:
    POJ 1062 坑爹的聘礼(枚举等级差选择性找边)
    c++ string函数详细返回值及用法!
    POJ 2240 利率变权值 Floyd变乘法
    POJ 1797 最大运载量
    API code
    编程题目的讨论
    C语言位运算符:与、或、异或、取反、左移和右移
    &与&& C语言
    反思
    CreateWindow的出错解决
  • 原文地址:https://www.cnblogs.com/zwh0910/p/15944837.html
Copyright © 2020-2023  润新知