前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springboot整合redis +cache

Springboot整合redis +cache

作者头像
smallmayi
发布2022-05-12 11:25:06
7560
发布2022-05-12 11:25:06
举报
文章被收录于专栏:small专栏small专栏

文章目录
  • redis简介

  • springboot整合redis
    • 1.依赖
    • 2.application.properties配置
    • 3.测试
    • 使用mysql数据库 测试
      • 上面我使用了*StringRedisTemplate* ,在使用数据库测试时,我使用的是*RedisTemplate*,关联和区别?
      • redistemplate 主要方法:
    • springboot cache + redis
    • 扩展
      • **使用fastjson序列化**
      • **注解方式实现过期时间自定义**
      • 参考:
redis简介

redis(Remote Dictionary Server 远程数据服务) 是一个高性能的key-value数据库。

Redis 与其他 key - value 缓存产品有以下三个特点:

Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

Redis不仅仅支持简单的key-value类型的数据,同时还提供string、hash、list、set、sorted set等数据结构的存储。

Redis支持数据的备份,即master-slave模式的数据备份。

springboot整合redis

1.依赖
代码语言:javascript
复制
 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>

其他依赖fastjson

代码语言:javascript
复制
<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.60</version>
</dependency>
2.application.properties配置
代码语言:javascript
复制
#Redis
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=192.168.4.100
# Redis服务器连接端口
spring.redis.port=6379
# Redis密码
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=5000
3.测试
代码语言:javascript
复制
@RestController
public class RedisTestCtrl {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @PostMapping("/user")
    public Object addUser(@RequestBody User user) {
        stringRedisTemplate.opsForValue().set("user", JSON.toJSONString(user));
        return "success";
    }

    @GetMapping("/user")
    public User getUser() {
        return JSON.parseObject(stringRedisTemplate.opsForValue().get("user"), User.class);
    }

    @PostMapping("/users")
    public Object addUsers(@RequestBody List<User> users) {
        stringRedisTemplate.opsForList().rightPushAll("users", users.stream().map(JSON::toJSONString).collect(Collectors.toList()));
        return "success";
    }

    @GetMapping("/users")
    public Object getUsers() {
        List<User> users = new ArrayList<>();
        while (true) {
            User user = JSON.parseObject(stringRedisTemplate.opsForList().leftPop("users"), User.class);
            if (Objects.isNull(user)) {
                break;
            }
            users.add(user);
        }
        return users;
    }
}

上面已将数据存入redis,可使用redis可视化工具进行查看

使用mysql数据库 测试

1. 添加mybatis,mysql 依赖, 配置连接 pom

代码语言:javascript
复制
<!--mybatis and mysql-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

配置

代码语言:javascript
复制
#mysql
spring.datasource.url=jdbc:mysql://192.168.4.100:3306/test
spring.datasource.username=root
spring.datasource.password=123456

2. 构建domain和dao

对象需要序列化

代码语言:javascript
复制
@Data
public class User implements Serializable {
    private String name;
    private int age;
}
代码语言:javascript
复制
@Mapper
public interface UserDao {
    @Select("select * from RedisUser")
    List<User> userList();
}

3. 测试redis 重点

检测缓存中是否有该key的缓存,没有则从数据库获取数据写入缓存

代码语言:javascript
复制
 @GetMapping("/queryUsers")
    public List<User> queryUsers() {
    	//自定义一个key,根据需求
        String key = "data";
        ValueOperations<String, List<User>> operations = redisTemplate.opsForValue();
        boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey) {
            List<User> users = operations.get(key);
            System.out.println("==========从缓存中获得数据=========");
            return users;
        } else {
            List<User> users = userDao.userList();
            System.out.println("==========从数据表中获得数据=========");
            // 写入缓存,设置过期时间
            operations.set(key, users, 5, TimeUnit.SECONDS);
            return users;
        }
    }

set()方法设置缓存过期时间,可不设置

在这里插入图片描述
在这里插入图片描述

到此就已经完成了redis的测试

上面我使用了StringRedisTemplate ,在使用数据库测试时,我使用的是RedisTemplate,关联和区别?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如图, user键是使用StringRedisTemplate data键是使用RedisTemplate 在RedisDesktop 可视化工具中看出,使用StringRedisTemplate维护的数据,键和值都是String形式,方便维护; 而使用RedisTemplate维护的数据,键和值都是转换为字节数组形式,没有可读性。 建议:字符串形式数据可以使用StringRedistemplate,对象形式数据可以使用RedisTemplate,如果使用StringRedisTemplate则需要转换成对象,如上面使用fastjson转换成user对象。

