springboot整合mybatis,取消一级缓存

it2024-12-28  8

前段时间开发过程中碰到了因为mybatis一级缓存导致对象被重复添加到list的问题,在此记录一下

 

参考博客:https://www.cnblogs.com/happyflyingpig/p/7739749.html

                  https://blog.csdn.net/j7636579/article/details/73647885

 

项目场景:

因为mybatis一级缓存导致对象被重复添加到list


问题描述:

对象A--约束条件,

对象B--需要查询出的对象

  Date date = new Date();

   List<A>  as = new ArrayList<A>();

   A a = new A();

   a.setDate(date);

   a.setProductId(1);

  ....

  

   A a1 = new A();

   a1.setDate(date);

   a1.setProductId(1);

   ....

   as.add(a);//a和a1的属性一致

   as.add(a1);

   List<B> result = new ArrayList<B>();

   int i = 0;

   for(A a : as) {

        //对象A的属性查询B的约束条件,呈现的sql select * from B where date< a.date and  productId = a.productId;         B date= Bservice.selectB(a);//由于两次查询条件一致,若开启一级缓存,会导致第二次查询返回的是第一次的结果集,对象引用也和第一次一致

//第一次返回 B ={id=1,name=2,...,count=1}             date.setCount(i++);//对查出的对象属性赋值             result .add(date);                 }     //result 输出后 [{id=1,name=2,...,count=2},{id=1,name=2,...,count=2}]

        Class A{         Date date;         int productId;         .....     }          Class B{         int id;         String name;         Date date;         int productId;

        int count;         .....     }


原因分析:

开启一级缓存后,查询条件不变,sqlSession 不变,查询返回的结果集也不变,导致了两次查出的对象是同一个


解决方案:

关闭一级缓存,自己尝试了不少方法包括在mapper文件中配置 flushCache="true" useCache="false" ,springboot配置关闭一级缓存---都无效

还有就是调用SqlSession.clearCache(),这种自己没有尝试过

 

直接在整合mybatis的代码中设置LocalCacheScope属性

@Component @Configuration public class MmsMybatisConfig {         //注入WmfDataSourceConfig中配置的ComboPooledDataSource是c2p0的实现标准     @Autowired     private DataSource dataSource;         private static Logger logger = LoggerFactory.getLogger (MmsMybatisConfig.class);

    @Bean(name = "sqlSessionFactory.cms")     public SqlSessionFactoryBean sqlSessionFactoryBeanGwcmp() {                           SqlSessionFactoryBean bean = new SqlSessionFactoryBean ();         bean.setDataSource (dataSource);         /**          * 关闭一级缓存          */         org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();         configuration.setLocalCacheScope(LocalCacheScope.STATEMENT);         bean.setConfiguration(configuration);         /**          * <array>          * </array>          */         PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver ();         String[] path = new String[] {"classpath*:mapper/*.xml","classpath*:com/aspire/boc/settle/*dao/*mapper/*.xml"};         List<Resource> arrayList = new ArrayList<> ();         try {             for (String s : path ) {                 List<Resource> asList = Arrays.asList (resolver.getResources (s));                 arrayList.addAll (asList);             }         }         catch (IOException e ) {             throw new RuntimeException (e);         }         bean.setMapperLocations (arrayList.toArray (new Resource[arrayList.size ()]));         try {              logger.info ("bean creat success Mapper [{}]",arrayList.size ());             return bean;         }         catch (Exception e ) {             logger.info ("bean creat error!");             e.printStackTrace ();             throw new RuntimeException (e);         }                      }

}

 

最新回复(0)