SpringBoot + Redis:基本配置及使用

2020-04-21 15:14:20

参考地址 SpringBoot + Redis:基本配置及使用

一、SpringBoot 配置Redis

  1.1 pom 引入spring-boot-starter-data-redis 包

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

  1.2 properties配置文件配置redis信息

  默认连接本地6379端口的redis服务,一般需要修改配置,例如:

复制代码

# Redis数据库索引(默认为0)
spring.redis.database=0# Redis服务器地址
spring.redis.host=127.0.0.1# Redis服务器连接端口
spring.redis.port=6379# Redis服务器连接密码(默认为空)
spring.redis.password=# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=20# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0# 连接超时时间(毫秒)
spring.redis.timeout=1000

复制代码

二、RedisTemplate<K,V>类的配置

  Spring 封装了RedisTemplate<K,V>对象来操作redis。

  2.1 Spring对RedisTemplate<K,V>类的默认配置(了解即可)

  Spring在 org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration类下配置的两个RedisTemplate的Bean。

  (1) RedisTemplate<Object, Object>

  这个Bean使用JdkSerializationRedisSerializer进行序列化,即key, value需要实现Serializable接口,redis数据格式比较难懂,例如

  

  (2) StringRedisTemplate,即RedisTemplate<String, String>

  key和value都是String。当需要存储实体类时,需要先转为String,再存入Redis。一般转为Json格式的字符串,所以使用StringRedisTemplate,需要手动将实体类转为Json格式。如

复制代码

ValueOperations<String, String> valueTemplate = stringTemplate.opsForValue();
Gson gson = new Gson();

valueTemplate.set("StringKey1", "hello spring boot redis, String Redis");
String value = valueTemplate.get("StringKey1");
System.out.println(value);

valueTemplate.set("StringKey2", gson.toJson(new Person("theName", 11)));
Person person = gson.fromJson(valueTemplate.get("StringKey2"), Person.class);
System.out.println(person);

复制代码

  

  2.2 配置一个RedisTemplate<String,Object>的Bean

   Spring配置的两个RedisTemplate都不太方便使用,所以可以配置一个RedisTemplate<String,Object> 的Bean,key使用String即可(包括Redis Hash 的key),value存取Redis时默认使用Json格式转换。如下

复制代码

    @Bean(name = "template")    public RedisTemplate<String, Object> template(RedisConnectionFactory factory) {        // 创建RedisTemplate<String, Object>对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();        // 配置连接工厂        template.setConnectionFactory(factory);        // 定义Jackson2JsonRedisSerializer序列化对象
        Jackson2JsonRedisSerializer<Object> 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);
        StringRedisSerializer stringSerial = new StringRedisSerializer();        // redis key 序列化方式使用stringSerial        template.setKeySerializer(stringSerial);        // redis value 序列化方式使用jackson        template.setValueSerializer(jacksonSeial);        // redis hash key 序列化方式使用stringSerial        template.setHashKeySerializer(stringSerial);        // redis hash value 序列化方式使用jackson        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();        return template;
    }

复制代码

  所以可以这样使用

复制代码

@Autowired
private RedisTemplate<String, Object> template;
public void test002() {
   ValueOperations<String, Object> redisString = template.opsForValue();
   // SET key value: 设置指定 key 的值
   redisString.set("strKey1", "hello spring boot redis");
   // GET key: 获取指定 key 的值
   String value = (String) redisString.get("strKey1");
   System.out.println(value);

   redisString.set("strKey2", new User("ID10086", "theName", 11));
   User user = (User) redisString.get("strKey2");
   System.out.println(user);
}  

复制代码

  

  2.3 配置Redis operations 的Bean

  RedisTemplate<K,V>类以下方法,返回值分别对应操作Redis的String、List、Set、Hash等,可以将这些operations 注入到Spring中,方便使用

  

复制代码

  /**
     * redis string     */
    @Bean    public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {        return redisTemplate.opsForValue();
    }    /**
     * redis hash     */
    @Bean    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {        return redisTemplate.opsForHash();
    }    /**
     * redis list     */
    @Bean    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {        return redisTemplate.opsForList();
    }    /**
     * redis set     */
    @Bean    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {        return redisTemplate.opsForSet();
    }    /**
     * redis zset     */
    @Bean    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {        return redisTemplate.opsForZSet();
    }

复制代码

三、RedisTemplate类的API使用

   RedisTemplate是Spring封装的类,它的API基本上对应了Redis的命令,下面列举了一小部分的使用,更多的请查看Javadoc。

复制代码

    @Autowired    private HashOperations<String, String, Object> redisHash;// Redis Hash

    @Test    public void test003() {
        Map<String, Object> map = new HashMap<>();
        map.put("id", "10010");
        map.put("name", "redis_name");
        map.put("amount", 12.34D);
        map.put("age", 11);
        redisHash.putAll("hashKey", map);        // HGET key field 获取存储在哈希表中指定字段的值
        String name = (String) redisHash.get("hashKey", "name");
        System.out.println(name);        // HGET key field
        Double amount = (Double) redisHash.get("hashKey", "amount");
        System.out.println(amount);        // HGETALL key 获取在哈希表中指定 key 的所有字段和值
        Map<String, Object> map2 = redisHash.entries("hashKey");
        System.out.println(map2);        // HKEYS key 获取在哈希表中指定 key 的所有字段
        Set<String> keySet = redisHash.keys("hashKey");
        System.out.println(keySet);        // HVALS key 获取在哈希表中指定 key 的所有值
        List<Object> valueList = redisHash.values("hashKey");
        System.out.println(valueList);
    }

复制代码

