(七)Spring Boot 集成 Redis 缓存 —— 《一步一步学 Spring Boot 2》读书笔记

本文纯个人读书笔记,书籍《一步一步学 Spring Boot 2》
如果喜欢,可直接购买书籍。如有侵权,请联系删除

一、Redis

Redis 是一个基于内存的单线程高性能 key-value 型数据库,读写性能优异 Redis 支持丰富的数据类型,包括 string(字符串) 、 list(链表 )、set(集合)、zset ( sorted set 有序集合)和 hash (哈希类型〉。

1.安装

Redis 项目本身是不支持 Window,但是 Microsoft 开放技术小组开发和维护 Win64 版本的。github 地址。

我们下载 zip 包。在这里插入图片描述
直接解压出来就可以。

2.运行服务端

运行非常简单,双击 redis-server.exe 直接运行。
在这里插入图片描述
运行结果:
在这里插入图片描述

3.运行客户端

双击 redis-cli.exe 运行 Redis 客户端。

在这里插入图片描述
运行界面:
在这里插入图片描述

二、Redis 操作

上面提到 Redis 支持丰富的数据类型,包括 string(字符串) 、 list(链表 )、set(集合)、zset ( sorted set 有序集合)和 hash (哈希类型〉,这边对这些数据类型进行增删改查。

1.字符串

添加

### 增加一个值, key 为 name,value 为 zx 
set name 'zx'

在这里插入图片描述
查询

### 查询 key 为 name 的值
get name

在这里插入图片描述
更新

### 更新 key 为 name 的值,value 为 zxy
set name 'zxy'

在这里插入图片描述
删除

###删除 name 的值
del name

在这里插入图片描述
查询是否存在

###查询是否存在 name,0 代表不存在
exists name

在这里插入图片描述

2.List

添加 List

###添加 key 为users,value 为 ’zx’,’zxy’ 的 list 集合
lpush users 'zx' 'zxy'

在这里插入图片描述
查询

###查询 key 为 users 的集合
lrange users 0 -1

在这里插入图片描述
后面跟的数字表示要查询的集合范围,0, -1 表示全部。

尾部添加

###往 users 尾部添加 'z' 元素
rpush users 'z'

在这里插入图片描述
头部添加

###往 users 头部添加 'a' 元素
lpush users 'a'

在这里插入图片描述

更新

###更新 index 为 0 的值为 'aa'
lset users 0 'aa'

在这里插入图片描述
删除

###删除 index 为 0 的值
lrem users 0 'aa'

在这里插入图片描述

3.Set

添加 Set

###添加 key 为 userSet, value 为 'zx'  'zxy' 的集合
sadd userSet  'zx'  'zxy' 

在这里插入图片描述
查询

###查询 key 为userSet 集合
smembers userSet

在这里插入图片描述
添加

###添加 ‘z’ 元素,set 集合是没有顺序的,所以无法判断添加到那个位置
sadd userSet 'z'

在这里插入图片描述
重复添加 ‘z’ 元素,不会成功,也不会报错。
在这里插入图片描述
删除


###删除 value 为 ‘z’,返回 1 表示删除成功,0 表示失败
srem userSet 'z'

在这里插入图片描述

4.Hash

添加 Hash

###创建 hash, key 为 userHash, 添加字段为 'user1',值为 ‘zx’。
hset userHash "user1"  "zx"

在这里插入图片描述
继续添加字段为 ‘user2’,值为 ‘zxy’。
在这里插入图片描述
查询长度

###查询 userHash 字段长度
hlen userHash

在这里插入图片描述
查询所有字段

###查询 userHash 所有字段
hkeys userHash

在这里插入图片描述
查询所有值

###查询 userHash 所有值
hvals userHash

在这里插入图片描述
查询特定字段值

###查询字段 'user1' 的值
hget userHash "user1"

在这里插入图片描述
查询所有字段和值

###获取 key 为 userHash 所有的字段和值
hgetall userHash

在这里插入图片描述
更新

###更新字段 user2 的值为 ‘z’
hset userHash "user2" "z"

在这里插入图片描述
删除

###删除字段 user2 和值
hdel userHash user2

在这里插入图片描述

5.zSet

zSet 主要是有个分数的概念,用来排序。

添加

### userZSet 集合添加 ‘zx’ 元素,分数为 1
zadd userZSet  1 "zx"

在这里插入图片描述
继续添加 ‘zxy’ 元素,分数为 2。
在这里插入图片描述

查询(由小到大排序)

###按照分数由小到大查询 userZSet 集合元素
zrange userZSet 0 -1

在这里插入图片描述
查询(由大到小排序)

###按照分数由大到小查询 userZSet 集合元素
zrevrange userZSet 0 -1

在这里插入图片描述
查询分数

###查询元素 ‘zx’ 的分数
zscore userZSet "zx"

在这里插入图片描述

6.其他

清除数据库

###清除数据库
flushdb

OK

三、Spring Boot 整合 Redis

Spring Boot 提供了强大的基于注解的缓存支持,可以通过注解配置方式,低侵入的给原有 Spring 应用增加缓存功能,提高数据访问性能。

Spring Boot为 我们配置了多个 CacheManager 的实现,我们可以根据具体的项目要求使用相应的缓存技术。
在这里插入图片描述
从上图可以发现,Spring Boot 支持许多类型的缓存,比如:EhCache、JCache、Redis 等。默认情况下,Spring Boot 使用 SimpleCacheConfiguration。

1.引入依赖

在 pom 文件中添加 Redis 依赖。

pom.xml:

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

2.添加配置

在 application.properties 中添加 Redis 的配置。

application.properties:

### redis缓存配置
### 默认redis数据库为db0
spring.redis.database=0
### 服务器地址,默认为localhost
spring.redis.host=localhost
### 链接端口,默认为6379
spring.redis.port=6379
### redis密码默认为空
spring.redis.password=

四、Redis 测试

在测试类 DemoApplicationTests.java 中添加测试代码,并进行测试。

DemoApplicationTests:

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void testRedis(){
        //增加 key:name,value:zx
        stringRedisTemplate.opsForValue().set("name","zx");
        String name = (String)stringRedisTemplate.opsForValue().get("name");
        System.out.println(name);
        //删除
        stringRedisTemplate.delete("name");
        //更新
        stringRedisTemplate.opsForValue().set("name","zxy");
        //查询
        name = stringRedisTemplate.opsForValue().get("name");

        System.out.println(name);
    }

RedisTemplate 和 StringRedisTemplate 都是 Spring Data Redis 为我们提供的两个模板类用来对数据进行操作,其中 StringRedisTemplate 只针对键值都是字符串的数据进行操作。在应用启动的时候,Spring 会为我们初始化这两个模板类,通过 @Resource 注解注入即可使用。

RedisTemplate 和 StringRedisTemplate 除了提供 opsForValue 方法用来操作简单属性数据之外,还提供了以下其它主要数据访问方法:

1)opsForList:操作含有list的数据。
2)opsForSet:操作含有set的数据。
3)opsForZSet:操作含有ZSet(有序set)的数据。
4)opsForHash:操作含有hash的数据。

