为什么@Cacheable在控制器和接口中使用时不起作用



springboot 1.5

@EnableCaching(proxyTargetClass = true)
@SpringBootApplication
@MapperScan(value = {"com.spring15.mapper", "com.spring15.cache.mapper"})
public class LearnMainApplication {
public static void main(String[] args){
SpringApplication.run(LearnMainApplication.class,args);
}
}

控制器

@PostMapping("/emp/get")
//@Cacheable(cacheNames = "employee", key = "#id", condition = "#id>0", unless = "#result == null")
public Employee getEmp(@RequestBody Employee employee){
logger.info("====== get ======");
return cacheService.getEmp(employee.getId());
}

mybatis映射器

public interface EmployeeMapper {
@Select("select * from employee where id = #{id}")
Employee getEmployeeById(Integer id);
//@CachePut(cacheNames = "employee")
@Update("update employee set id = #{id}, lastName = #{lastName}, email = #{email}, dId = #{dId}, gender = #{gender} where id = #{id}")
int updateEmp(Employee employee);
//@CacheEvict(cacheNames = "employee")
@Delete("delete from employee where id = #{id}")
int deleteEmp(Integer id);
//@Cacheable(cacheNames = "employee")
@Insert("insert into employee(lastName, email, dId, gender) values(#{lastName}, #{email}, #{dId}, #{gender})")
int insertEmp(Employee employee);
}

服务

@Service
// @CacheConfig(cacheNames ="employee")
public class CacheService {
@Autowired
EmployeeMapper employeeMapper;
//@Cacheable(cacheNames = "employee", key = "#id", condition = "#id>0", unless = "#result == null")
public Employee getEmp(Integer id){
return employeeMapper.getEmployeeById(id);
}
}

Postman发送邮件请求后得到以下结果:

@Cacheable在服务中的应用

第二次从缓存中获取员工的数据。

@Service
// @CacheConfig(cacheNames ="employee")
public class CacheService {
@Autowired
EmployeeMapper employeeMapper;
@Cacheable(cacheNames = "employee", key = "#id", condition = "#id>0", unless = "#result == null")
public Employee getEmp(Integer id){
return employeeMapper.getEmployeeById(id);
}
}

@Cacheable在控制器中的应用

总是从数据库中获取员工的数据。@Cacheable不起作用。

@PostMapping("/emp/get")
@Cacheable(cacheNames = "employee", key = "#id", condition = "#id>0", unless = "#result == null")
public Employee getEmp(@RequestBody Employee employee){
logger.info("====== get ======");
return cacheService.getEmp(employee.getId());
}

@Cacheable在映射器中的应用

总是从数据库中获取员工的数据。@Cacheable不起作用。

public interface EmployeeMapper {
@Cacheable(cacheNames = "employee", key = "#a0", condition = "#id>0", unless = "#result == null")
@Select("select * from employee where id = #{id}")
Employee getEmployeeById(Integer id);
//@CachePut(cacheNames = "employee")
@Update("update employee set id = #{id}, lastName = #{lastName}, email = #{email}, dId = #{dId}, gender = #{gender} where id = #{id}")
int updateEmp(Employee employee);
//@CacheEvict(cacheNames = "employee")
@Delete("delete from employee where id = #{id}")
int deleteEmp(Integer id);
//@Cacheable(cacheNames = "employee")
@Insert("insert into employee(lastName, email, dId, gender) values(#{lastName}, #{email}, #{dId}, #{gender})")
int insertEmp(Employee employee);
}

为什么?他们有什么不同?

public Employee getEmp(@RequestBody Employee employee){
logger.info("====== get ======");
return cacheService.getEmp(employee.getId());
}

对于控制器,方法签名不包含id作为参数,因此@Cacheable将无法工作,因为缺少缓存密钥。它有一个Employee作为参数,而不是int id。因此,缓存密钥应该是#employee.id才能使用正确的缓存密钥。

MyBatis映射程序不是由Spring管理的,而是由MyBatis管理的,将Spring Annotations添加到非Spring管理的bean将不会导致任何应用。它将以Employee为密钥而不是值来缓存更新计数(int返回值(,而不是缓存Employee

最新更新