在Springboot应用使用redis缓存
缓存
缓存(cache,又称高速缓存)是指可以高速访问的、用于临时存储的数据存储区。
缓存使用的场合
缓存一般用于在较短的时间段对相同数据频繁读取的场合,将读取频度较高的数据放入缓存,直接从缓存取数据,以提高效率。
redis缓存
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。Redis本身是一个内存数据库,在应用中可以充当缓存,提高系统数据查询性能。
redis缓存使用实例
redis的安装
Window 环境
- 下载地址:https://github.com/MSOpenTech/redis/releases
- 下载zip版本或者安装版(建议zip版)
- 解压
- 打开一个 cmd 窗口 使用cd命令切换目录到 redis解压目录, 运行 redis-server redis.windows.conf,启动redis服务
- 另打开一个cmd窗口,切换到redis目录下运行 redis-cli -h 127.0.0.1 -p 6379
- 输入 set key value 存储一个键值对
- 输入 get key 根据键获取值
- 若一切顺利,则安装成功。
ubuntu/deepin 环境
- 在终端执行命令 sudo apt-get update ,更新软件列表
- 在终端执行命令 sudo apt-get install redis-server 安装redis
- 启动redis服务器
前台方式启动:在终端执行命令 redis-server
后台方式启动:在终端执行命令 /etc/init.d/redis-server start - 在终端执行命令 redis-cli 进入redis客户端命令行模式
- 输入 set key value 存储一个键值对
- 输入 get key 根据键获取值
- 关闭redis服务器
前台启动方式的关闭:在终端执行 redis-cli shutdown
后台启动方式的关闭:在终端执行 /etc/init.d/redis-server stop - 若一切顺利,则安装成功。
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
在配置文件application.yaml中添加如下配置:
spring:
cache:
redis:
time-to-live: 6000000 #缓存有效时间
type: redis #缓存类型
redis:
database: 1 # Redis数据库索引(默认为0)
host: 127.0.0.1 # Redis服务器地址
password: # Redis服务器连接密码(默认为空)
jedis:
pool:
max-idle: 100 # 连接池最大连接数(使用负值表示没有限制)连接池中的最大空闲连接
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 2 # 连接池中的最小空闲连接
port: 6379 # Redis服务器连接端口
timeout: 15000 # 连接超时时间(毫秒)
在配置类上引入注解@EnableCaching开启缓存
@SpringBootApplication
@EnableCaching
public class XXXApplication implements WebMvcConfigurer {
//...
public static void main(String[] args) {
SpringApplication.run(ScgcxxApplication.class, args);
}
//...
}
在业务对象使用缓存注解
-
@CacheConfig是一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager 和CacheResolver。
该操作会被方法级别注解覆盖。
-
@Cacheable是一个方法级别的注解,声明方法返回值是可缓存的,将返回值存储到缓存中以便后续使用相同参数调用时不需执行实际的方法,直接从缓存中取值。
缓存数据的key值由@Cacheable的key属性指定。key属性指定可以使用spEL(Spring EL,即Spring表达式),其中几个重要内置变量名:targetClass(当前目标对象所属类名)、methodName(当前方法名称)、#P0(第0个参数)、#p1(第1个参数)、#ename(名称为ename的参数)
-
@CachePut是一个方法级别的注解,用于声明方法正常执行,并在执行后更新缓存。
@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
-
@CacheEvict是一个方法级别的注解,用于声明方法正常执行,并在执行后清空指定key值的缓存或全部的缓存。
spring cache不仅支持将数据缓存,还支持将缓存数据删除。此过程经常用于从缓存中清除过期或未使用的数据。@CacheEvict可以指定删除一个key或多个key缓存数据。此外,还提供了一个额外的属性allEntries ,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。
缓存注解代码示例
@Service
@Transactional
@CacheConfig(cacheNames="customer")
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerDao customerDao;
//Customer应当是可序列化类
@Cacheable(key="targetClass +'.'+ methodName+'()'")
@Override
public List<Customer> getAllCustomers() {
return customerDao.findAllCustomers();
}
//Customer应当是可序列化类
//方法的参数若为Pojo(JavaBean),应当重写toString方法,确保同样的属性值toString返回值是一致的
@Cacheable(key="targetClass +'.'+ methodName+'(' + #p0 +')'")
@Override
public PageInfo<Customer> getCustomersPage(PageParam pageParam) {
return PageCreater.createPageInfo(
()->{return customerDao.findCustomersPage(pageParam);},
pageParam
);
}
//Customer应当是可序列化类
@Cacheable(key="targetClass +'.'+ methodName+'(' + #cus_id +')'")
@Override
public Customer getCustomer(Integer cus_id) {
return customerDao.findCustomerbyId(cus_id);
}
@CacheEvict(allEntries=true)
@Override
public boolean addCustomer(CustomerDto dto) {
dto.setCus_status(DataStatusEnum.未确定.getCode());
int cnt = customerDao.insertCustomer(dto);
return cnt>0;
}
@CacheEvict(allEntries=true)
@Override
public boolean updateCustomer(CustomerDto dto) {
int cnt = customerDao.updateCustomer(dto);
return cnt>0;
}
@CacheEvict(allEntries=true)
@Override
public boolean deleteCustomer(Integer... cus_ids) {
if(cus_ids==null || cus_ids.length==0) {
return false;
}
int cnt = customerDao.deleteCustomerByIds(cus_ids);
return cnt>0;
}
@CacheEvict(allEntries=true)
@Override
public boolean updateCustomersStatus(String status, Integer[] cus_ids) {
if(cus_ids==null || cus_ids.length==0) {
return false;
}
int cnt = customerDao.updateCustomerStatusByIds(status,cus_ids);
return cnt>0;
}
}
注:
业务方法的返回对象应当实现序列化接口,示例如下:
public class Customer implements Serializable {
private Integer cus_id;
private String cus_name;
private String cus_remark;
private String cus_status;
//......
}
Dto对象应当重写toString方法,示例如下:
public class CustomerDto extends PageParam {
private static final Logger LOG = LoggerFactory.getLogger(CustomerDto.class);
@Override
public String toString() {
String json = new ObjectMapper().writeValueAsString(this);//将本对象转化为json串
LOG.debug(this.getClass().getSimpleName() + "=>" + json);
return json;
}
private Integer cus_id;
private String cus_name;
private String cus_remark;
private String cus_status;
//......
}
进行测试
在application.yaml文件中配置缓存日志,启动运行观察日志信息。
logging:
level:
......
org.springframework.cache: trace
......