Springboot核心技术SpringBoot精选SpringBoot之路

SpringBoot与redis

2019-09-29  本文已影响0人  华盛顿可乐

SpringBoot与redis

核心步骤

  1. 使用前准备

    • 打开redis

    • 配置redis(spring.redis.host=127.0.0.1)

      如果是在虚拟机中使用:

      docker pull redis

      docker run -d -p 6379:6379 --name myredis redis(镜像名)

    • 创建springboot的时候选择web,mysql,mybatis,redis模块(默认使用RedisCacheConfiguration)

    • 导入数据库文件创建出department和employee表

    • 创建javaBean封装数据

    • 整合Mybatis操作数据库(扫描com.atguigu.cache.mapper和配置数据源)

  2. 快速使用

    package com.atguigu.cache.springboot2;
    import com.atguigu.cache.bean.Employee;
    import com.atguigu.cache.mapper.EmployeeMapper;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.test.context.junit4.SpringRunner;
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class Springboot2cacheApplicationTests {
        @Autowired
        EmployeeMapper employeeMapper;
        //导入了redis的start就可以将redisTemplate和stringRedisTemplate自动注入
        @Autowired
        RedisTemplate redisTemplate自动注入; //操作k-v都是对象
        @Autowired
        StringRedisTemplate stringRedisTemplate;  //操作k-v都是字符串的,因为这种类型比较多所以redis封装了一个
        @Test
        public void contextLoads() {
            Employee empById = employeeMapper.getEmpById(1);
            //默认如果保存对象,使用jdk序列化机制,序列化后的数据保存到redis中,JdkSerializationRedisSerializer是默认序列化方式
            //redisTemplate.opsForValue().set("emp-01",empById);
         //1、将数据以json的方式保存
          //(1)自己将对象转为json
          //(2)redisTemplate默认的序列化规则;改变默认的序列化规则;自己写一个redisTemplate
            redisTemplate.opsForValue().set("emp-01",empById);
        }
    }
    
  3. 序列化方式的研究

    1. JdkSerializationRedisSerializer是默认序列化方式,是最简单的也是最安全的,只要实现了Serializer接口,实体类型,集合,Map等都能序列化与反序列化,但缺陷是序列化数据很多,会对redis造成更大压力,且可读性和跨平台基本无法实现
    2. Jackson2JsonRedisSerializer用的是json的序列化方式,能解决JdkSerializationRedisSerializer带来的缺陷,但复杂类型(集合,泛型,实体包装类)反序列化时会报错,且Jackson2JsonRedisSerializer需要指明序列化的类Class,这代表一个实体类就有一个RedisCacheManager,代码冗余
    3. 最后查看源码,发现RedisSerializer(Jackson2JsonRedisSerializer也实现此接口)的实现类中有一个GenericJackson2JsonRedisSerializer,此类不用需要指明序列化的类,写一个RedisCacheManager即可,代码更精简,复杂类型(集合,泛型)反序列化时不会报错,查看redis数据可以发现实现原理是在json数据中放一个@class属性,指定了类的全路径包名,方便反序列化,所以在内存占用上高一点点,但是反序列化性能自测要比Jackson2JsonRedisSerializer高(有兴趣的老哥也可以自己试试性能差别),空间换时间,当然也因为此特性,项目一部分的结构(实体全类名)会json数据中体现。
      注:经过反复考虑,目前使用了GenericJackson2JsonRedisSerializer作为序列化方式
  4. 改变序列化方式

    1. 使用Jackson2JsonRedisSerializer序列化
package com.atguigu.cache.config;
import com.atguigu.cache.bean.Department;
import com.atguigu.cache.bean.Employee;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.net.UnknownHostException;
import java.time.Duration;
@Configuration
public class MyRedisConfig {
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration cacheConfiguration =
                RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofDays(1))
                        .disableCachingNullValues()
                    .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer
                                (new Jackson2JsonRedisSerializer<Employee>(Employee.class)));
        return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();
    }
}
  1. 使用GenericJackson2JsonRedisSerializer序列化
//springboot检查到了缓存管理器,就不会使用默认的缓存管理器了,会使用我们在下面创建的缓存管理器
//有多个CacheManager需要用注解@Primary  //将某个缓存管理器作为默认的
@Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration cacheConfiguration =
                RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofDays(1))
                        .disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new
                                GenericJackson2JsonRedisSerializer()));
        return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();
    }

测试

//可以在注解中指定cacheManager,cacheManager = "cacheManager",这个cacheManager是上面的方法名
@Cacheable(cacheNames = "dept")
    public Department getDeptById(Integer id){
        System.out.println("查询部门"+id);
        Department department = departmentMapper.getDeptById(id);
        return department;
    }

三、整合redis作为缓存

 @MapperScan("com.atguigu.cache.mapper")
  @SpringBootApplication
  @EnableCaching
  public class Springboot2Application {
  public static void main(String[] args) {
      SpringApplication.run(Springboot2Application.class, args);
  }
}
上一篇 下一篇

猜你喜欢

热点阅读