今天介绍 SpringBoot 的数据缓存。做过开发的都知道程序的瓶颈在于数据库,我们也知道内存的速度是大大快于硬盘的,当需要重复获取相同数据时,一次又一次的请求数据库或者远程服务,导致大量时间耗费在数据库查询或远程方法调用上,导致性能的恶化,这便是数据缓存要解决的问题。
对应的 cache 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
项目配置 application.properties
# springboot2.0加cj(mysql驱动)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#我把ip去掉了,33306是我docker中的mysql端口转发,MyBatis数据库,useSSL=false连接外网
# 这里是jdbc:mysql,用编辑器复制会去访问,我加个`
spring.datasource.url=jdbc:mysql`://ip:33306/MyBatis?&serverTimezone=GMT&userUnicode=true&characterEncoding=UTF8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
# mybatis开启驼峰命名匹配规则
mybatis.configuration.map-underscore-to-camel-case=true
# log4j配置debug
logging.level.cachedemo.mapper = debug
# redis配置
spring.redis.port=6380
spring.redis.host=106.54.232.112
在项目的启动类里添加 @EnableCaching
注解,他会去扫描每一个 bean,检查是否存在对应的缓存,如果有执行缓存。
对应的 employee 类的字段,后面代码直接 ALT+INS
补充 getting
, setting
,和 tostring
方法
import org.apache.ibatis.annotations.*;
@Mapper
public interface EmployeeMapper {
@Select("SELECT * FROM employee WHERE id = #{id}")
public Employee getEmpById(Integer id);
@Update("UPDATE employee SET lastName=#{lastName},email=#{email},gender=#{gender},d_id=#{dId} WHERE id=#{id}")
public void updateEmp(Employee employee);
@Delete("DELETE FROM employee WHERE id=#{id}")
public void deleteEmpById(Integer id);
@Insert("INSERT INTO employee(lastName,email,gender,d_id) VALUES(#{lastName},#{email},#{gender},#{dId})")
public void insertEmployee(Employee employee);
@Select("SELECT * FROM employee WHERE lastName = #{lastName}")
Employee getEmpByLastName(String lastName);
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeController {
@Autowired
EmployeeService employeeService;
@GetMapping("/emp/{id}")
public Employee getEmployee(@PathVariable("id") Integer id) {
Employee employee = employeeService.getEmp(id);
return employee;
}
@GetMapping("/emp")
public Employee update(Employee employee) {
Employee emp = employeeService.updateEmp(employee);
return emp;
}
@GetMapping("/delemp")
public String deleteEmp(Integer id) {
employeeService.deleteEmp(id);
return "success";
}
@GetMapping("/emp/lastname/{lastName}")
public Employee getEmpByLastName(@PathVariable("lastName") String lastName) {
return employeeService.getEmpByLastName(lastName);
}
}
缓存用 @Cacheable 封装在 server 服务中的
@Cacheable 主要是针对方法配置,能根据方法的请求参数对结果进行缓存
// value指的是路由emp,
@Cacheable(value = {"emp"} /*,keyGenerator = "myKeyGenerator",condition = "#a0>1",unless = "#a0==2"*/)
public Employee getEmp(Integer id) {
System.out.println("查询" + id + "号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
跑起来,第一次访问要几秒,因为没有缓存,去数据库需要时间
控制台也给出回应
刷新就不去数据库拿数据了
到底是通过什么东东缓存的?
使用的是 CacheAutoConfiguration 配置类
缓存的配置类
* org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration
* org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration
* org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration
* org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration
* org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
* org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
* org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
* org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
* org.springframework.boot.autoconfigure.cache.GuavaCacheConfiguration
* org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration【默认】
* org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
源码中使用的是 SimpleCacheConfiguration
运行流程:
(百度的)