SpringBoot 1.x之使用Redis

在项目的pom.xml中引入以下依赖:

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

配置:

#redis主机
spring.redis.host=192.168.3.18

查看RedisAutoConfiguration源码:

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

    @Bean
    @ConditionalOnMissingBean(
        name = {"redisTemplate"}
    )
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Object> 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;
    }
}

可以看出为我们提供了RedisTemplateStringRedisTemplate两个模板工具,用于简化对redis的操作。

RedisTemplate用于key-value的对象操作,而StringRedisTemplate偏向于字符串的操作

测试:
这里就挑重点测试,其实这些模板的使用与命令行的命令是差不多的,类比就行。

一般将数据保存redis中,是以字符串的形式,即将其转化为json数据。

  1. 自己将对象转成json数据,再以String-String的形式存入redis
  2. 自定义RedisTemplate中的Serializer

这里不做设置,直接将其序列化存入redis中,注意:被序列化的对象需要实现Serializable接口

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootCacheApplicationTests {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testRedisTemplate(){

        Employee employee = employeeMapper.selectEmployeeById(1);

        redisTemplate.opsForHash().put("employee", employee.getId(), employee);
    }
}

结果:
这里写图片描述
原因:
RedisTemplate中,默认的序列化器是JdkSerializationRedisSerializer

if (this.defaultSerializer == null) {
    this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
}

而redis中的数据就是使用这个序列化器后的结果。

自定义模板组件以及序列化器:

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<Object, Employee> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Employee> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer<Employee> employeeJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);

        template.setDefaultSerializer(employeeJackson2JsonRedisSerializer);

        return template;
    }

}

我们可以看到RedisSerializer的实现类:
这里写图片描述
选择Jackson2JsonRedisSerializer将其设置为默认的序列化器即可。

结果:
这里写图片描述

接下来又有问题了,如果我们想存储的是别的表,而不是Employee呢?

我们可以通过自定义配置类加入多个自定义Template组件,分别由各自的CacheManager管理,使用的时候指定CacheManager就可以了。

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<Object, Employee> employeeRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Employee> ser = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
        template.setDefaultSerializer(ser);
        return template;
    }
    @Bean
    public RedisTemplate<Object, Department> departmentRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Department> template = new RedisTemplate<Object, Department>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Department> ser = new Jackson2JsonRedisSerializer<Department>(Department.class);
        template.setDefaultSerializer(ser);
        return template;
    }

    // 默认的CacheManger由RedisCacheConfiguration配置,其配置可参考RedisCacheConfiguration
    @Primary  // 作为默认的缓存管理器
    @Bean
    public RedisCacheManager employeeCacheManager(RedisTemplate<Object, Employee> employeeRedisTemplate){
        RedisCacheManager cacheManager = new RedisCacheManager(employeeRedisTemplate);

        //使用前缀,默认会将CacheName作为key的前缀
        cacheManager.setUsePrefix(true);

        return cacheManager;
    }

    @Bean
    public RedisCacheManager departmentCacheManager(RedisTemplate<Object, Department> departmentRedisTemplate){
        RedisCacheManager cacheManager = new RedisCacheManager(departmentRedisTemplate);
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }
}

使用:

@CacheConfig(cacheNames="employee", cacheManager="employeeCacheManager") // 抽取缓存的公共配置
@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    EmployeeMapper employeeMapper;

    @Override
    @Cacheable()
    public Employee getEmployeeById(Integer id){
        Employee employee = employeeMapper.getEmployeeById(id);
        return employee;
    }
}
@Service
public class DepartmentServiceimpl implements DepartmentService {

    @Autowired
    DepartmentMapper departmentMapper;

    @Autowired
    @Qualifier("departmentCacheManager")
    RedisCacheManager departmentCacheManager;

//  1、使用注解缓存
//  @Override
//  @Cacheable(cacheNames = "department", cacheManager = "departmentCacheManager")  // 指定cacheManager,获取相应的template
//  public Department getDepartmentById(Integer id){
//      Department department = departmentMapper.getDepartmentById(id);
//      return department;
//  }

//  2、使用编码方式缓存
    // 使用缓存管理器得到缓存,进行api调用
    @Override
    public Department getDepartmentById(Integer id){
        Department department = departmentMapper.getDepartmentById(id);

        // 获取Cache
        Cache departmentCache = departmentCacheManager.getCache("department");
        departmentCache.put("department:"+department.getId(), department);

        return department;
    }
}

猜你喜欢

转载自blog.csdn.net/Code_shadow/article/details/81273579
今日推荐