SpringBoot整合redis

一、介绍

  • SpringBoot提供了Spring-data-redis的整合方法,整合了redisTemplate等调用方法和jedis连接池的实现,无须像SpringMVC进行繁琐的xml配置,配置全部在application.properties中完成。同时,Spring-Session-redis的整合也可以使用相同的配置项。

二、框架搭建

  • redis环境,自行搭建,参考

    https://redis.io/

  • 引入pom

         <!-- spring redis -->
     	<dependency>
     		<groupId>org.springframework.boot</groupId>
     		<artifactId>spring-boot-starter-data-redis</artifactId>
     	</dependency>
    
  • application.properties配置项中添加如下配置:

      ########################################################
      ###Redis连接配置
      ########################################################
      ##Redis数据库索引(默认为0)
      spring.redis.database=2
      spring.redis.host=127.0.0.1
      spring.redis.port=6380
      spring.redis.password=test2016
      ## 连接池中的最大空闲连接
      spring.redis.pool.max-idle=2000
      ## 连接池中的最小空闲连接
      spring.redis.pool.min-idle=1
      ## 连接池最大连接数(使用负值表示没有限制)
      spring.redis.pool.max-active=1000
      ## 连接池最大阻塞等待时间(使用负值表示没有限制)
      spring.redis.pool.max-wait=-1
      ## 连接超时时间(毫秒)
      spring.redis.timeout=100000
    

三、 基础配置

  • 创建配置类,@EnableCaching注解启用缓存;这里务必对key和value的序列化方式进行定义,否则存储redis时会处理乱码情况。

      import org.springframework.cache.CacheManager;
      import org.springframework.cache.annotation.CachingConfigurerSupport;
      import org.springframework.cache.annotation.EnableCaching;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.data.redis.cache.RedisCacheManager;
      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.serializer.Jackson2JsonRedisSerializer;
      
      import com.fasterxml.jackson.databind.ObjectMapper;
      
      /**
       * @author xiaojin_wu
       * @email wuxiaojin258@126.com
       * @date 2018年3月13日
       * @description redis缓存管理
       */
      @Configuration
      @EnableCaching//启用缓存
      public class RedisConfig extends CachingConfigurerSupport{
          
          /**	springboot注入连接池	*/
      	@Autowired  
          private JedisConnectionFactory jedisConnectionFactory;
          
          @SuppressWarnings("rawtypes")
      	@Bean
          public CacheManager cacheManager(RedisTemplate redisTemplate) {
              RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
              return rcm;
          }
          /**
           * RedisTemplate配置
           * @param factory
           * @return
           */
          @SuppressWarnings({ "rawtypes", "unchecked" })
      	@Bean
          public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {
              RedisTemplate template = new StringRedisTemplate(factory);
              //定义value的序列化方式
              Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
              ObjectMapper om = new ObjectMapper();
              om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
              jackson2JsonRedisSerializer.setObjectMapper(om);
              
             // template.setKeySerializer(redisSerializer);
              template.setValueSerializer(jackson2JsonRedisSerializer);
              template.setHashValueSerializer(jackson2JsonRedisSerializer);
              //设置连接池
              template.setConnectionFactory(jedisConnectionFactory);
              template.afterPropertiesSet();
              return template;
          }
          
      
      }
    

