有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么@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());
}

迈巴蒂斯地图绘制器

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);
    }
}

邮递员发出了邮寄请求,然后得到以下结果:

@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在mapper中使用

总是从数据库获取员工数据。 @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);

}

为什么?他们的区别是什么


共 (1) 个答案

  1. # 1 楼答案

    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管理的bean中添加Spring注释将不会导致任何应用。它不会缓存Employee,而是缓存更新计数(返回值int),以Employee作为键,而不是值