数据库在用户数量多,系统访问量大的时候,系统性能会下降,用户体验差。
1.缓存优化
作用:
1.降低数据库的访问压力
2.提高系统的访问性能
3.从而提高用户体验
实现思路:
1.先查询缓存
2.如果缓存有数据,直接返回
3.如果缓存中没有数据,则需要查询数据库,再将数据库查询的结果,缓存到redis中。
4.如果数据库中的数据发生修改,缓存数据应当清空,保证和数据库中的数据一致!(下一次查询会查询数据库,然后最新的数据就到缓存了)
2.使用Redis缓存优化
1.环境搭建
1.导入maven坐标
<!--spring Data Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.修改配置文件
# redis相关配置
redis:
host: ip地址
port: 6379
password: 密码
database: 0 # 操作的是0号数据库
jedis:
#redis连接池配置
pool:
max-active: 8 #最大连接数
max-wait: 1ms #连接池最大阻塞等待时间
max-idle: 4 #连接池中最大空闲连接
min-idle: 0 #连接池中最小空闲连接
3.导入配置类
/**
* Redis配置类
*/
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory connectionFactory){
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
//默认的key序列化器为:JdkSerializationRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
2.使用RedisTemplate操作Redis
在高并发的情况下,频繁地查询数据库会导致系统性能下降,服务端响应时间增加,需要对这些Controller方法进行缓存优化,提高系统的性能。
实现思路:
1.先查询redis,如果redis中有就直接返回结果,如果没有就去查询数据库,并将查询到的结果放入Redis并指定有效期。
2.在新增,删除和修改操作的时候,清空对应的缓存,保证数据库中数据和缓存中数据一致。
3.Spring Cache(重点)
Spring Cache是一个框架,实现了 基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
Spring Cache提供了一层抽象,底层可以切换不同的cache实现,具体就是通过 CacheManager接口来统一不同的缓存技术。
ChacheManager是Spring提供的各种缓存技术抽象接口
EhCacheCacheManager :使用EhCache作为缓存技术
GuavaCacheManager:使用Google的GuavaCache作为缓存技术
RedisCacheManager:使用Redis作为缓存技术
使用步骤:
1.导入Maven坐标:(使用redis缓存技术)
<!--spring cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--spring Data Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置application.yml
spring:
cache:
redis:
time-to-live: 1800000 #设置缓存有效时间
3.在启动类上加入@EnableCaching注解,开启缓存注解功能
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
4.在Controller方法上加入@Cacheable,@CacheEvict等注解,进行缓存操作
@EnableCaching |
开启缓存注解功能 |
@Cacheable |
在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中。 |
@CachePut |
将方法的返回值放到缓存中 |
@CacheEvict |
将一条或多条数据从缓存中删除 |
注意:在Spring Boot项目中使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在启动类上使用@EnableCaching开启缓存支持即可。
例如:使用Redis作为缓存技术,只需要导入Spring data Redis的maven坐标即可。
对象在网络中传输需要实现序列化接口。
@Slf4j
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private CacheManager cacheManager;
/*
* 缓存测试 @Cacheable
*
* @Cacheable:
* 作用:
* 1.可以在方法执行前,先自动查询缓存,如果缓存中存在数据,就直接返回(此方法不再执行)
* 2.如果缓存中没有数据,执行此方法,并且将方法返回值自动存入redis
*
* 属性:
* cacheNames:key名称空间
* key: 名称空间下的key
* 最终redis存储的key:[cacheNames::key]
* 最终redis存储的key:[userCache::1]
*/
@Cacheable(cacheNames = "userCache",key = "#id")
@GetMapping("/{id}")
public User one(@PathVariable Long id){
User user = userService.getById(id);
log.info("缓存中没有查数据库");
return user;
}
/*
* 测试缓存清理:@CacheEvict
*
* @CacheEvict
* 作用:
* 当方法执行完毕后,去清理对应的缓存数据
*
* allEntries = true:代表把当前名称空间下的key都清理(默认false)
* */
// @CacheEvict(cacheNames = "userCache",allEntries = true)
@CacheEvict(cacheNames = "userCache",key = "#id")
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id){
userService.removeById(id);
}
@CacheEvict(cacheNames = "userCache",key = "#user.id")
@PutMapping
public User update(@RequestBody User user){
userService.updateById(user);
return user;
}
}
cacheNames和key相当于这样的结构