简单介绍 Springboo-Redis

Springboot-Redis

  • springboot简单集成redis
    • springboot版本问题
    • jedis和lettuce
    • 首先介绍以jedis的方式
      • pom依赖
      • redis连接器配置config
      • 缓存策略的封装
      • 使用redis
    • 以Lettuce作为连接池配置
      • pom文件加入新的依赖
      • application.yml

springboot简单集成redis

springboot版本问题

首先在开始的时候,我们应该注意到springboot的版本,在springboot1.x版本是默认使用的jedis作为连接redis的驱动,在springboot2.x及以上的版本默认使用的是Lettuce作为redis的连接池,那么这两个有什么区别呢?

jedis和lettuce

jedis在实现上是直接连接redis server的,在多线程的情况下,并非是线程安全的,当然我们可以在应用层面来保证线程安全,但是我们希望我们在做业务的时候,不需要关系太多其他插件的细节。在这种情况下Lettuce就出现了,Lettuce的连接是基于Netty的,可以在多个线程间并发访问,并且Lettuce是线程安全的。 本次介绍我们将会依次使用jedis和Lettuce,可以根据自己的需求进行选择。

首先介绍以jedis的方式

pom依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

redis连接器配置config

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

//    @Bean
//    public RedisConnectionFactory factory(){
//        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
//        // host
//        jedisConnectionFactory.setHostName("");
//        // 端口
//        jedisConnectionFactory.setPort(6379);
//        // 密码
//        jedisConnectionFactory.setPassword("");
//        // 连接超时时间
//        jedisConnectionFactory.setTimeout(2000);
//        // 默认连接数量配置
//        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//        jedisPoolConfig.setMaxIdle(8);
//        jedisPoolConfig.setMinIdle(0);
//        jedisPoolConfig.setMaxTotal(8);
//        jedisConnectionFactory.setPoolConfig(jedisPoolConfig);
//        return jedisConnectionFactory;
//    }

    /**
     * redistemplate相关配置
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String, ?> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, ?> template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(factory);
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,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(new StringRedisSerializer());
        // 设置hash key 和value序列化模式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jacksonSeial);
        // 初始化配置
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 对hash类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public HashOperations<String, String, ?> hashOperations(RedisTemplate<String, ?> redisTemplate) {
        return redisTemplate.opsForHash();
    }

    /**
     * 对redis字符串类型数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ValueOperations<?, ?> valueOperations(RedisTemplate<?, ?> redisTemplate) {
        return redisTemplate.opsForValue();
    }

    /**
     * 对链表类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ListOperations<?, ?> listOperations(RedisTemplate<?, ?> redisTemplate) {
        return redisTemplate.opsForList();
    }

    /**
     * 对无序集合类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public SetOperations<?, ?> setOperations(RedisTemplate<?, ?> redisTemplate) {
        return redisTemplate.opsForSet();
    }

    /**
     * 对有序集合类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ZSetOperations<?, ?> zSetOperations(RedisTemplate<?, ?> redisTemplate) {
        return redisTemplate.opsForZSet();
    }

jedis的连接配置我们可以通过代码配置,也可以通过配置文件配置,一般的我们会通过配置文件进行配置,这样在多环境切换的时候更加的灵活,以下是配置文件的内容

spring:
  redis:
    host: localhost
    password: 123
    port: 6379
    pool:
      max-active: 8
      max-wait: -1
      max-idle: 8
      min-idle: 0

如果没有pssword参数,可以直接删除

缓存策略的封装

@Service
public class RedisService {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    /**
     * 默认过期时长,单位:秒
     */
    public static final long DEFAULT_EXPIRE = 60 * 60 * 24;
    /**
     * 不设置过期时长
     */
    public static final long NOT_EXPIRE = -1;
    public boolean existsKey(String key) {
        return redisTemplate.hasKey(key);
    }
    /**
     * 重名名key,如果newKey已经存在,则newKey的原值被覆盖
     *
     * @param oldKey
     * @param newKey
     */
    public void renameKey(String oldKey, String newKey) {
        redisTemplate.rename(oldKey, newKey);
    }
    /**
     * newKey不存在时才重命名
     *
     * @param oldKey
     * @param newKey
     * @return 修改成功返回true
     */
    public boolean renameKeyNotExist(String oldKey, String newKey) {
        return redisTemplate.renameIfAbsent(oldKey, newKey);
    }
    /**
     * 删除key
     *
     * @param key
     */
    public void deleteKey(String key) {
        redisTemplate.delete(key);
    }
    /**
     * 删除多个key
     *
     * @param keys
     */
    public void deleteKey(String... keys) {
        Set<String> kSet = Stream.of(keys).map(k -> k).collect(Collectors.toSet());
        redisTemplate.delete(kSet);
    }
    /**
     * 删除Key的集合
     *
     * @param keys
     */
    public void deleteKey(Collection<String> keys) {
        Set<String> kSet = keys.stream().map(k -> k).collect(Collectors.toSet());
        redisTemplate.delete(kSet);
    }
    /**
     * 设置key的生命周期
     *
     * @param key
     * @param time
     * @param timeUnit
     */
    public void expireKey(String key, long time, TimeUnit timeUnit) {
        redisTemplate.expire(key, time, timeUnit);
    }
    /**
     * 指定key在指定的日期过期
     *
     * @param key
     * @param date
     */
    public void expireKeyAt(String key, Date date) {
        redisTemplate.expireAt(key, date);
    }
    /**
     * 查询key的生命周期
     *
     * @param key
     * @param timeUnit
     * @return
     */
    public long getKeyExpire(String key, TimeUnit timeUnit) {
        return redisTemplate.getExpire(key, timeUnit);
    }
    /**
     * 将key设置为永久有效
     *
     * @param key
     */
    public void persistKey(String key) {
        redisTemplate.persist(key);
    }
}