RedisTemplate和StringRedisTemplate的区别:

  1. 两者的关系是StringRedisTemplate继承RedisTemplate。
  2. 两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
  3. SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。

StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。

RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

redistemplate 主要方法:

上面测试时只使用了redisteplate的opsForValue()方法和hasKey()方法;

在这里插入图片描述
在这里插入图片描述

redistemplate 方法有很多,图上只是一部分,

在这里插入图片描述
在这里插入图片描述

redis有5种数据类型,String,list,hash,set,zset ,相应的有对应的ops方法

下面举例list类型对应的opsForLIst

代码语言:javascript
复制
@RequestMapping(value = "/redis/list")
    public void listOperation() {
        List<String> list1 = new ArrayList<String>();
        list1.add("a1");
        list1.add("a2");
        list1.add("a3");

        List<String> list2 = new ArrayList<String>();
        list2.add("b1");
        list2.add("b2");
        list2.add("b3");
        //leftpush是在list的左侧添加,即列表的头部,right是在list的左侧添加,即在列表的尾部。
        // 插入
        redisTemplate.opsForList().leftPush("listkey1",list1);
        redisTemplate.opsForList().rightPush("listkey2", list2);
        
        //获取数据后移除,Pop方法会移除缓存
        List<String> resultList1 = (List<String>) redisTemplate.opsForList().leftPop("listkey1");
        List<String> resultList2 = (List<String>) redisTemplate.opsForList().rightPop("listkey2");
        System.out.println("resultList1:" + resultList1);
        System.out.println("resultList2:" + resultList2);
    }

其他方法

代码语言:javascript
复制
//设置过期时间
redistemplate.expire(key,seconds,TimeUnit.SECONDS)
//如果只想要查看某个元素。可以使用range,他有三个参数,第一个参数是key,后面是搜索范围,
//全集合搜索可以用(key,0,-1);
redisTemplate.opsForList().range("listkey1",0,-1)

其余类型方法暂略。

springboot cache + redis

上面我们已经整合了springboot+redis ,可以使用cache进一步简化。 springboot 默认集成了cache,注解使用即可。

SpringCache包含两个顶级接口,Cache(缓存)和CacheManager(缓存管理器), 而在spring-boot-starter-data-redis中已经帮我们自动配置实现了Cache接口,使用方便

测试

代码语言:javascript
复制
 @GetMapping("/getUser")
    @Cacheable(cacheNames = "aa",key = "#p0")
    public User addUser(String id) {
        log.info("进入数据");
        User user = new User("xiaomi", 19);
        return user;
    }
在这里插入图片描述
在这里插入图片描述

redis数据库成功存入,但是存入的是字节数组。

配置转换成json

代码语言:javascript
复制
@Configuration
public class MyRedisConfig {

    public MyRedisConfig() {
    }

    /**
     * 参考RedisAutoConfiguration, 主动缓存调用的时候  转JSON
     */
    @Bean
    public RedisTemplate<Object, User> userRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {


        RedisTemplate<Object, User> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer<User> serializer = new Jackson2JsonRedisSerializer<User>(User.class);
        template.setDefaultSerializer(serializer);
        return template;
    }


    /**
     * 参考 org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration;
     * <p>
     * 被动缓存调用的时候  结果转JSON
     */
    @Bean
    public RedisCacheManager userCacheManage(RedisConnectionFactory connectionFactory) {
        
        Jackson2JsonRedisSerializer<Object> redisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        redisSerializer.setObjectMapper(objectMapper);

        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer));

        RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory).cacheDefaults(cacheConfiguration).build();

        return redisCacheManager;

    }

}

查看数据库,已成功转换。

在这里插入图片描述
在这里插入图片描述
扩展
使用fastjson序列化

springboot2.x使用redis作为缓存(使用fastjson序列化的方式,并调试反序列化异常)

注解方式实现过期时间自定义

springboot2.0整合redis自定义注解实现过期时间

git地址:https://gitee.com/yutiankong/springcache_redis

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-11-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
    • redis简介
    • springboot整合redis
      • 1.依赖
        • 2.application.properties配置
          • 3.测试
            • 使用mysql数据库 测试
              • 上面我使用了StringRedisTemplate ,在使用数据库测试时,我使用的是RedisTemplate,关联和区别?
              • redistemplate 主要方法:
            • springboot cache + redis
              • 扩展
                • 使用fastjson序列化
                • 注解方式实现过期时间自定义
            相关产品与服务
            云数据库 Redis
            腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档