springboot 2.0 + Redis

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件

1、使用docker安装redis

docker pull redis // 拉取镜像

docker ps // 列出所有的容器

docker run -d -p 6379:6379 --name myredis redis:latest // 使用docker镜像redis:latest以后台模式启动一个容器,并将容器命名为myredis,容器的 6379 端口映射到主机的 6379 端口

docker rmi <Image-Id> // 使用rmi 删除容器时提示错误
Error response from daemon: conflict: unable to delete <Image-ID> (must be forced) - image is being used by stopped container xxxxxxxxxxx
// 可强制删除
docker rmi -f <image_id>  

2、pom.xml 注入redis依赖

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

3、测试Redis

@RunWith(SpringRunner.class)
@SpringBootTest
public class MySpringBootRedisApplicationTests {
    @Autowired
    EmployeeMapper employeeMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;  //操作k-v都是字符串的

    @Autowired
    RedisTemplate redisTemplate;  //k-v都是对象的

    /**
     * Redis常见的五大数据类型
     *  String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合)
     *  stringRedisTemplate.opsForValue()[String(字符串)]
     *  stringRedisTemplate.opsForList()[List(列表)]
     *  stringRedisTemplate.opsForSet()[Set(集合)]
     *  stringRedisTemplate.opsForHash()[Hash(散列)]
     *  stringRedisTemplate.opsForZSet()[ZSet(有序集合)]
     */
    @Test
    public void test01(){
        //给redis中保存数据
        //stringRedisTemplate.opsForValue().append("msg","hello");
        String msg = stringRedisTemplate.opsForValue().get("msg"); // 保存字符串
        System.out.println(msg);

        stringRedisTemplate.opsForList().leftPush("mylist","1"); // 保存列表
        stringRedisTemplate.opsForList().leftPush("mylist","2");
    }
   //测试保存对象
    @Test
    public void test02(){
        Employee empById = employeeMapper.getEmpById(1);
        //如果保存对象,默认使用jdk序列化机制,序列化后的数据保存到redis中
        redisTemplate.opsForValue().set("emp-01",empById); // Employee bean实现Serializable
    }
}

4、RedisConfig

@Configuration
public class MyRedisConfig {
    // 改变默认的序列化规则
    @Bean
    public RedisTemplate<Object, Employee> empRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Employee> ser = new Jackson2JsonRedisSerializer<Employee>(Employee.class); // Jackson2JsonRedisSerializer redis的序列化器
        template.setDefaultSerializer(ser); // 切换到redis序列化器
        return template;
    }
}

测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class MySpringBootRedisApplicationTests {
    @Autowired
    EmployeeMapper employeeMapper;

    @Autowired
    RedisTemplate<Object, Employee> empRedisTemplate;

   //测试保存对象
    @Test
    public void test02(){
        Employee empById = employeeMapper.getEmpById(1);
        //1、将数据以json的方式保存
        //(1)自己将对象转为json
        //(2)redisTemplate默认的序列化规则;可以转为json
        empRedisTemplate.opsForValue().set("emp-01",empById);
    }
}

5、CacheManager

@Configuration
public class MyRedisConfig {
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        //重写objectMapper
        MyObjectMapper objectMapper = new MyObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        //设置序列化器
        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer);
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
        return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
    }

    public class MyObjectMapper extends ObjectMapper {
        private static final long serialVersionUID = 1L;

        public MyObjectMapper() {
            super();
            // 去掉各种@JsonSerialize注解的解析
            this.configure(MapperFeature.USE_ANNOTATIONS, false);
            // 只针对非空的值进行序列化
            this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            // 对于找不到匹配属性的时候忽略报错
            this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            // 不包含任何属性的bean也不报错
            this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        }
    }
}
public class Department  {
    
    private Integer id;
    private String departmentName;
    
    public Department() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Department(Integer id, String departmentName) {
        super();
        this.id = id;
        this.departmentName = departmentName;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getDepartmentName() {
        return departmentName;
    }
    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }
    @Override
    public String toString() {
        return "Department [id=" + id + ", departmentName=" + departmentName + "]";
    }
}
@Mapper
public interface DepartmentMapper {
    @Select("SELECT * FROM department WHERE id = #{id}")
    Department getDeptById(Integer id);
}
@RestController
public class DeptController {

    @Autowired
    DeptService deptService;

    @GetMapping("/dept/{id}")
    public Department getDept(@PathVariable("id") Integer id){
        return deptService.getDeptById(id);
    }
}
// 缓存:缓存中存在从缓存返回,缓存中没有查DB返回并更新缓存
// 使用缓存,方式一,使用注解
@Service
public class DeptService {
    @Autowired
    DepartmentMapper departmentMapper;
    // 使用缓存管理器得到缓存,进行api调用
    @Cacheable(cacheNames = {"dept"},key = "#id")
    public Department getDeptById(Integer id) {
        Department department = departmentMapper.getDeptById(id);
        return department;
    }
}

// 使用缓存,方式二,编码
@Service
public class DeptService {
    @Autowired
    DepartmentMapper departmentMapper;
    @Autowired
    CacheManager cacheManager;
    public Department getDeptById(Integer id) {
        //获取某个缓存
        Cache dept = cacheManager.getCache("dept");
        if (dept != null) {
            Department department1 = dept.get(id, Department.class);
            if (department1 != null) {
                return department1;
            }
        }
        Department department = departmentMapper.getDeptById(id);
        dept.put(id, department);
        return department;
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java-内部类

    如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象(在静态方法内部创建某个内部类的对象),那么必须像在main()方法中那样,具体地指明这个对象的类型...

    桑鱼
  • Java设计模式:(1)设计模式七大设计原则-依赖倒转原则

    1)依赖倒转原则基于这样的设计理念:相对于细节的多变形,抽象的东西要稳定的多,以抽象为基础搭建的架构比以细节为基础的架构要稳定的多

    桑鱼
  • Spring - AOP(10)

    使用动态代理解决上述问题 代理设计模式的原理:使用一个代理将对象包装起来,然后用该代理对象取代原始对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及...

    桑鱼
  • androidannotions开发框架在Eclipse中的配置

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

    泥豆芽儿 MT
  • springClound --- 中级篇(1)

    本系列笔记涉及到的代码在GitHub上,地址:https://github.com/zsllsz/cloud

    贪挽懒月
  • 一波神操作,SQL效率提升10000000倍!

    发现没有用到索引,type全是ALL,那么首先想到的就是建立一个索引,建立索引的字段当然是在where条件的字段。

    挨踢小子部落阁
  • 一次非常有意思的sql优化经历

    发现没有用到索引,type全是ALL,那么首先想到的就是建立一个索引,建立索引的字段当然是在where条件的字段。

    后端技术探索
  • SQL执行效率提升几万倍的操作详解!

    发现没有用到索引,type全是ALL,那么首先想到的就是建立一个索引,建立索引的字段当然是在where条件的字段。

    数据和云
  • 一次非常有趣的 SQL 优化经历

    发现没有用到索引,type全是ALL,那么首先想到的就是建立一个索引,建立索引的字段当然是在where条件的字段了。

    用户2769421
  • 一次非常有意思的 SQL 优化经历:从 30248.271s 到 0.001s

    发现没有用到索引,type全是ALL,那么首先想到的就是建立一个索引,建立索引的字段当然是在where条件的字段。

    芋道源码

扫码关注云+社区

领取腾讯云代金券