该配置是一些一般的缓存策略的封装,包括查询key的存在,或者设置缓存的过期时间等

使用redis

	// 加入依赖, 以普通字符串类型的缓存作演示
    @Autowired
    private ValueOperations<String,Object> valueOperations;
    // 加入缓存策略
    @Autowired
    private RedisService redisService;
    
    public void setRedisMessage(){
    	try{
    		// 将数据缓存,可以直接存储自定义对象,我们在配置conifg的时候已经指定了序列化工具
        	valueOperations.set(key,Object);
        	// 设置这个key对应的缓存的过期时间,此处设置为60s过期
        	redisService.expireKey(key,60, TimeUnit.SECONDS);
    	}catch(RedisConnectionFailureException e){
			// 使用redis可能会出现失败,典型的redis server未开启或者服务器重启等,需要对异常进行处理。
    	}
    }
    
    public void getRedisVal(){
    	try{
    		// 可以直接取出自定义对象数据,需要进行强制转换,我们在config配置时,指定了序列化方式,因此可以强制转换。
    		Object obj = (Object)valueOperations.get(key);
    	}catch(RedisConnectionFailureException e){
    		//
    	}
    }

通过这样的处理,上面的redis就可以简单的进行使用了,当然你需要在你的本地安装redis server端,网上查一下安装教程,有很详细的安装介绍,这里就不再展开了。

以Lettuce作为连接池配置

pom文件加入新的依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<!--引入lettuce连接池新增的配置 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
			<version>2.4.3</version>
		</dependency>

application.yml

spring:
  redis:
    host: localhost
    password: jy123123
    port: 6379
    lettuce:
      pool:
        # 连接池中的最大空闲连接 默认 8
        max-active: 8
        # 连接池中的最小空闲连接 默认 0
        max-idle: 0
        # 连接池最大阻塞等待时间,单位毫秒(使用负值表示没有限制) 默认 -1
        max-wait: 1000ms
      shutdown-timeout: 100ms

总体上只需要变更这两个地方,其他地方不变,使用方式也和往常一样。(Lettuce和jedis只能选择一种,配置类注释代码在Lettuce无效)

你可能感兴趣的:(java)