Spring Boot微服务项目实战(第2版)学习笔记-第7章集成Redis缓存

本章主要介绍如何安装Redis缓存、Redis缓存5种基本数据类型的增删改查、Spring Boot中如何集成Redis缓存以及如何使用Redis缓存用户数据等内容。

1.Redis缓存介绍

1.1 Redis概述

Redis是一个基于内存的单线程高性能key-value型数据库,读写性能优异。和Memcached缓存相比,Redis支持丰富的数据类型,包括string(字符串)、list(链表)、set(集合)、zset(sorted set有序集合)和hash(哈希类型)。因此Redis在企业中被广泛使用。

1.2 Redis服务器安装

Redis项目本身是不支持Windows的,但是Microsoft开发技术小组针对Win64开发和维护了Windows端口,所以可以在网络上下载Redis的Windows版本。具体步骤如下:

  1. 打开官方网站http://redis.io/,单击Download
  1. 在弹出的页面中,找到Learn more选项,并单击进入。
  1. 在弹出的页面中选择【releases】选项。
  1. 在弹出的界面中选择Redis3.0.504这个版本,选择其他版本也可以,单击【Redis-x64-3.0.504.zip】下载Redis安装包。
  1. 解压下载的安装包【Redis-x64-3.0.504.zip】,双击【redis-server.exe】,Redis服务器就运行起来了,同时可以看到Redis启动成功的界面,如图所示。

1.3 Redis缓存测试

Redis安装成功之后,可以在安装包里找到Redis客户端程序redis-cli.exe,双击redis-cli.exe,打开Redis客户端界面。

下面就使用Redis客户端对Redis的几种数据类型做基本的增删改查操作练习。

1.3.1 字符串类型的增删改查

1.3.2 List集合的增删改查

1.3.3 Set集合的增删改查

1.3.4 Hash集合的增删改查

1.3.5 SortedSet集合的增删改查

2.Spring Boot集成Redis缓存

2.1 Spring Boot缓存支持

在Spring Boot中提供了强大的基于注解的缓存支持,可以通过注解配置的方式低侵入地给原有Spring应用增加缓存功能,提高数据访问的性能。Spring Boot为我们配置了多个CacheManager的实现,可以根据具体的项目要求使用相应的缓存技术。

从图可知,Spring Boot支持许多类型的缓存,比如EhCache、JCache、Redis等。在不添加任何额外配置的情况下,Spring Boot默认使用SimpleCacheConfiguration,考虑到Redis缓存在企业中被广泛使用,故选择用Redis缓存来进行讲解。

2.2 引入依赖

在Spring Boot中集成Redis,首先需要在pom.xml文件中引入所需的依赖,具体代码如下:

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

2.3 添加缓存配置

在pom文件引入Redis所需的依赖之后,需要在application.properties文件中添加如下的配置信息:

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

2.4 测试用例开发

在application.properties配置文件中添加完Redis配置之后,在测试类DemoApplicationTests.java中继续添加如下的代码:

@Resource
private RedisTemplate redisTemplate;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Test
public void testRedis() {
	//增key:name, value:ay
	redisTemplate.opsForValue().set("name","ay");
	String name = (String)redisTemplate.opsForvalue().get("name");
	System.out.printIn(name);
	//删除
	redisTemplate.delete("name");
	//更新
	redisTemplate.opsForvalue().set("name","al");
	//查询
	name = stringRedisTemplate.opsForValue().get("name");
	System.out.printIn(name);
}

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

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

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

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

2.5 测试

上节测试用例代码开发完成之后,运行单元测试用例,除了可以在控制台查看打印结果信息和在Redis客户端查看数据之外,还可以使用RedisClient客户端工具查看Redis缓存数据库中的数据。RedisClient客户端软件可以到网络上下载,并安装到自己的操作系统中。安装完成之后,可以看到如图所示的界面。

可以看到Redis默认有16个数据库,客户端与Redis建立连接后会自动选择0号数据库。通过该客户端可以清楚地查看Redis数据库中存放的数据情况,同时可以在客户端中对数据进行增删改查等操作,方便使用。

3.Redis缓存在Spring Boot中的使用

3.1 监听器Listener开发

在上一章,我们已经简单地开发好AyUserListener监听器类,并在上下文启动时打印信息。在本节中,我们想在上下文初始化的方法中,加载数据库中的所有用户数据,并存放到Redis缓存中。之所以要把用户数据存放到缓存中,是因为用户的数据属于变动不大的数据,适合存放到缓存中,在应用需要获取用户数据时,可以直接到Redis缓存中获取,不用到数据库中获取数据库连接查询数据,提高数据的访问速度。具体代码如下:

@WebListener
public class AyuserListener implements ServletContextListener {
	@Resource
	private RedisTemplate redisTemplate;
	@Resource
	private AyUserService ayUserService;
	private static final String ALL_USER ="ALL_USER_LIST";
	
