Spring Boot's personal notes from 0 to learn 7 - caching cache

1. Concept

  • Cache: Cache interface, which defines the cache operation
  • @EnableCaching: Turn on cache mode
  • CacheManager: Cache manager, manage various cache components
  • @Cacheable: Before the method, it is generally used before querying the operation method of a certain id, so that if you check the ID next time, the method will not be executed and the result will be taken directly from the cache
  • @CacheEvict: Clear the cache, generally used before the method of deleting a certain ID
  • @CachePut: Ensure that the method is called, and hope that the result is cached, before using the updated method

Two, create a project

Insert picture description here
Be prepared first, import the basic things
spring-boot-mycache-preparation (Chinese removed)
Database: cache

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for department
-- ----------------------------
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `departmentName` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `lastName` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `gender` int(2) DEFAULT NULL,
  `dId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  • Note, there is one more servicelayer here , which can be understood as something between Mapper and Controller, which is more standardized

Third, the initial use of the cache

EmployeeService:

@Service
public class EmployeeService{
    
    
    @Autowired
    EmployeeMapper employeeMapper;

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

@Cacheable: Execute before calling the method . There are many optional attributes inside, there are several attributes below

  • cacheNames/value: Specify the name of the cache component; which cache to put the return result of the method in is an array, and multiple caches can be specified;
  • key: The key used for cached data; you can use it to specify. The default is to use the value of the method parameter 1-the return value of the method, write SpEL; #id;The value of the parameter id#a0 #p0 #root.args[0],getEmp[2]
  • keyGenerator: Key generator; you can specify the component id of the key generator yourself
  • key/keyGenerator:Choose one to use;
  • cacheManager: Specify the cache manager; or cacheResolver to specify the resolver
  • condition: Cache only when the specified conditions are met; for example condition = "#id>0": Cache only when the value of the first parameter>1
  • unless: Negative caching; when the condition specified by unless is true, the return value of the method will not be cached; the result can be obtained for judgment. For example unless = "#result == null": if the result is empty, it will not be saved. unless = "#a0==2": If the value of the first parameter is 2, the result is not cached;
  • sync: Whether to use asynchronous mode

The following is the format of SpEL, @Cacheablewhich is the format in which the properties can be written, but it @Cacheablecannot be used #result, because it is useless to return the result, which @Cacheableis executed before the method is run.
Insert picture description here
Annotation is also added in front of the SpringBootMycacheApplication class to @EnableCachingenable the caching mechanism

When we input http://localhost:8080/emp/1, when
Insert picture description here
you press the console file several @EnableCachingtimes, the console will not pop again and appear again, because it has been saved in the cache, Java will automatically call the contents of the cache instead of Call method

Four, simply talk about the principle

1) Use CacheManager [ConcurrentMapCacheManager] to get the Cache [ConcurrentMapCache] component according to the name.
2) The key is generated using keyGenerator, and the default is SimpleKeyGenerator.
I don't understand it. . .

Five, attributes

1、key/keyGenerator

  • key: The key used for cached data; you can use it to specify. The default is to use the value of the method parameter 1-the return value of the method, write SpEL; #id;The value of the parameter id#a0 #p0 #root.args[0],getEmp[2]
  • keyGenerator: Key generator; you can specify the component id of the key generator yourself
  • key/keyGenerator:Choose one to use;

For example, if we are visiting http://localhost:8080/emp/1, the id is 1, then the default key is 1.
But if the @Cacheable(cacheNames = {"emp"},key = "#root.methodName+'['+#id+']'")key is 方法名[id], for example, the id is 1, then the key is getEmp[1](because our @Cacheableannotation is placed in front of the method, and the key is the attribute)

For keyGenerator, write a class and use it, I don’t know how. . . .

    @Cacheable(cacheNames = {
    
    "emp"},key = "#root.methodName+'['+#id+']'")
    public Employee getEmp(Integer id){
    
    
        System.out.println("查询"+id+"号员工");
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }

2、condition/unless

For example condition = "#id>2": when id>2, this method is added to the cache
condition = "#a0>1": when the value of the first parameter>1, it is added to the cache, a0which refers to the first parameter
unless = "#a0>1": this is the reverse, when the first parameter When a parameter>1, do not join the cache

Six, @CachePut

This comment is generally used to write before the update.
Execution steps: After running the method, call the annotation.

First complete the code to
EmployeeService:

//这一行是正确的写法,如果没有的话,就产生下面说的key不一致的错误
@CachePut(/*value = "emp",*/key = "#result.id")
public Employee updateEmp(Employee employee){
    
    
    System.out.println("updateEmp:"+employee);
    employeeMapper.updateEmp(employee);
    return employee;
}

EmployeeController:

@GetMapping("/emp")
public Employee update(Employee employee){
    
    
    Employee emp = employeeService.updateEmp(employee);
    return emp;
}

It is also something that the service calls the Mapper layer, and then the controller layer is responsible for requesting and returning values

1. Analysis

  • @CachePut: Not only call the method, but also update the cache data; update the cache synchronously
  • Modify a certain data in the database and update the cache at the same time;
    • When to run:
    • 1. Call the target method first
    • 2. Cache the results of the target method

According to the source code, we can know that things are cached according to the name (key) when caching. For example id=1, if we check , then this key is 1
if the @CachePutattribute key is not written in it, then, according to the update()function, the key is employee, one key is 1, and the other key is employee, The two keys are different, no cache binding is performed, and the cache cannot be modified.
Insert picture description here

  • It is because the key is different, or it is not used when it is updated. It @CachePutis only displayed on the web page, but it will not be returned to the database.

2. The correct way to update the cache:

@CachePutAdd the attribute key = "#result.id"or key = "#employee.id", then the default key will not be used as the parameter, but will become #result.idor #employee.id. The former means that the key is the id of the result of the method, because the returned result is employee, and the attribute is id. For example, if our new id is 1, then this key is also changed 1instead of employee, and the result of the latter is the same as before.
Note that the above is key = "#root.methodName+'['+#id+']'"deleted, otherwise the ID is different and the experiment will not be possible

    @Cacheable(value = {
    
    "emp"})
    public Employee getEmp(Integer id){
    
    
        System.out.println("查询"+id+"号员工");
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }
    @CachePut(value = {
    
    "emp"},key = "#result.id")
    public Employee updateEmp(Employee employee){
    
    
        System.out.println(employee.getdId());
        System.out.println("updateEmp:"+employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

For these two, the operating cache name is called emp. Then, in emp, the two keys must be the same for normal operation.
First query
Insert picture description here
and then modify.
Insert picture description here
Console:
Insert picture description here
But the database:
Insert picture description here
Although it is not displayed on the web page! ! ! ! ! The cache has been changed, the database has also been changed, this is a fact! ! ! ! !

3. Just use it in the future

In the future, if you want to cache, query, @Cacheable(value = {"xxx"})and update the same thing again @CachePut(value = {"xxx"},key = "#result.yyy"), the first query parameter is an object attribute, then yyy is the attribute of the object and the query parameter

Seven, @CacheEvict: cache clearing

@CacheEvict: Cache clear
service layer

    @CacheEvict(value="emp"/*beforeInvocation = true*/,key = "#id")
    public void deleteEmp(Integer id){
    
    
        System.out.println("deleteEmp:"+id);
        employeeMapper.deleteEmpById(id);
    }

EmployeeController:

    @GetMapping("/delemp")
    public String deleteEmp(Integer id){
    
    
        employeeService.deleteEmp(id);
        return "成功删除"+id+"号员工";
    }

@CacheEvictProperties in:

  • key: Specify the data to be cleared
  • allEntries = true: Specify to clear all the data in this cache, the default is false
  • beforeInvocation = false: Is the cache clearing performed after the method? True is executed after the method, and false is executed before the method. , The default represents that the cache clearing operation is executed after the method is executed; if an exception occurs, the cache will not be cleared, the default is false
  • beforeInvocation = true: Indicates that the cache clear operation is executed before the method runs. The cache will be cleared regardless of whether the method is abnormal or not. The default is false

Check and
Insert picture description here
Insert picture description here
delete
Insert picture description here

Insert picture description here
Insert picture description here
Check again
Insert picture description here
Insert picture description here

  • It is displayed on the console again, because the deletion has deleted the cache, and there is no cache. When you check again, you can only call the method and call the database. If you check again at this time, the cache is called

Eight, @Caching and @CacheConfig

@CachingThe source code:

public @interface Caching {
    
    
    Cacheable[] cacheable() default {
    
    };

    CachePut[] put() default {
    
    };

    CacheEvict[] evict() default {
    
    };
}

This is a complex combination of caching mechanism, which can be written as

// @Caching 定义复杂的缓存规则
@Caching(
        cacheable = {
    
    
                @Cacheable(value="emp",key = "#lastName")
        },
        put = {
    
    
                @CachePut(value="emp",key = "#result.id"),
                @CachePut(value="emp",key = "#result.email")
        }
)
public Employee getEmpByLastName(String lastName){
    
    
    return employeeMapper.getEmpByLastName(lastName);
}
  • That is, this one annotation uses so many cached annotations (in fact, it can be used separately)

@CacheConfig: // extraction buffer common configuration
example @CacheConfig(cacheNames="emp"), used in front of the class, it shows all the cache of the class valueor cacheNamesareemp

Nine, redis

This is a very powerful thing. Baidu says it can cache something.
Unfortunately, I won’t, forget it, I’ll learn it later, and I will use it when I find a job. . . Too much to learn

Guess you like

Origin blog.csdn.net/yi742891270/article/details/107728606
Recommended