springboot中缓存使用

为什么使用缓存

  • 对于一些经常读取很少修改的数据存入缓存,减少查询数据库的消耗

缓存的使用步骤

  1. 创建springboot应用,选中Mysql、Mybatis、Web模块

  2. 创建数据库表及对应的pojo类

在这里插入图片描述

@Data
public class Employee {

    private Integer id;
    private String lastName;
    private String email;
    private Integer gender; //性别 1男  0女
    private Integer dId;
}
  1. 整合mybatis操作数据库
  • 添加jar包依赖

            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.2</version>
            </dependency>
    
  • 在application.properties中添加数据源配置

    spring.datasource.url=jdbc:mysql://localhost:3306/springboot_h?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
    spring.datasource.username=root
    spring.datasource.password=root
    #spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
  1. 创建dao层、service层和controller层,核心启动类上添加@MapperScan扫描mapper包

    dao层:

    public interface EmployeeMapper {
    
        @Select("select * from employee where id = #{id}")
        public Employee getEmpById(Integer id);
    
        @Insert("insert into employee(lastName, email, gender, d_id) values(#{lastName},#{email},#{gender},#{dId})")
        public void insertEmp(Employee employee);
    
        @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);
    
    }
    

    service层:

    @Service
    public class EmployeeService {
    
        @Autowired
        private EmployeeMapper employeeMapper;
    
        public Employee findEmpById(Integer id){
            Employee emp = employeeMapper.getEmpById(id);
            return emp;
        }
    
        public Employee updateEmp(Employee employee){
            employeeMapper.updateEmp(employee);
            return employee;
        
    
        public void delEmp(Integer id
            employeeMapper.deleteEmpById(id);
        }
    
    }
    

    controller层:

    @RestController
    public class EmployeeController {
    
        @Autowired
        private EmployeeService employeeService;
    
        @RequestMapping("/emp/{id}")
        public Employee getEmp(@PathVariable("id") Integer id){
            Employee emp = employeeService.findEmpById(id);
            return emp;
        }
    
        @RequestMapping("/updateEmp/{id}")
        public Employee updateEmp(@PathVariable("id") Integer id){
            Employee emp = employeeService.findEmpById(id);
            //手动设置更新
            emp.setLastName("李四");
            Employee employee = employeeService.updateEmp(emp);
    
            return employee;
        }
    
        @RequestMapping("/delEmp/{id}")
        public Employee delEmp(@PathVariable("id") Integer id){
            employeeService.delEmp(id);
            return null;
        }
    }
    

    核心启动类添加注解扫描:

    @MapperScan("com.example.mapper")
    
  2. 核心启动类添加@EnableCaching开启基于注解的缓存,pojo类需要实现序列化接口

    • 开启基于注解的缓存
    @SpringBootApplication
    @MapperScan("com.example.mapper")
    @EnableCaching
    public class SpringBoot04CacheApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringBoot04CacheApplication.class, args);
        }
    
    }
    
    • 修改pojo类,实现序列化接口
    @Data
    public class Employee implements Serializable {
    
        private Integer id;
        private String lastName;
        private String email;
        private Integer gender; //性别 1男  0女
        private Integer dId;
    }
    
  3. 缓存相关注解的使用(在service层的方法上添加注解)及测试

    1. 查询使用:@Cacheable(key = “#id”, condition = “#id > 0”, unless = “#result == null”)
    	/*
    	 * 	@Cacheable : 缓存查询:会将该方法的返回值存到缓存中
    	 *		value/cacheNames:指定缓存的名称 ,cacheManager是管理多个cache,以名称进行区分
    	 * 		key:缓存数据时指定key值 (key,value) ,默认是方法的参数值,也可以使用spEL来计算key的值
    	 * 		keyGenerator:key的生成策略,和key进行二选一 ,自定义keyGenerator
    	 * 		cacheManager:指定缓存管理器  redis:emp   ehcache:emp
    	 * 		cacheResolver: 功能跟cacheManager相同,二选一即可
    	 * 		condition:条件属性,满足这个条件才会进行缓存
    	 * 		unless: 否定条件:满足这个条件,不进行缓存
    	 * 		sync: 是否使用异步模式进行缓存 true
    	 *			(1) condition/unless 同时满足,不缓存
    	 * 			(2) sync的值为true的时候,unless不被支持
    	 */
    @Cacheable(cacheNames = {"emp"}, key = "#id", condition = "#id > 0", unless = "#result == null")
        public Employee findEmpById(Integer id){
            Employee emp = employeeMapper.getEmpById(id);
            return emp;
        }
    

    先查询缓存,缓存没有则查询数据库,然后添加进缓存。

    1. 更新使用:@CachePut(key = “#employee.id”)

          @CachePut(cacheNames = {"emp"}, key = "#employee.id")
          public Employee updateEmp(Employee employee){
              employeeMapper.updateEmp(employee);
              return employee;
          }
      

      方法执行,缓存也一定会更新

    2. 删除使用:@CacheEvict(key = “#id”,beforeInvocation = true)

          //beforeInvocation = true即为在方法执行前清除缓存,为false在方法执行后再清除,若
      	//方法发生异常,可能产生未清除缓存的情况。
      	//默认为false,所以需要手动改为true
      	@CacheEvict(cacheNames = {"emp"}, key = "#id", beforeInvocation = true)
          public void delEmp(Integer id){
              employeeMapper.deleteEmpById(id);
          }
      
    3. 全局配置时使用:@CacheConfig(cacheNames = {“emp”}) ,在类上标明此注解,方法上即可省去相关配置

  4. 测试:

    1. 查询:

      • 第一次查询时缓存没有数据,执行了sql语句

在这里插入图片描述
第二次查询时缓存已存入数据,不再执行sql语句

  1. 更新:

在这里插入图片描述
再次查询因为缓存已经更改,也不再执行sql语句。

  1. 删除:

在这里插入图片描述

再次查询,缓存中没有数据,所以会执行sql查询数据库,当然,数据库也没有数据了。

在这里插入图片描述

总结:

  • 一个springboot工程想要使用缓存,在核心启动类上添加**@EnableCaching**注解即可
  • @Cacheable对应查询、@Cacheput对应更新、@CacheEvict对应删除、@CacheConfig对应全局配置
  • 注意pojo类需要实现序列化接口
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值