	@override
	public void contextInitialized(ServletContextEvent servletContextEvent) {
		//查询数据库所有的用户
		List<AyUser> ayUserList = ayUserService.findAll();
		//清除缓存中的用户数据
		redisTemplate.delete(ALL_USER);
		//将数据存放到Redis缓存中
		redisTemplate.opsForList().leftPushAll(ALL _USER, ayUserList);
		//真实项目中需要注释掉,查询所有的用户数据
		List<AyUser> queryUserList = redisTemplate.opsForList().range(ALL_USER, 0,-1);
		System.out.println("缓存中目前的用户数有:"+ queryUserList.size()+"人");
		System.out. println("ServletContext上下文初始化");
	}
	@Override
	public void contextDestroyed (ServletContextEvent servletContextEvent){
		System.out.printIn("ServletContext上下文销毁");
	}
}
  • redisTemplate.opsForList().leftPushAll:查询缓存中所有的用户数据,ALL_USER键若不存在,会创建该键及与其关联的List,之后再将参数中的ayUserList从左到右依次插入。
  • redisTemplate.opsForList().range:取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素。

当我们的数据存放到Redis的时候,键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用JdkSerializationRedisSerializer,而StringRedisTemplate默认使用StringRedisSerializer。所以我们需要让用户类AyUser(/src/main/java/com.example.demo.model)实现序列化接口Serializable,具体代码如下:

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

3.2 项目启动缓存数据

开发好AyUserListener监听器类和AyUser用户类,重新启动项目,这时候数据库表ay_user中的所有数据都会加载到Redis缓存中。在contextInitialized方法中进行断点调试,出现如图所示的图片,可见代码数据已经成功地被加载到缓存中。我们也可以用RedisClient客户端软件来查看用户数据是否存放到缓存中。

3.3 更新缓存数据

项目启动加载所有用户数据到缓存之后,需要修改AyUserServiceImpl中的接口,比如findById、Save、Delete等方法。因为如果在Redis缓存中查询不到数据,那么就需要到数据库中查询,如果能够在数据库中查询到数据,除了返回数据之外,还需要把数据更新到缓存中。这样再次查询数据时,就不需要到数据库中查询数据。这里主要对方法findById进行修改,AyUserServiceImpl中具体需要修改的代码如下:

//省略代码
@Service
public class AyUserServiceImpl implements AyUserService {
	@Resource(name = "ayUserRepository")
	private AyUserRepository ayUserRepository;
	@Resource
	private RedisTemplate redisTemplate;
	private static final String ALL USER ="ALL_USER_LIST";
	@Override
	public AyUser findById(String id){
		//step.1查询 Redis缓存中的所有数据
		List<AyUser> ayUserList= redisTemplate.opsForList.range(ALL_USER,0,-1);
		if(ayUserList != null & ayUserList.size() > 0){
			for(AyUser user:ayUserList){
				if (user.getId().equals(id)){
					return user;
				}
			}
		}
		//step.2查询数据库中的数据
		AyUserayuser ayuserRepository.findById(id).get();
		if(ayUser != null){
			//step.3将数据插入到 Redis缓存中
			redisTemplate.opsForList(leftPush(ALL_USER, ayUser);
		}
		return ayuser;
		//省略代码
	}
}

对于Save、Delete等方法的修改,思路是一样的,这里就不一一重复赘述,读者可自己尝试实现。虽然引入Redis缓存用户数据可以提高访问性能,但是带来的代码复杂度也是可想而知的。所以在工作中,需要权衡性能和代码的复杂度,根据具体的业务场景加以选择,不可滥用缓存。

3.4 测试

在测试类MySpringBootApplicationTests下继续添加如下的测试方法:

@Test
public void testFindById(){
	Long redisUserSize = OL;
	//查询id=1的数据,该数据存在于Redis缓存中
	AyUser ayUser = ayUserService.findById("1");
	redisUsersize = redisTemplate.opsForList().size("ALL_USER_LIST");
	System.out.println("目前缓存中的用户数量为:"+ redisUsersize);
	System.out.printIn("--->>>id:"+ ayUser.getId()+"name:"+ ayUser. getName());
	//查询id=2的数据,该数据存在于Redis缓存中
	AyUser ayUserl = ayUserService.findById("2");
	redisUsersize = redisTemplate.opsForList().size("ALL_USER_LIST");
	System.out.println("目前缓存中的用户数量为:"+ redisUsersize);
	System.out.printIn("--->>i:"+ ayUser1.getId()+"name:"+ ayUserl.getName());
	//查询id=4的数据,不存在于 Redis缓存中,存在于数据库中,所以会把数据库查询的数据更新到缓存中
	AyUser ayUser3 = ayUserService.findById("4");
	System.out.println ("--->> id:" + ayUser3.getId()+ "name:"+ ayUser3. getName());
	redisUserSize = redisTemplate.opsForList().size("ALL_USER_LIST");
	System.out.println("目前缓存中的用户数量为:"+ redisUsersize);
}

代码开发完成之后,重新启动项目,数据库中的3条数据会重新被添加到Redis缓存中。项目启动成功之后,我们往数据库表ay_user中添加id为4的第4条数据。

最后执行单元测试方法testFindById(),在Intellij IDEA的控制台中会打印如下的信息:

目前缓存中的用户数量为:3
-->>>id:name:阿毅
目前缓存中的用户数量为:3
--->>>id:name阿兰
--->>>id: 4 name: test
目前缓存中的用户数量为:4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值