1. Concept
- Cache: Cache interface, which defines the cache operation
@EnableCaching
: Turn on cache modeCacheManager
: 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
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
service
layer 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 yourselfkey/keyGenerator
:Choose one to use;cacheManager
: Specify the cache manager; or cacheResolver to specify the resolvercondition
: Cache only when the specified conditions are met; for examplecondition = "#id>0"
: Cache only when the value of the first parameter>1unless
: 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 exampleunless = "#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, @Cacheable
which is the format in which the properties can be written, but it @Cacheable
cannot be used #result
, because it is useless to return the result, which @Cacheable
is executed before the method is run.
Annotation is also added in front of the SpringBootMycacheApplication class to @EnableCaching
enable the caching mechanism
When we input http://localhost:8080/emp/1
, when
you press the console file several @EnableCaching
times, 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 yourselfkey/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 @Cacheable
annotation 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, a0
which 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 @CachePut
attribute 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.
- It is because the key is different, or it is not used when it is updated. It
@CachePut
is only displayed on the web page, but it will not be returned to the database.
2. The correct way to update the cache:
@CachePut
Add the attribute key = "#result.id"
or key = "#employee.id"
, then the default key will not be used as the parameter, but will become #result.id
or #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 1
instead 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
and then modify.
Console:
But the database:
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+"号员工";
}
@CacheEvict
Properties in:
key
: Specify the data to be clearedallEntries = true
: Specify to clear all the data in this cache, the default is falsebeforeInvocation = 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 falsebeforeInvocation = 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
delete
Check again
- 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
@Caching
The 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 value
or cacheNames
areemp
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