(一)Spring-Boot 整合 Redis,整合SpringCache

1.引入依赖包


    org.springframework.boot
    spring-boot-starter-data-redis

Spring Boot 提供了对 Redis 集成的组件包:spring-boot-starter-data-redis,spring-boot-starter-data-redis依赖于spring-data-redis 和 lettuce 。

2.添加配置文件

spring.redis.host=192.168.1.1
spring.redis.database=15
spring.redis.port=6379
spring.redis.password=******

注入的是 RedisProperties
前缀是spring.redis

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties{
      // 部分代码

    /**
     * Database index used by the connection factory.
     */
    private int database = 0;

    /**
     * Connection URL. Overrides host, port, and password. User is ignored. Example:
     * redis://user:[email protected]:6379
     */
    private String url;

    /**
     * Redis server host.
     */
    private String host = "localhost";

    /**
     * Login password of the redis server.
     */
    private String password;

    /**
     * Redis server port.
     */
    private int port = 6379;
}

3.使用RedisTemplate操作redis库

spring-boot-redis实现了两种模板类。
RedisTemplate 和 StringRedisTemplate 。

经常使用的redis操作一般都是操作String类型的,没有特殊需要可以先使用》
StringRedisTemplate,当然RedisTemplate 是都支持的。

为了方便操作缓存对象,可以自己实现不同类型的RedisTemplate。
文章后面的RedisConfig也实现了RedisTemplate ,方便我们操作可序列化对象

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

}

操作redis库

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisTemplate redisCacheTemplate;

    @Test
    void testRedis1() {
        stringRedisTemplate.opsForValue().set("key", "value");
        String keu = stringRedisTemplate.opsForValue().get("keu");
    }

    @Test
    void testRedis2() {
        redisCacheTemplate.opsForValue().set("user" ,new User(1l ,"jim2"));
        User user = (User) redisCacheTemplate.opsForValue().get("user");
        System.out.println(user.toString());
    }

模板类提供了多种操作redis库的方法,各种神奇的用法,等用到再去探索吧

当然为了更方便的使用,我们可以再把redis操作封装一层

@Component
public class RedisUtils {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public String get(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    public void set(String key ,String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }
}

4.使用spring-boot + redis实现缓存数据

spring-boot帮我们集成了SpringCache方便使用缓存。
缓存数据的key的规则。

@Configuration
@EnableCaching
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append("::");
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * 默认情况下的模板只能支持RedisTemplate,也就是只能存入字符串,因此支持序列化
     */
    @Bean
    public RedisTemplate redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    /**
     * 配置使用注解的时候缓存配置,默认是序列化反序列化的形式,加上此配置则为 json 形式
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 配置序列化
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        return RedisCacheManager.builder(factory).cacheDefaults(redisCacheConfiguration).build();
    }


}

当我们访问/test接口时,返回的数据就保存到了redis库中.
@Cacheable主动开启缓存

@RestController
public class TestController {

    @GetMapping("/test")
    @Cacheable(value = "testKey")
    public String getAa() {

        return "Hello";
    }

}

缓存的其他使用方式。
下面参考其他作者的例子。

 /**
     * 查询出一条数据并且添加到缓存
     *
     * @param userId
     * @return
     */
    @RequestMapping("/getUser")
    @Cacheable("userCache")
    public User getUser(@RequestParam(required = true) String userId) {
        System.out.println("如果没有缓存,就会调用下面方法,如果有缓存,则直接输出,不会输出此段话");
        return userDao.getUser(Integer.parseInt(userId));
    }

    /**
     * 删除一个缓存
     *
     * @param userId
     * @return
     */
    @RequestMapping(value = "/deleteUser")
    @CacheEvict("userCache")
    public String deleteUser(@RequestParam(required = true) String userId) {
        return "删除成功";
    }

    /**
     * 添加一条保存的数据到缓存,缓存的key是当前user的id
     *
     * @param user
     * @return
     */
    @RequestMapping("/saveUser")
    @CachePut(value = "userCache", key = "#result.userId +''")
    public User saveUser(User user) {
        return user;
    }


    /**
     * 返回结果userPassword中含有nocache字符串就不缓存
     *
     * @param userId
     * @return
     */
    @RequestMapping("/getUser2")
    @CachePut(value = "userCache", unless = "#result.userPassword.contains('nocache')")
    public User getUser2(@RequestParam(required = true) String userId) {
        System.out.println("如果走到这里说明,说明缓存没有生效!");
        User user = new User(Integer.parseInt(userId), "name_nocache" + userId, "nocache");
        return user;
    }


    @RequestMapping("/getUser3")
    @Cacheable(value = "userCache", key = "#root.targetClass.getName() + #root.methodName + #userId")
    public User getUser3(@RequestParam(required = true) String userId) {
        System.out.println("如果第二次没有走到这里说明缓存被添加了");
        return userDao.getUser(Integer.parseInt(userId));
    }

作者:米奇罗
链接:https://juejin.im/post/5ca07a98f265da30933fc4c4
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:((一)Spring-Boot 整合 Redis,整合SpringCache)