四、使用Redis缓存数据库数据

   Redis有很多使用场景,一个demo就是缓存数据库的数据。Redis作为一个内存数据库,存取数据的速度比传统的数据库快得多。使用Redis缓存数据库数据,可以减轻系统对数据库的访问压力,及加快查询效率等好处。下面讲解如何使用 SpringBoot + Redis来缓存数据库数据(这里数据库使用MySql)。

  4.1 配置Redis作为Spring的缓存管理

  Spring支持多种缓存技术:RedisCacheManager、EhCacheCacheManager、GuavaCacheManager等,使用之前需要配置一个CacheManager的Bean。配置好之后使用三个注解来缓存数据:@Cacheable,@CachePut 和 @CacheEvict。这三个注解可以加Service层或Dao层的类名上或方法上(建议加在Service层的方法上),加上类上表示所有方法支持该注解的缓存;三注解需要指定Key,以返回值作为value操作缓存服务。所以,如果加在Dao层,当新增1行数据时,返回数字1,会将1缓存到Redis,而不是缓存新增的数据。

  RedisCacheManager的配置如下:

复制代码

   /**
     * <p>SpringBoot配置redis作为默认缓存工具</p>
     * <p>SpringBoot 2.0 以上版本的配置</p>     */
    @Bean    public CacheManager cacheManager(RedisTemplate<String, Object> template) {
        RedisCacheConfiguration defaultCacheConfiguration =
                RedisCacheConfiguration
                        .defaultCacheConfig()                        // 设置key为String                        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getStringSerializer()))                        // 设置value 为自动转Json的Object                        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getValueSerializer()))                        // 不缓存null                        .disableCachingNullValues()                        // 缓存数据保存1小时
                        .entryTtl(Duration.ofHours(1));
        RedisCacheManager redisCacheManager =
                RedisCacheManagerBuilder                        // Redis 连接工厂                        .fromConnectionFactory(template.getConnectionFactory())                        // 缓存配置                        .cacheDefaults(defaultCacheConfiguration)                        // 配置同步修改或删除 put/evict                        .transactionAware()
                        .build();        return redisCacheManager;
    }

复制代码

  4.2 @Cacheabl、@CachePut、@CacheEvict的使用

复制代码

= "user" = "user", key = "#id"="'list'" List<User>= "#id", condition = "#number ge 20") 
     User selectUserByIdWithCondition(String id, = "#id", unless = "#number lt 20") 
     User selectUserByIdWithUnless(String id, = "#user.id"= "#user.id", condition = "#user.age ge 20"= "#user.id"= "#id" = "#id", allEntries =

复制代码

五、项目地址

  项目github地址,里面的测试类均有对上面涉及的内容进行测试。喜欢的帮忙点个Star

  https://github.com/caizhaokai/spring-boot-demo

 


  • 2019-12-04 10:46:26

    nuxt.js项目中全局捕获异常并生成错误日志全过程

     需求:客户在使用过程中页面报错时,可以生成错误记录传回服务器,以便改进。   步骤:     一.全局捕获异常,     二.发送到服务端,     三.生成错误日志。   一.全局捕获异常 如图,vue提供了errorHandle这个方法来处理全局异常,更多详细内容参见官网。

  • 2019-12-04 10:47:59

    nuxt.js项目中全局捕获异常并生成错误日志全过程

     需求:客户在使用过程中页面报错时,可以生成错误记录传回服务器,以便改进。   步骤:     一.全局捕获异常,     二.发送到服务端,     三.生成错误日志。   一.全局捕获异常 如图,vue提供了errorHandle这个方法来处理全局异常,更多详细内容参见官网。

  • 2019-12-04 10:48:18

    vue 项目资源文件 static 和 assets 不说区别直接使用?

    assets中资源会webpack构建压缩到你代码中,而static文件直接引用。 static 中长存放类包、插件等第三方的文件,assets里放属资源文件比如自己资源图片、css文件、js文件。 引入资源的方式static文件夹可以使用~/static/方式引入, assets文件夹可以使用 ~@/assets 方式引入

  • 2019-12-05 17:01:36

    Vue 结合 Axios 接口超时统一处理

    当网路慢的时候。又或者公司服务器不在内地的时候,接口数据请求不回来超时报错的情况相信大家肯定遇到过的,这里我把我公司项目请求超时的处理方法分享下,希望看过后有帮助。

  • 2019-12-05 17:13:40

    JS模板工具lodash.template的简单用法

    lodash是从underscore分支的一个项目,之前我写了一篇JS模板工具underscore.template的简单用法,lodash跟underscore很相似,这也简单介绍一下lodash的template方法。 先把underscore的文章中用过的代码贴过来,把underscore的js文件换成lodash的js,其他一字不改,然后我们试试:

  • 2019-12-06 10:47:29

    date-fns日期工具的使用方法详解

    isToday() 判断传入日期是否为今天 isYesterday() 判断传入日期是否为昨天 isTomorrow() 判断传入日期是否为 format() 日期格式化 addDays() 获得当前日期之后的日期 addHours() 获得当前时间n小时之后的时间点 addMinutes() 获得当前时间n分钟之后的时间 addMonths() 获得当前月之后n个月的月份 subDays() 获得当前时间之前n天的时间 subHours() 获得当前时间之前n小时的时间 subMinutes() 获得当前时间之前n分钟的时间 subMonths() 获得当前时间之前n个月的时间 differenceInYears() 获得两个时间相差的年份 differenceInWeeks() 获得两个时间相差的周数 differenceInDays() 获得两个时间相差的天数 differenceInHours() 获得两个时间相差的小时数 differenceInMinutes() 获得两个时间相差的分钟数

  • 2019-12-06 10:49:39

    npm 查看源 换源

    npm,cnpm,查看源,切换源,npm config set registry https://registry.npmjs.org