1. Conceito
- Cache: interface de cache, que define a operação de cache
@EnableCaching
: Ativa o modo de cacheCacheManager
: Gerenciador de cache, gerencie vários componentes de cache@Cacheable
: Antes do método, geralmente é usado antes de consultar o método de operação de um determinado id, de modo que se você verificar o ID na próxima vez, o método não será executado e o resultado será retirado diretamente do cache@CacheEvict
: Limpe o cache, geralmente usado antes do método de exclusão de um determinado ID@CachePut
: Certifique-se de que o método seja chamado e espere que o resultado seja armazenado em cache, antes de usar o método atualizado
Dois, crie um projeto
Esteja preparado primeiro, importe os itens básicos
spring-boot-mycache-Preparation (chinês removido)
Banco de dados: 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, há mais uma
service
camada aqui , que pode ser entendida como algo entre Mapeador e Controlador, que é mais padronizado
Terceiro, o uso inicial do 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 antes de chamar o método . Existem muitos atributos opcionais dentro, existem vários atributos abaixo
cacheNames/value
: Especifique o nome do componente do cache; em qual cache colocar o resultado de retorno do método é uma matriz, e vários caches podem ser especificados;key
: A chave usada para dados em cache; você pode usá-la para especificar. O padrão é usar o valor do parâmetro do método 1 - o valor de retorno do método, escreva SpEL; #id; O valor do parâmetro id # a0 # p0 # root.args [0], getEmp [2]keyGenerator
: Gerador de chave; você mesmo pode especificar o id do componente do gerador de chavekey/keyGenerator
: Escolha um para usar;cacheManager
: Especifique o gerenciador de cache; ou cacheResolver para especificar o resolvedorcondition
: Cache apenas quando as condições especificadas forem atendidas; por exemplocondition = "#id>0"
: Cache apenas quando o valor do primeiro parâmetro> 1unless
: Cache negativo; quando a condição especificada por except for verdadeira, o valor de retorno do método não será armazenado em cache; o resultado pode ser obtido para julgamento. Por exemplounless = "#result == null"
: se o resultado estiver vazio, ele não será salvo.unless = "#a0==2"
: Se o valor do primeiro parâmetro for 2, o resultado não é armazenado em cache;sync
: Se deve usar o modo assíncrono
A seguir está o formato de SpEL, @Cacheable
que é o formato no qual as propriedades podem ser escritas, mas não @Cacheable
pode ser usado #result
, porque é inútil retornar o resultado, que @Cacheable
é executado antes que o método seja executado. A
anotação também é adicionada na frente da classe SpringBootMycacheApplication para @EnableCaching
habilitar o mecanismo de cache
Quando inserimos http://localhost:8080/emp/1
, quando
você pressiona o arquivo do console várias @EnableCaching
vezes, o console não aparecerá novamente e não aparecerá novamente, porque foi salvo no cache, o Java irá chamar automaticamente o conteúdo do cache em vez do método Call
Quatro, simplesmente fale sobre o princípio
1) Use CacheManager [ConcurrentMapCacheManager] para obter o componente Cache [ConcurrentMapCache] de acordo com o nome
2) A chave é gerada usando keyGenerator, e o padrão é SimpleKeyGenerator.
Eu não entendo. . .
Cinco, atributos
1 、 key / keyGenerator
key
: A chave usada para dados em cache; você pode usá-la para especificar. O padrão é usar o valor do parâmetro do método 1 - o valor de retorno do método, escreva SpEL; #id; O valor do parâmetro id # a0 # p0 # root.args [0], getEmp [2]keyGenerator
: Gerador de chave; você mesmo pode especificar o id do componente do gerador de chavekey/keyGenerator
: Escolha um para usar;
Por exemplo, se estivermos visitando http://localhost:8080/emp/1
, o id é 1, então a chave padrão é 1
.
Mas se a @Cacheable(cacheNames = {"emp"},key = "#root.methodName+'['+#id+']'")
chave for 方法名[id]
, por exemplo, o id é 1, então a chave é getEmp[1]
(porque nossa @Cacheable
anotação é colocada na frente do método, e a chave é o atributo)
Para keyGenerator, escreva uma classe e use-a, não sei como. . . .
@Cacheable(cacheNames = {
"emp"},key = "#root.methodName+'['+#id+']'")
public Employee getEmp(Integer id){
System.out.println("查询"+id+"号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
2 、 condição / a menos
Por exemplo condition = "#id>2"
: quando id> 2, este método é adicionado ao cache
condition = "#a0>1"
: quando o valor do primeiro parâmetro> 1, ele é adicionado ao cache, a0
que se refere ao primeiro parâmetro
unless = "#a0>1"
: este é o inverso, quando o primeiro parâmetro Quando um parâmetro> 1, não entre no cache
Seis, @CachePut
Este comentário é geralmente usado para escrever antes da atualização.
Etapas de execução: Após executar o método, chame a anotação.
Primeiro, complete o código para
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;
}
É também algo que o serviço chama de camada Mapeador, e então a camada controladora é responsável por solicitar e retornar valores
1. Análise
@CachePut
: Não apenas chama o método, mas também atualiza os dados do cache; atualiza o cache de forma síncrona- Modifique alguns dados no banco de dados e atualize o cache ao mesmo tempo;
- Quando correr:
- 1. Chame o método de destino primeiro
- 2. Armazene em cache os resultados do método de destino
De acordo com o código-fonte, podemos saber que as coisas são armazenadas em cache de acordo com o nome (chave) ao armazenar em cache. Por exemplo id=1
, se verificarmos , essa chave é 1
se a @CachePut
chave de atributo não está escrita nela, então, de acordo com a update()
função , a chave é employee
, uma chave é 1
e a outra chave é employee
, As duas chaves são diferentes, nenhuma ligação de cache é executada e o cache não pode ser modificado.
- É porque a chave é diferente ou não é usada quando é atualizada,
@CachePut
apenas a exibe na página da web, mas não será devolvida ao banco de dados.
2. A maneira correta de atualizar o cache:
@CachePut
Adicione o atributo key = "#result.id"
ou key = "#employee.id"
, então a chave padrão não será usada como parâmetro, mas se tornará #result.id
ou #employee.id
. O primeiro significa que a chave é o id do resultado do método, porque o resultado retornado é funcionário e o atributo é id. Por exemplo, se nosso novo id for 1, essa chave também será alterada em 1
vez de employee
, e o o resultado deste último é o mesmo de antes.
Observe que o item acima foi key = "#root.methodName+'['+#id+']'"
excluído, caso contrário, o ID é diferente e o experimento não será possível
@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;
}
Para estes dois, o nome do cache operacional é chamado emp. Então, no emp, as duas chaves devem ser as mesmas para a operação normal.
Primeiro consulte
e depois modifique.
Console:
Mas o banco de dados:
Embora não seja exibido na página da web! ! ! ! ! O cache foi alterado, o banco de dados também foi alterado, isso é um fato! ! ! ! !
3. Basta usá-lo no futuro
No futuro, se você quiser armazenar em cache, consultar @Cacheable(value = {"xxx"})
e atualizar a mesma coisa novamente @CachePut(value = {"xxx"},key = "#result.yyy")
, o primeiro parâmetro de consulta é um atributo de objeto, então yyy é o atributo do objeto e o parâmetro de consulta
Sete, @CacheEvict: limpeza de cache
@CacheEvict
:
Camada de serviço de limpeza de cache
@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
Propriedades em:
key
: Especifique os dados a serem apagadosallEntries = true
: Especifique para limpar todos os dados neste cache, o padrão é falsobeforeInvocation = false
: A limpeza do cache é realizada após o método? True é executado após o método e false é executado antes do método. , O padrão representa que a operação de limpeza do cache é executada após o método ser executado; se ocorrer uma exceção, o cache não será limpo, o padrão é falsobeforeInvocation = true
: Indica que a operação de limpeza do cache é executada antes da execução do método. O cache será limpo independentemente de o método ser anormal ou não. O padrão é falso
Verificar e
excluir
Verifique novamente
- Ele é exibido no console novamente, porque a exclusão excluiu o cache e não há cache.Quando você verificar novamente, você só pode chamar o método e chamar o banco de dados. Se você verificar novamente neste momento, o cache é chamado
Oito, @Caching e @CacheConfig
@Caching
O código-fonte:
public @interface Caching {
Cacheable[] cacheable() default {
};
CachePut[] put() default {
};
CacheEvict[] evict() default {
};
}
Esta é uma combinação complexa de mecanismo de cache, que pode ser escrita como
// @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);
}
- Ou seja, esta única anotação usa tantas anotações em cache (na verdade, ela pode ser usada separadamente)
@CacheConfig
: //
exemplo de configuração comum de buffer de extração @CacheConfig(cacheNames="emp")
, usado na frente da classe, mostra todo o cache da classe value
ou cacheNames
sãoemp
Nove, redis
Isso é uma coisa muito poderosa. O Baidu diz que pode armazenar algo em cache.
Infelizmente, não vou, esqueça, vou aprender mais tarde e vou usá-lo quando encontrar um emprego. . . Muito para aprender