当我们的数据存放到 Redis 的时候,键(key)和值(value)都是通过 Spring 提供的 Serializer 序列化到数据库的。RedisTemplate 默认使用 JdkSerializationRedisSerializer,而 StringRedisTemplate 默认使用 StringRedisSerializer。

运行

右击 testRedis 方法,并运行,查看控制台输出。
在这里插入图片描述
也可以安装 RedisClient 进行查看。
在这里插入图片描述

四、Redis 的使用

1.使用

在实际项目中,用户数据的变动很小,但又经常要查询的,这样的数据适合存放到缓存中。这样在应用需要获取用户数据时,可以直接到 Redis 缓存中获取,不用到数据库中获取数据库连接查询数据,提高数据的访问速度。

在上一篇已经简单的介绍了监听器,我们可以在上下文初始化的方法中,加载所有的用户数据,放到 Redis 中。

UserListener.java:

@WebListener
public class UserListener implements ServletContextListener {


    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private UserService userService;

    private static final String ALL_USER = "ALL_USER_LIST";
    @Override
    public void contextInitialized(ServletContextEvent sce) {

        System.out.println("111 zx UserListener contextInitialized");

        //查询数据库所有的用户
        List<User> userList =  userService.findAll();
        //清除缓存中的用户数据
        redisTemplate.delete(ALL_USER);
        //将数据存放到 redis 缓存中
        redisTemplate.opsForList().leftPushAll(ALL_USER, userList);
        //真实项目中需要注释掉,查询所有的用户数据
        List<User> queryUserList = redisTemplate.opsForList().range(ALL_USER, 0, -1);
        System.out.println("缓存中目前的用户数有:" + queryUserList.size() + " 人");
        System.out.println("ServletContext上下文初始化");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

        System.out.println("111 zx UserListener contextDestroyed");
    }

}

