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我们是如何整合的吧~

  • 相关阅读:
    Porter Stemming Algorithm
    Hook API to detect memory leak
    Are tuples more efficient than lists in Python?
    boost::intrusive_ptr VS boost::shared_ptr
    How Python GC deal with referencecycles?
    LINQ排序数组
    Sublime Text 2 (Version 2.0.1 build 2217) x64 破解注册方法
    GC in C# and Python
    Python中的else
    Managed C++ Destructor
  • 原文地址:https://www.cnblogs.com/iceb/p/9475059.html
Copyright © 2011-2022 走看看