前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springboot中的cache(一)

Springboot中的cache(一)

作者头像
润森
发布2019-12-25 14:44:50
4320
发布2019-12-25 14:44:50
举报
文章被收录于专栏:毛利学Python毛利学Python

今天介绍 SpringBoot 的数据缓存。做过开发的都知道程序的瓶颈在于数据库,我们也知道内存的速度是大大快于硬盘的,当需要重复获取相同数据时,一次又一次的请求数据库或者远程服务,导致大量时间耗费在数据库查询或远程方法调用上,导致性能的恶化,这便是数据缓存要解决的问题。

pom.xml

对应的 cache 依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

项目配置 application.properties

代码语言:javascript
复制
# 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方法

cache 的体验

代码语言:javascript
复制
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);
}

路由和控制器

代码语言:javascript
复制
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 主要是针对方法配置,能根据方法的请求参数对结果进行缓存

代码语言:javascript
复制
// 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 配置类

代码语言:javascript
复制
缓存的配置类
* 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

运行流程:

  • 方法运行之前,先去查询 Cache(缓存组件),按照 cacheNames 指定的名字去缓存中获取(CacheManager 先获取相应的缓存),第一次获取缓存,如果没有 Cache 组件,则会自动创建。
  • 去 Cache 中查找缓存的内容,使用一个 key(默认是方法的参数),其中 key 是按照某种策略生成的,默认是使用 SimpleKeyGenerator 生成的。
  • SimpleKeyGenerator 生成 key 的策略:
    • 如果没有参数,key=new SimpleKey();
    • 如果有一个参数,key = 参数值
    • 如果有多个参数,key=new SimpleKey(params);
    • 没有查到缓存,就调用目标方法;如果查到缓存,则直接返回结果,不调用目标方法。
    • 没有查到缓存后去调用目标方法,然后将目标方法返回的结果放进缓存。

(百度的)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小刘IT教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • pom.xml
  • cache 的体验
    • 路由和控制器
    相关产品与服务
    数据库
    云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档