1、注解
@CacheNamespace(flushInterval = 100000,eviction = LruCache.class,readWrite = false,size = 1024)
2、xml配置
<cache eviction= "LRU" flushInterval= "100000" readOnly= "true" size= "1024"/>
二级缓存,配置文件和接口注释是不能够配合使用的。只能通过全注解的方式才能够生效;
3、问题是以上两个不能同时使用,会报错
mybatis puls 同时使用sql和 QueryWrapper查询
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'baseDrugController': Unsatisfied dependency expressed through field 'baseDrugService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'baseDrugServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'baseDrugMapper' defined in file [D:\yuguang\DrugGuide\ruoyi-business\target\classes\com\ruoyi\drug\mapper\BaseDrugMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [com/baomidou/mybatisplus/autoconfigure/MybatisPlusAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:\yuguang\DrugGuide\ruoyi-business\target\classes\mapper\drug\DrugPurchaseDetailMapper.xml]'; nested exception is java.lang.IllegalArgumentException: Caches collection already contains value for com.ruoyi.drug.mapper.DrugPurchaseDetailMapper
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:659)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:453)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:343)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1359)
at com.ruoyi.RuoYiApplication.main(RuoYiApplication.java:21)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'baseDrugServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'baseDrugMapper' defined in file [D:\yuguang\DrugGuide\ruoyi-business\target\classes\com\ruoyi\drug\mapper\BaseDrugMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [com/baomidou/mybatisplus/autoconfigure/MybatisPlusAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:\yuguang\DrugGuide\ruoyi-business\target\classes\mapper\drug\DrugPurchaseDetailMapper.xml]'; nested exception is java.lang.IllegalArgumentException: Caches collection already contains value for com.ruoyi.drug.mapper.DrugPurchaseDetailMapper
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:659)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
4、解决办法
在mapper.xml中加上配置,然后再mapper接口加上注解
@CacheNamespaceRef(name = "com.ruoyi.drug.mapper.DrugPurchaseDetailMapper")
public interface DrugPurchaseDetailMapper extends BaseMapper<DrugPurchaseDetail> {
5、引用其他博客的解读细节
讲一下@CacheNamespace和@CacheNamespaceRef这俩注解的区别以及使用心得。
@CacheNamespace,作用于mapper接口上面,是用来实现二级缓存的,点击查看源码可以发现,东西也不多,主要讲的是缓存的实现类,如果不指定实现类的话,默认就是PerpetualCache(实际上就是hashmap实现的)
我们平常使用默认方式的的时候可以直接使用,如果使用自定义的方式,则需要指明实现类,如图 implementation = MybatisCache.class
这里讲一下存在的一个问题:当使用该注解的时候,你去查询的时候,使用到的查询能被缓存起来,但是,加入你这个查询SQL调用的是xml文件里面的,此时,是不会被缓存的,因为我们有时候会使用很多注解或者tk.mapper,这个时候是不会走xml,所以这个缓存我们用不上,此时存在一个解决方案,在xml文件里面也用上缓存,如下就代表开启使用缓存了,这个方式进行的话存在同上面类似的问题
这个存在的问题是xml里面走的SQL是可以被缓存的,但是你接口层的注解之类的SQL是不会被缓存,那有的人就说了,我把@CacheNamespace注解和cache标签一起使用不就行了嘛,但实际上是不行的。
那么如何同时去满足这个问题呢
@CacheNamespaceRef 来解决这个问题,也就是在接口上使用这个注解,把接口上的@CacheNamespace注解替换成@CacheNamespaceRef ,同时的话xml文件里面使用cache标签,
使用@CacheNamespaceRef注解要注意一点,要指明value或者name,如果不指明则会报错
org.apache.ibatis.builder.BuilderException: Should be specified either value() or name() attribute in the @CacheNamespaceRef
- 1
查看该注解源码,value就是当前类,name是你使用的Mapper接口的全限定名
使用如下三种方式:
顺便说一下,如果某个SQL不想被缓存,可以单独处理一下:
1、SQL走的是xml文件查询:配置useCache=“false”
2、SQL走的是注解形式:@Options(useCache=false)
如果你走的是xml,你在注解上使用这个注解,将不会起效
这些便是我对他俩的理解和使用过程