四、基础封装

  • 创建redis服务

     import java.util.Set;
     import java.util.concurrent.TimeUnit;
     
     /**
      * @author 
      * 		xiaojin_wu
      * @email 
      * 		wuxiaojin258@126.com
      * @date 
      * 		2018年1月31日
      * @description 
      * 		redis服务
      */
     public interface IRedisService {
     	
     	/**
          * 根据指定key获取String
          * @param key
          * @return
          */
         public String get(String key);
         
         /**
          * 设置Str缓存
          * @param key
          * @param val
          */
         public void set(String key, String val);
         
         /**
          * 设置Str缓存
          * @param key
          * @param val
          * @param 有效时间,单位:秒
          */
         public void set(String key, String val,long validTime);
         
         /**
          * 设置Str缓存
          * @param key
          * @param val
          * @param validTime 
          * 			有效时间,单位:秒
          * @param unit 
          * 			缓存生效时间单位,java.util.concurrent.TimeUnit定义有静态时间单位常量
          */
         public void set(String key, String val,long validTime,TimeUnit unit);
         
         /**
          * 删除指定key
          * @param key
          */
         public void del(String key);
         
         /**
          * 根据指定o获取Object
          * @param o
          * @return
          */
         public Object getObject(Object o);
         
         /**
          * 设置obj缓存
          * @param o1
          * @param o2
          */
         public void setObject(Object o1, Object o2);
         
         /**
          * 删除Obj缓存
          * @param o
          */
         public void delObject(Object o);
         
         /**
          * 根据规则查询集合,通过keys命令查询
          * @deprecated 线上环境性能差,废弃
          * @param pattern
          */
         @Deprecated
         public Set<String> getStringByPattern(String pattern);	
         
         /**
          * 根据规则查询集合,通过keys命令查询
          * @deprecated 线上环境性能差,废弃
          * @param pattern
          */
         @Deprecated
         public Set<Object> getObjectByPattern(String pattern);
         
         /**
          * 存储obj缓存并设置生效时间
          * @param o1
          * @param o2
          */
         public void setObject(Object key, Object val,long validTime,TimeUnit unit);
         
         /**
          * 操作列表进行rightpush
          * @param key
          * @param value
          */
         public void rightPush(Object key,Object value);
         
         /**
          * 操作列表进行leftPush
          * @param key
          * @param value
          */
         public void leftPush(Object key,Object value);
         
         /**
          * 操作列表进行leftPop
          * @param key
          */
         public void leftPop(Object key);
         
         /**
          * 操作列表进行rightPop
          * @param key
          */
         public void rightPop(Object key);
         
         /**
          * 操作列表,分页读取数据
          * @param key
          * @param start
          * @param end
          * @return
          */
         public List<?> range(Object key,long start,long end);
         
         /**
          * 操作列表,读取所有数据
          * @param key
          * @return
          */
         public List<?> rangeAll(Object key);
         
         /**
          * leftPushAll存储数组
          */
         public long leftPushAll(Object key,Object list);
         
         /**
          * rightPushAll存储数组
          */
         public long rightPushAll(Object key,Object list);
         
         /**
          * leftpush存储数组
          * @param key
          * @param list
          */
         public void pushAllToList(Object key,List<?> list,long validtime,TimeUnit unit);
         
         /**
          * 获取有效时间
          * @param key
          * @return
          */
         public long getValidTime(Object key,TimeUnit unit);
         
         /**
          * 使用redis的scan命令迭代进行模糊查询key集合,用于替换keys命令
          * @param pattern
          * 			模糊匹配的字符串
          * @author xiaojin_wu
          * @return
          * 			模糊匹配的key集合
          */
         public Set<String> getListByScan(String pattern);
     }
    
  • 创建redis服务实现类,通过注解自动注入redisTemplate和StringRedisTemplate;此处封装了部分hash操作和list操作。

     import java.util.NoSuchElementException;
     import java.util.Set;
     import java.util.concurrent.TimeUnit;
     
     import javax.annotation.Resource;
     
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.dao.DataAccessException;
     import org.springframework.data.redis.connection.RedisConnection;
     import org.springframework.data.redis.core.Cursor;
     import org.springframework.data.redis.core.RedisCallback;
     import org.springframework.data.redis.core.RedisTemplate;
     import org.springframework.data.redis.core.ScanOptions;
     import org.springframework.data.redis.core.StringRedisTemplate;
     import org.springframework.data.redis.core.ValueOperations;
     
     import com.akucun.applets.common.redis.IRedisService;
     
     /**
      * @author xiaojin_wu
      * @email wuxiaojin258@126.com
      * @date 2018年1月31日
      * @description redis公用方法实现类
      */
     // @Service(version = "1.0.0")
     @org.springframework.stereotype.Service
     public class RedisServiceImpl implements IRedisService {
     
     	@Autowired
     	StringRedisTemplate stringRedisTemplate;
     
     	@Resource(name = "stringRedisTemplate")
     	ValueOperations<String, String> valOpsStr;
     
     	@Autowired
     	RedisTemplate<Object, Object> redisTemplate;
     
     	@Resource(name = "redisTemplate")
     	ValueOperations<Object, Object> valOpsObj;
     
     	/**
     	 * 根据指定key获取String
     	 *
     	 * @param key
     	 * @return
     	 */
     	public String get(String key) {
     		return valOpsStr.get(key);
     	}
     
     	/**
     	 * 设置Str缓存
     	 *
     	 * @param key
     	 * @param val
     	 */
     	public void set(String key, String val) {
     		valOpsStr.set(key, val);
     	}
     
     	/**
     	 * 设置Str缓存
     	 *
     	 * @param key
     	 * @param val
     	 * @param 有效时间,单位:秒
     	 * @description void set(K key, V value, long offset); 这个api是设置从头开始 偏移多少位 void
     	 *              set(K key, V value, long timeout, TimeUnit unit); 这个api才是过期时间
     	 */
     	public void set(String key, String val, long validTime) {
     		valOpsStr.set(key, val, validTime, TimeUnit.SECONDS);
     	}
     
     	/**
     	 * 设置Str缓存
     	 *
     	 * @param key
     	 * @param val
     	 * @param validTime
     	 *            有效时间
     	 * @param unit
     	 *            缓存生效时间单位,java.util.concurrent.TimeUnit定义有静态时间单位常量
     	 */
     	public void set(String key, String val, long validTime, TimeUnit unit) {
     		valOpsStr.set(key, val, validTime, unit);
     	}
     
     	/**
     	 * 删除指定key
     	 *
     	 * @param key
     	 */
     	public void del(String key) {
     		stringRedisTemplate.delete(key);
     	}
     
     	/**
     	 * 根据指定o获取Object
     	 *
     	 * @param o
     	 * @return
     	 */
     	public Object getObject(Object o) {
     		return valOpsObj.get(o);
     	}
     
     	/**
     	 * 设置obj缓存
     	 *
     	 * @param o1
     	 * @param o2
     	 */
     	public void setObject(Object o1, Object o2) {
     		valOpsObj.set(o1, o2);
     	}
     
     	/**
     	 * 删除Obj缓存
     	 *
     	 * @param o
     	 */
     	public void delObject(Object o) {
     		redisTemplate.delete(o);
     	}
     
     	@Override
     	@Deprecated
     	public Set<String> getStringByPattern(String pattern) {
     		return stringRedisTemplate.keys("*" + pattern + "*");
     	}
     
     	@Override
     	public void setObject(Object key, Object val, long validTime, TimeUnit unit) {
     		valOpsObj.set(key, val, validTime, unit);
     	}
     
     	@Override
     	@Deprecated
     	public Set<Object> getObjectByPattern(String pattern) {
     		return redisTemplate.keys("*" + pattern + "*");
     	}
     
     	@Override
     	public void rightPush(Object key, Object value) {
     		redisTemplate.opsForList().leftPush(key, value);
     	}
     
     	@Override
     	public void leftPush(Object key, Object value) {
     		redisTemplate.opsForList().leftPush(key, value);
     	}
     
     	@Override
     	public void leftPop(Object key) {
     		redisTemplate.opsForList().leftPop(key);
     	}
     
     	@Override
     	public void rightPop(Object key) {
     		redisTemplate.opsForList().rightPop(key);
     	}
     
     	@Override
     	public List<?> range(Object key, long start, long end) {
     		return redisTemplate.opsForList().range(key, start, end);
     	}
     
     	@Override
     	public List<?> rangeAll(Object key) {
     		return redisTemplate.opsForList().range(key, 0, -1);
     	}
     
     	@Override
     	public long leftPushAll(Object key, Object list) {
     		return redisTemplate.opsForList().leftPushAll(key, list);
     	}
     
     	@Override
     	public long rightPushAll(Object key, Object list) {
     		return redisTemplate.opsForList().rightPushAll(key, list);
     	}
     
     	@Override
     	public void pushAllToList(Object key, List<?> list, long validtime, TimeUnit unit) {
     		for (Object object : list) {
     			leftPush(key, object);
     		}
     		redisTemplate.expire(key, validtime, unit);
     	}
     
     	@Override
     	public long getValidTime(Object key, TimeUnit unit) {
     		return redisTemplate.getExpire(key, unit);
     	}
     
     	@Override
     	public Set<String> getListByScan(String pattern) {
     		
     		
     
     		Set<String> set = new HashSet<>();
     		long count = 100;//初始化迭代增量
     		redisTemplate.execute(new RedisCallback<Iterable<byte[]>>() {
     
     			@Override
     			public Iterable<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
     
     				ScanOptions options = ScanOptions.scanOptions().match(pattern+"*").count(count).build();
     				boolean done = false;
     				// while循环确保能够获取到有效的cursor
     				while (!done) {
     					Cursor<byte[]> cursor = connection.scan(options);
     					try {
     						while (cursor.hasNext()) {
     							String key = new String(cursor.next());
     							set.add(key);
     						}
     						done = true; // we've made it here, lets go away
     					} catch (NoSuchElementException nse) {
     						System.out.println("使用"+count+"条进行迭代增量不足,加倍进行迭代");
     						options = ScanOptions.scanOptions().match(pattern).count(count * 2).build();
     					} finally {
     						connection.close();
     					}
     				}
     
     				return null;
     			}
     		});
     		return set;
     
     	}
     
     }
    

五、使用注意

  • hash操作使用stringRedisTemplate

  • list、set等redis提供的数据结构操作使用redisTemplate

  • redis的key值命名推荐使用‘:’区分业务,在RedisDesktopManager远程连接redis的工具上会对redis存储的值进行分包分类,便于维护

  • 对redis的key值进行模糊查询是,禁止使用keys命令,此处封装了scan的方式通过迭代进行模糊匹配

  • redis的scan命令会查询出重复记录,因此使用set存储查询结果集,参考:

    http://www.redis.cn/commands/scan.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值