Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java spring@Cacheable如何使用dao调用在服务级别工作_Java_Spring_Spring Boot - Fatal编程技术网

Java spring@Cacheable如何使用dao调用在服务级别工作

Java spring@Cacheable如何使用dao调用在服务级别工作,java,spring,spring-boot,Java,Spring,Spring Boot,我有以下代码: @Service public class MyServiceImpl implements MyService { @Autowired private MyDao myDao; @Cacheable("callDao") @Override public MyResultModel callDao(MyCondition condition) { System.out.println("call without cac

我有以下代码:

@Service
public class MyServiceImpl implements MyService {
    @Autowired
    private MyDao myDao;

    @Cacheable("callDao")
    @Override
    public MyResultModel callDao(MyCondition condition) {
        System.out.println("call without cache");
        return myDao.call(condition);
    }

    @Cacheable("cacheTest")
    @Override
    public MyResultModel cacheTest(MyCondition condition) {
        System.out.println("call without cache");
        return new MyResultModel(someProperties);
    }
}
但是,
callDao
缓存不工作,因为该方法仍然一直调用数据库。另一方面,
cacheTest
工作正常。我的
callDao
方法有什么问题

以下是我的配置:

@Bean
public CacheManager cacheManager(RedisCacheManagerConfiguration configuration,
        @SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
    RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
    cacheManager.setDefaultExpiration(configuration.getDefaultExpiration());
    cacheManager.setUsePrefix(configuration.isUsePrefix());
    cacheManager.setLoadRemoteCachesOnStartup(configuration.isLoadRemoteCachesOnStartup());
    return cacheManager;
}

@Bean
public RedisTemplate<String, String> stringRedisTemplate(
        @Qualifier("stringRedisSerializer") RedisSerializer<String> keySerializer,
        @Qualifier("stringRedisSerializer") RedisSerializer<String> valueSerializer,
        @Qualifier("stringRedisSerializer") RedisSerializer<String> hashKeySerializer,
        @Qualifier("stringRedisSerializer") RedisSerializer<String> hashValueSerializer,
        JedisConnectionFactory connectionFactory) {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setKeySerializer(keySerializer);
    template.setValueSerializer(valueSerializer);
    template.setHashKeySerializer(hashKeySerializer);
    template.setHashValueSerializer(hashValueSerializer);
    template.setConnectionFactory(connectionFactory);
    template.afterPropertiesSet();

    return template;
}

@Bean(name = "stringRedisSerializer")
public StringRedisSerializer stringRedisSerializer() {
    return new StringRedisSerializer();
}
我是这样称呼这些方法的

@EnableCaching
@EnableAutoConfiguration
@ComponentScan({ "com.mypackage" })
@SpringBootApplication
public class Application extends ContextIdApplicationContextInitializer {
    public static ConfigurableApplicationContext ctx;

    public static void main(String[] args) throws Exception {
        ctx = SpringApplication.run(Application.class, args);

        MyService myService = ctx.getBean(MyService.class);

        for (int i = 0; i < 10; i++) {
            MyCondition condition = new ConditionForRideCard();
            condition.setGuid("adsgsfdhgsfgfdghhsdfgfadf");
            myService.callDao(condition);
            System.out.println("-------------------------------------------------------");
            myService.cacheTest(condition);
            System.out.println("=======================================================");
            Thread.sleep(1000);
        }
    }
}
正如所指出的(在他删除的答案中,需要10000个声誉才能看到)和评论中所指出的,您需要在
MyCondition
类中实现
equals()
hashCode()

Spring的缓存抽象通过基于参数缓存方法调用的结果来工作。在本例中,您只有一个参数(
MyCondition
)。但是,生成的密钥将使用参数的
hashCode()
实现

在您的例子中,您没有实现
equals()
hashCode()
,因此每次创建一个新的
MyCondition
对象时,它都会有一个不同的hashCode,因此Spring不会知道它缓存了结果


这并不能解释为什么
cacheTest()
方法确实有效。但我想这是因为我们现在没有看到代码(或者您使用了不同的条件,或者发生了其他情况)。

PS:我用redis配置缓存。可能是缓存配置的问题。谢谢你的帮助,我的配置已经发布了@DarkCan您可以显示MyCondition的代码吗?另外,如何调用
callDao
方法?您是从不同的类/服务调用它还是在同一个服务中调用它?在您的
MyCondition
类中实现
hashCode
equals
。非常感谢。我终于解决了我的问题。原因是,我在mybatis受体中修改了mycondition。然后更改redis键。因此,第二次调用无法命中缓存。
@EnableCaching
@EnableAutoConfiguration
@ComponentScan({ "com.mypackage" })
@SpringBootApplication
public class Application extends ContextIdApplicationContextInitializer {
    public static ConfigurableApplicationContext ctx;

    public static void main(String[] args) throws Exception {
        ctx = SpringApplication.run(Application.class, args);

        MyService myService = ctx.getBean(MyService.class);

        for (int i = 0; i < 10; i++) {
            MyCondition condition = new ConditionForRideCard();
            condition.setGuid("adsgsfdhgsfgfdghhsdfgfadf");
            myService.callDao(condition);
            System.out.println("-------------------------------------------------------");
            myService.cacheTest(condition);
            System.out.println("=======================================================");
            Thread.sleep(1000);
        }
    }
}
call without cache
-------------------------------------------------------
call without cache
=======================================================
call without cache
-------------------------------------------------------
=======================================================
call without cache
-------------------------------------------------------
=======================================================
call without cache
-------------------------------------------------------
=======================================================
call without cache
-------------------------------------------------------
=======================================================
call without cache
-------------------------------------------------------
=======================================================
call without cache
-------------------------------------------------------
=======================================================
call without cache
-------------------------------------------------------
=======================================================
call without cache
-------------------------------------------------------
=======================================================
call without cache
-------------------------------------------------------
=======================================================