redis 配置以及快取(javaconfig)

seal_de發表於2017-06-11

redis 配置以及快取(javaconfig)

redis

  • 是一種資料庫,一種資料庫,一種資料庫

  • 如何快取:將想要快取的資料新增到 redis 資料庫中

  • redis:基於記憶體亦可持久化的 Key-Value 資料庫,所以速度快

maven

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.1.3</version>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>${redis.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>${spring.data.redis.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>

gradle

dependencies {
    compile("org.springframework.boot:spring-boot-starter-data-redis")
    compile("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
    compile("redis.clients:jedis:$redisVersion")
    ...
}

redis 配置

@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return (target, method, 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 CacheManager cacheManager(RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }


    @Bean
    public RedisConnectionFactory redisCF() {
        JedisConnectionFactory cf = new JedisConnectionFactory();
        cf.setPassword("$2a$10$7e3cgzcCqwapf.TmEl1vi.b4ibSRxhqRjZKmRf9fV5b5u5L/CWaIa");
        return cf;
    }

    @Bean
    public StringRedisTemplate redisTemplate(RedisConnectionFactory cf) {
        StringRedisTemplate redis = new StringRedisTemplate(cf);
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);
        redis.setValueSerializer(serializer);
        redis.afterPropertiesSet();
        return redis;
    }

    ...
}
  • @EnableCaching 啟動 spring 快取

  • keyGenerator bean 是預設生成主鍵的方式

  • cacheManager bean 是快取管理器

  • StringRedisTemplate 是 spring-data-redis 的一種模板,還有一種模板是 RedisTemplate<K, V>

手動使用 redis 做快取

public List<Provinces> findAll() {
    long provinces_redis_size = redis.opsForList().size("provinces").longValue();
    List<Provinces> redisProvinces = redis.opsForList().range("provinces", 0, provinces_redis_size);
    if(redisProvinces.size() != 0)
        return redisProvinces;

    List<Provinces> persistProvinces = repository.findAll();
    for(Provinces provinces : persistProvinces) {
        redis.opsForList().rightPush("provinces", provinces);
    }

    return persistProvinces;
}
  • 思路就是查詢的時候從 redis 中查詢,若查到了,就將資料返回;若沒查到,就從正在使用的資料庫查(比如 MySql,H2等),然後將資料放入 redis 資料庫中

使用 spring 註解快取

@Cacheable(value = "provincesCache", key = "`provinces`")
public List<Provinces> findAllWithSpringCache() {
    return repository.findAll();
}
@Cacheable(value = "citiesCache", key = "#provinceId")
public List<Cities> findByProvinceId(String provinceId) {
    return repository.findByProvinceId(provinceId);
}

測試

  • 測試快取省份 provinces

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class ProvincesServiceTest {
    @Autowired
    private ProvincesService provincesService;

    @Autowired
    private RedisTemplate<String, Provinces> redis;

    @Autowired
    private StringRedisTemplate stringRedis;

    @After
    public void cleanUp() {
        redis.delete("provinces");
        stringRedis.delete("provinces");
        stringRedis.delete("provincesCache~keys");
    }

    @Test
    public void findAll() {
        List<Provinces> list = provincesService.findAll();
        Assert.assertEquals(list.size(), 34);
    }

    @Test
    public void findAllWithSpringCache() {
        List<Provinces> list = provincesService.findAllWithSpringCache();
        Assert.assertEquals(list.size(), 34);
    }
}
  • 測試快取市區 cities

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class CitiesServiceTest {
    @Autowired
    private CitiesService citiesService;

    @Autowired
    private StringRedisTemplate stringRedis;

    @After
    public void cleanUp() {
        stringRedis.delete("440000");
    }

    @Test
    public void findByProvinceId() {
        List<Cities> list = citiesService.findByProvinceId("440000");
        Assert.assertEquals(list.size(), 21);
    }
}

原始碼地址

相關文章