zoukankan      html  css  js  c++  java
  • SpringBoot日记——缓存的使用

      SpringBoot核心技术的东西基本上都有介绍过了,接下来,进阶点~来说说缓存吧~

      缓存这个词不少同学应该不会很陌生。而我们这里主要使用的就是Redis。

      客户端第一次请求的时候是从库里拿出我们需要的数据,但如果每次查询都从库里拿,就会很耗时耗能。那么使用缓存以后,我们只需要第一次从库里拿完存到缓存中,只要不清除缓存,我们以后的请求都直接在缓存中拿数据,就会快很多很多。

      先给出几个基础的方法,包括Mapper/Bean/Controller,不然后边说的东西估计有些人会很懵。

    package com.oooodin.cache.bean;
    
    public class Employee {
        
        private Integer id;
        private String lastName;
        private String email;
        private Integer gender; //性别 1男  0女
        private Integer dId;
        
        
        public Employee() {
            super();
        }
    
        
        public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) {
            super();
            this.id = id;
            this.lastName = lastName;
            this.email = email;
            this.gender = gender;
            this.dId = dId;
        }
        
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getLastName() {
            return lastName;
        }
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
        public String getEmail() {
            return email;
        }
        public void setEmail(String email) {
            this.email = email;
        }
        public Integer getGender() {
            return gender;
        }
        public void setGender(Integer gender) {
            this.gender = gender;
        }
        public Integer getdId() {
            return dId;
        }
        public void setdId(Integer dId) {
            this.dId = dId;
        }
        @Override
        public String toString() {
            return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId="
                    + dId + "]";
        }
    
    }
    bean.Employee
    import com.oooodin.cache.bean.Employee;
    import org.apache.ibatis.annotations.Delete;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Select;
    import org.apache.ibatis.annotations.Update;
    
    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,genderm,d_id) VALUES(#{lastName},#{email},#{gender},#{dId})")
        public void insertEmp(Employee employee);
    }
    mapper.EmployeeMapper
    import com.oooodin.cache.bean.Employee;
    import com.oooodin.cache.mapper.EmployeeMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.CachePut;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Service;
    
    @Service
    public class EmployeeService {
    
        @Autowired
        EmployeeMapper employeeMapper;
    
        /**
         * 将方法结果进行缓存
         * 再要相同数据,直接从缓存中获取,不再调用方法
         *
         * @param id
         * @return
         */
        @Cacheable(cacheNames = "emp")
        public Employee getEmp(Integer id) {
            System.out.println("查询" + id + "号员工");
            Employee emp = employeeMapper.getEmpById(id);
            return emp;
        }
    
        @CachePut(cacheNames = "emp", key = "#result.id")
        public Employee updateEmp(Employee employee) {
            System.out.println("updateEmp:" + employee);
            employeeMapper.updateEmp(employee);
            return employee;
        }
    
        @CacheEvict(cacheNames = "emp", key = "#id")
        public void deleteEmp(Integer id) {
            employeeMapper.deleteEmpById(id);
        }
    }
    service.EmployeeService
    import com.oooodin.cache.bean.Employee;
    import com.oooodin.cache.service.EmployeeService;
    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 getEmploee(@PathVariable("id") Integer id) {
            Employee emp = employeeService.getEmp(id);
            return emp;
        }
    
        @GetMapping("/emp")
        public Employee updateEmp(Employee employee) {
            Employee emp = employeeService.updateEmp(employee);
            return emp;
        }
    
        @GetMapping("/delete")
        public String deleteEmp(Integer id) {
            employeeService.deleteEmp(id);
            System.out.println("success");
            return "success to delete EMP with id =" + id.toString();
        }
    }
    controller.EmployeeController

    基本注解

      我们需要了解的一些基本注解有:

        @EnableCache:开启基于注解的缓存。通常我们放在application的主方法中

        @Cacheable:针对方法请求参数对结果进行缓存
        @CachePut:保证方法的调用/执行,以及更新缓存
        @CacheEvict:清除缓存

      难么如何来使用呢?首先,在pom.xml中添加如下:

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>

      这样,我们就关联了cache缓存。

      然后,我们创建数据,在数据库里录入些东西,让我们之后可以读取和展示数据。那么关于增删改查的,关于mapper/bean等方法我就不在这里写了,想了解的可以翻看前边的文章~

      下边是主程序的代码,我加了一些注释,告诉大家一些基本步骤

    /**
     * 一、搭建环境
     * 1.导入数据库文件,创建出两个表
     * 2.创建javaBean封装数据库
     * 3.整合Mybatis数据源信息
     *      1.配置数据库
     *      2.使用注解版的MyBatis
     *          1)、使用@Mapper扫描包
     *          2)、创建Service和Controller
     * 二、缓存
     *      步骤:
     *          1、开启基于注解的缓存
     *          2、标注缓存注解即可
     *              @Cacheable
     *              @CacheEvict
     *              @CachePut
     */
    @MapperScan("com.oooodin.cache.mapper")
    @SpringBootApplication
    @EnableCaching
    public class CacheApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(CacheApplication.class, args);
        }
    }

      

      看到了吧,上边有个橙色的注解,那个就是开启了缓存的注解功能,这样我们方法中写的缓存注解就可以被识别和使用了。例如:

      这个方法的结果就会被写入到缓存中,我们可以启动主程序,然后在浏览器中多访问几次,看看打印了几次,如果只有1次,说明后边的请求都是从缓存中获得,而没有运行方法去查数据库,那么就成功了。

      http://localhost:8080/emp/1   <====用这个来查询1号员工,并存入缓存

        @Cacheable(cacheNames = "emp")
        public Employee getEmp(Integer id) {
            System.out.println("查询" + id + "号员工");
            Employee emp = employeeMapper.getEmpById(id);
            return emp;
        }

      继续来看:

      这个就是将缓存数据更新的作用,同时方法也一定会运行。也就是像之前那样多次请求的话,每次都会访问数据库了。那么我们为什么要用这个?

      这么说吧,当我们更新数据库的同时,同样更新缓存。然后我们再次请求一次。所以我们更新以后,再用上边的地址查询一下看看是不是有更新。

      http://localhost:8080/emp?id=1&lastName=张三&gender=2  <===这个是用来更新数据到数据库的,同时也可以更新缓存。

        @CachePut(cacheNames = "emp")
        public Employee updateEmp(Employee employee) {
            System.out.println("updateEmp:" + employee);
            employeeMapper.updateEmp(employee);
            return employee;
        }

      诶?是不是发现更新没问题,但是查询发现没变啊????

      来看这个参数:key。因为我们在查询的那个方法中如果没有设定key,就会默认以参数当做key值在保存。然后我们在更新的时候要对应key才行。所以(取结果的id):

      这回我们再刷新和查询的时候就会有变化了吧~

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

      

      在开发过程中,我们不光是要更新,也要清除缓存,不然一直存着也会有问题的~:

      这样,我们清除缓存名未emp中key是id的那条~,再次查询的时候,你会发现,我们又需要查询数据库重新保存缓存了。

      http://localhost:8080/delete?id=1  <===删除id是1的那条缓存

        @CacheEvict(cacheNames = "emp", key = "#id")
        public void deleteEmp(Integer id) {
            employeeMapper.deleteEmpById(id);
        }

      

      当然注解和参数,还有其他很多,我们可以去进入的jar包看一下具体的都有哪些,然后自己挨个尝试一下。比如Caching。这里我就不详细来说了(其实也没说多少东西……)

      对了,这里给大家推荐一下可以学习的地方。可以搜一下 尚硅谷讲的SpringBoot的搞基片(高级篇),里边讲的真的很不错,很详细。

      真正的教程不是视频或者书籍,而是官方API文档和源码。看懂这两个就能基本解决所有问题了,加油!

      下一篇文章,说一下redis我们是如何整合的吧~

  • 相关阅读:
    WF4.0 Beta1 自定义跟踪
    WF4.0 Beta1 流程设计器与Activity Designer
    新版本工作流平台的 (二) 权限算法(组织结构部分)
    WF4.0 Beta1 WorkflowInvoker
    WF4.0 基础篇 (十) Collection 集合操作
    WF4.0 基础篇 (十五) TransactionScope 事物容器
    WF4.0 基础篇 (六) 数据的传递 Arguments 参数
    WF4B1 的Procedural Activity 之InvokeMethod , InvokeMethod<T> 使用
    WF4.0 Beta1 异常处理
    WF4.0 Beta1 变量 Variables
  • 原文地址:https://www.cnblogs.com/iceb/p/9475059.html
Copyright © 2011-2022 走看看