由于 RedisTemplate 默认使用 JdkSerializationRedisSerializer,所以需要对存储的 User 类进行实现 Serializer 接口。

User.java:

@Entity
@Table(name = "user")
public class User implements Serializable{
    //省略代码
}

2.测试

运行应用,进行查看日志。
在这里插入图片描述
说明 Redis 存储 User 缓存成功,也可以通过 RedisCliemt 进行数据查看。

3.更新缓存

User 使用了 Redis 后,需要修改一系列的数据库操作方法来支持更新缓存。比如 findById、save、delete 等方法。

findById: 先从 Redis 缓存中查找,如果 Redis 缓存中查询不到数据,需要到数据库查询。数据库查找数据成功后,需要把数据更新到缓存中。

save: 添加数据到数据库的同时,需要添加到 Redis 缓存中。

delete: 删除数据库中数据的同时,需要把 Redis 缓存中对应的数据也删除掉。

UserServiceImpl :

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Resource
    private UserRepository userRepository;

    @Resource
    private RedisTemplate redisTemplate;

    private static final String ALL_USER = "ALL_USER_LIST";

    @Override
    public User findByid(String id) {

        //step.1  查询 Redis 缓存中的所有数据
        List<User> userList = redisTemplate.opsForList().range(ALL_USER, 0, -1);
        if(userList != null && userList.size() > 0){
            for(User user : userList){
                if (user.getId().equals(id)){
                    return user;
                }
            }
        }

        //step.2  查询数据库中的数据
        User user = userRepository.findById(id).get();
        if(user != null){
            //step.3 将数据插入到 Redis 缓存中
            redisTemplate.opsForList().leftPush(ALL_USER, user);
        }

        return user;
    }
	......
}

这边不是主要讲解 Redis 的使用,就没有对所有方法进行修改。

在 DemoApplicationTests.java 中编写测试代码进行测试。

DemoApplicationTests.java:

    @Test
    public void testFindById(){
        Long redisUserSize = 0L;
        //查询 id = 1 的数据,不存在于 redis 缓存中,存在于数据库中,所以会把数据库查询的数据更新到缓存中
        User user = userService.findById("1");
        redisUserSize = redisTemplate.opsForList().size("ALL_USER_LIST");
        System.out.println("目前缓存中的用户数量为:" + redisUserSize);
        System.out.println("--->>> id: " + user.getId() + " name:" + user.getName());

        //查询 id = 2 的数据,不存在于 redis 缓存中,存在于数据库中,所以会把数据库查询的数据更新到缓存中
        User user1 = userService.findById("2");
        redisUserSize = redisTemplate.opsForList().size("ALL_USER_LIST");
        System.out.println("目前缓存中的用户数量为:" + redisUserSize);
        System.out.println("--->>> id: " + user1.getId() + " name:" + user1.getName());

        //再次查询 id = 2 的数据,该数据存在于 redis 缓存中
        User user2 = userService.findById("2");
        redisUserSize = redisTemplate.opsForList().size("ALL_USER_LIST");
        System.out.println("目前缓存中的用户数量为:" + redisUserSize);
        System.out.println("--->>> id: " + user2.getId() + " name:" + user2.getName());

    }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值