A, JSR107
Java Caching defines five core interface:
- CachingProvider defines the creation, configuration, acquisition, management control what more CacheingManageer, an application can access multiple CachingProvider at runtime.
- CachingManager defines the creation, configuration, acquisition, management control what more uniquely named Cache, Cache write this exists in the context CacheManager, one CacheManager only a CacheProvider owned.
- Cache is a data structure similar to the Map and temporarily stores the value of the index key is not, a cache only have a CacheManager
- Entry is key-value pairs stored in each of the Cache.
- Expiry stored in each of the Cache entry has a defined period, once over this time, the state entry has not expired. Once expired, the entry ginger inaccessible, update, and delete. The cache is valid through ExpiryPolicy.
Second, the comment cache
Cache | Cache interface, defined cache operation is implemented by: RedisCache, EhCacheCahe, ConcurrentMapCache |
---|---|
CacheManager | Cache Manager, manage the cache (Cache) assemblies |
@Cacheable | The main methods for configuration, it is possible according to the results of its cache request parameter method |
@CacheEvict | Empty the cache |
@CachePut | Ensure the method is called, and hope results are cached |
@EnableCaching | Open annotation-based caching |
keyGenerator | When the comment cache key generation strategy |
serialize | Cache data value when serialization strategy |
1、@Cacheable
- cacheNames / values : Specifies the name cache component, the method will return the results in the cache is an array, you can specify multiple cache
- Key : caching data used key, it can be specified, the default is to use the value of the parameter
For example: 1- methods return values may be used SpEL expressions #id; parameter value id # a0 # p0 # root.args [0]
- keyGenerator : key generator, the key may specify their own generator component id key / keyGenerator: using a second election
- CacheManager / cacheResolver : Specifies the cache manager; or obtain a parser is used to specify cacheResolver
- for condition Condition : the case of specified qualifying only cache
- unless : Negative cache, unless specified when the condition is true, the return value will not be cached, the determination result can be acquired
- Sync : whether to use asynchronous mode
Running processes:
@Cacheable:
-
Before running the method, go to the query Cache (cache component), acquired in accordance with the specified name cacheNames, (CacheManagerz first obtain the corresponding cache), if not first obtain the cache Cache component automatically created
-
Find Cache to cache content, the use of a key, is the default method parameters, key is generated according to a certain strategy; default is to use keyGenerator generated,
-
Not found in the cache is called the target method
-
The results returned by the target method, into the cache
SpringEL expression:
first name | position | description | Examples |
---|---|---|---|
methodName | root object | The current method is called name | #root.methodName |
method | root object | The current method is called | #root.method.name |
target | root object | The current target object has been called | #root.target |
targetClass | root object | The current target object class is called | #root.targetClass |
args | root object | Parameter list is called the current method | #root.args[0] |
caches | root object | Current methods used to invoke a cache list (e.g. @Cacheable (value = { "cache1", "cache2"})), there are two cache | #root.caches[0].name |
argument name | evaluation context | Name parameter can be directly # method parameter name, also p0 form or can use # # a0, 0 represents the index parameters; | #iban, # a0, # p0 |
result | evaluation context | The return value after execution of the method (determination only after the implementation of an effective method, such as 'unless', 'cache put' expression 'cache evict' expression beforeInvocation = false) | #result |
@Cacheable(cacheNames = {"emp"}/*, keyGenerator = "myKeyGenerator"*/)
public Employee getEmp(Integer id){
System.out.println("查询"+id+"号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
2、@CachePut
Run timing:
1, the first call to the target method
2, the target method of cached results
/**
* @Description: 既调用方法,又更新缓存
* 先调用方法,然后将结果进行缓存
* key = "#employee.id"
* key = "#result.id" 返回值的id
* 更新和查询用的key必须一致
*/
@CachePut(value = "emp",/*key = "#employee.id"*/key = "#result.id")
public Employee updateEmp(Employee employee){
employeeMapper.updateEmp(employee);
return employee;
}
3 @ CacheEvict
Clear the cache, you can delete the specified key
//allEntries:默认为false,为true时,指定清楚这个缓存中所有的数据
//beforeInvocation:缓存的清除是否在方法之前执行
/**
* @Description:@CacheEvict清除缓存
*/
@CacheEvict(value = "emp",key = "#id")
public void deleteEmp(Integer id){
employeeMapper.deleteEmpById(id);
}
4.@Caching
包含上面三个注解,适合复杂规则使用
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
例如:
//复杂规则使用
@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);
}
5 @ CacheConfig
指定公共属性
@CacheConfig(cacheNames = "emp")
@Service
public class EmployeeService {
The specified key Component Builder:
@Bean("myKeyGenerator")
public KeyGenerator keyGenerator(){
return new KeyGenerator(){
@Override
public Object generate(Object o, Method method, Object... objects) {
return method.getName()+"["+ Arrays.asList(objects).toString()+"]";
}
};
}s
Third, as a buffer integrated redis
pom.xml file to add:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
- Redis introduction of starter, the storage container is RedisCacheManager
- RedisCacheManager as a buffer components to create RedisCache
- Kv is the default save data object, use serialization to save
@SpringBootTest
class Springboot01CacheApplicationTests {
@Autowired
EmployeeMapper employeeMapper;
@Autowired
StringRedisTemplate stringRedisTemplate;
@Autowired
RedisTemplate redisTemplate;
@Autowired
RedisTemplate<Object,Employee> employeeRedisTemplate;
/*
*Redis常见五种数据类型: String、List、Set、Hash(散列)、ZSet(有序集合)
*stringRedisTemplate.opsForValue()操作String;
*stringRedisTemplate.opsForList()操作List;
* stringRedisTemplate.opsForSet()操作Set;
* stringRedisTemplate.opsForHash()操作Hash;
* stringRedisTemplate.opsForZSet()操作Zset;
*/
@Test
public void test01(){
// stringRedisTemplate.opsForValue().append("msg","hello");
stringRedisTemplate.opsForList().leftPush("myList","1");
stringRedisTemplate.opsForList().leftPush("myList","2");
String msg = stringRedisTemplate.opsForValue().get("msg");
System.out.println("msg = " + msg);
// stringRedisTemplate.opsForList();
// stringRedisTemplate.opsForSet();
// stringRedisTemplate.opsForHash();
// stringRedisTemplate.opsForZSet();
// System.out.println("=========");
}
@Test
public void test02(){
Employee emp = employeeMapper.getEmpById(1);
employeeRedisTemplate.opsForValue().set("emp-01",emp);
}
@Test
void contextLoads() {
Employee emp = employeeMapper.getEmpById(1);
}
}
Custom cachemanager serialized to json
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory){
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
RedisCacheManager build = RedisCacheManager.builder(factory).cacheDefaults(configuration).build();
return build;
}
Gets the cache and add cache
@Autowired
CacheManager cacheManager;
@Cacheable(cacheNames = "dept")
public Department getDeptById(Integer id){
System.out.println("查询部门" + id);
Department dept = departmentMapper.getDeptByid(id);
Cache dept1 = cacheManager.getCache("dept");
dept1.put("dept1",dept);
return dept;
}