Mybatis-plus和pagehelper引入的mybatis、mybatis-spring版本冲突导致ClassNotFoundException:org.mybatis.logging.LoggerFactory及自定义sqlSessionTemplate
背景情况: 当前项目是以前的老项目,使用SpringBoot+Jersey,它依赖公用工具模块,而该模块使用到了mybatis及mybatis-plus。依赖分析看下图。当然由于还引入了其他打包的依赖B,B又依赖C,C继承了父项目的PageHelper的starter依赖,但实际上C并不需要PageHelper,PageHelper的starter也依赖mybatis-spring-boot-starter。总的来说,只有common-utils是真正需要mybatis的,是由于有些依赖从父pom中继承了不需要的mybatis,这是我花了些时间做依赖分析得出的结论。
1. 解决版本冲突
出现启动项目时报ClassNotFoundException:org.mybatis.logging.LoggerFactory的问题多半是因为版本冲突,mybatis-plus中的类文件需要导入mybatis包下的这个类,但是mybatis包下现在没有。现在要么升级mybatis和对应的mybatis-spring,或者降低引入的mybatis-plus的版本,只要达到版本一致就行。我的版本mybatis3.4.6、mybatis-spring1.3.2,通过引入不同mybatis-plus的版本查看其依赖发现,mybatis-plus-boot-starter版3.1以下到3.0都是适配的,3.0以下没查看。
总结,根据需要升级mybatis、mybatis-spring版本,或者降级mybatis-plus版本,或者直接排除mybatis和mybatis-srping再引入mybatis-plus,只要达到版本适配兼容就行。mybatis-plus-boot-starter3.0-3.1 是适配mybatis3.4.6、mybatis-spring1.3.2的,其他未知。
2. 自定义SqlSession并指定sqlSessionTemplate
我先排除了无用的pagehelper,由于不敢通过排除mybatis、mybatis-spring在引入它们的高版本进行升级,我采用选择合适的mybatis-plus-boot-starter3.0.7.1。但是现在当前项目引入的common-utils工具包注入容器中的SqlSession进行数据库操作,并且当前老项目也自定义配置了SqlSessionFatoryBean并生成了SqlSession的实现类SqlSessionTemplate对象放在容器中。
以下是当前项目自定义配置的SqlSession
@Component
@EnableConfigurationProperties({ DatasourceConnInfo.class })
public class SqlSessionConfig {
//这里是自定义的数据源信息配置类
@Autowired
private DatasourceConnInfo connInfo;
@Bean
public SqlSessionTemplate sqlSession() throws Exception{
if(connInfo != null && connInfo.isEnable()) {
// 从数据源信息中创建 mybatis-spring包下SqlSessionFactoryBean对象
// 创建SqlSession的实现类SqlSessionTemplate对象放入容器中
SqlSessionFactoryBean sqlSessionFactory = MybatisSqlSessionFactoryBeanBuilder.build(connInfo);
return new SqlSessionTemplate(sqlSessionFactory.getObject());
}
return null;
}
}
这样就会导致mybatis-plus-boot-starter中的自动配置类的一些配置失效,不是自己所需。以下是它的自动配置内容:
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisPlusProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisPlusAutoConfiguration {
...
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception{...}
...
@Bean
@ConditionalOnMissingBean//失效
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {...}
}
因此,需要自动手动配置SqlSessionTemplate。当然还要检查DataSourceAutoConfiguration数据源的自动配置是否生效,是否是自己所需的数据源等,这里需要自己根据情况具体分析,总之保证在SqlSessionTemplate创建之前的配置是自己现在所需的,如数据源DataSourceAutoConfiguration、SqlSessionFactory等。
2.1 配置SqlSessionTemplate
其实就是从MybatisPlusAutoConfiguration中的copy复制一份。如下:
@Configuration
public class MyBatisPlusConfig {
...//copy一样的属性
// 我的情况是,自动配置类是生效的,可以不配置
@Bean(name = "mySqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {...}
@Bean(name = "myProjSqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(
@Autowired @Qualifier("mySqlSessionFactory")SqlSessionFactory sqlSessionFactory){...}
...
}
其他的不是spring-boot的情况也是同样的分析,分析容器中bean的情况,是否是当前所需,然后在做配置。
当然,根据情况,看看是否还需配置数据源,SqlSessionFactory等,方法也是一样,通过参考AutoConfiguration、Customer、Adopter等配置类,具体就是Spring-Boot如何配置的问题。
接着,在**@MapperScan中指定mapper接口的位置及指定容器中的SqlSessionTemplate**,也可以指定SqlSessionFactory。如下:
@MapperScan(basePackages = "com.xxx.xxx.xxx.dao",sqlSessionTemplateRef = "mySqlSessionTemplate")
public class XXXServiceApplication {
...
}
2.2 mybatis-plus的配置
接下来就可以在application.yml中配置mybatis的相关配置,具体可参考mybatis-plus的官网。
# 注意此处mybatis-plus是通过新的spring-datasource的数据源创建的sqlSession来注入mapper代理对象进行操作的
# 这样容器中就有两个SqlSession,互不干扰,各用个的
mybatis-plus:
mapper-locations:
- classpath:/mapper/**/mybatisplusmapper/*Dao.xml # 你的Mapper.xml文件的路径
- classpath:/mapper/**/mybatisplusmapper/*Mapper.xml
global-config:
db-config:
id-type: uuid
这样就配置使用自己的SqlSession,与依赖的包所需的SqlSession互不干扰,各自用自己的,各自扫描自己的mapper接口和mapper.xml文件。
参考:
1. 关于@MapperScan注解的一些问题:sqlSessionTemplateRef与sqlSessionFactoryRef
2. Springboot集成mybatis-plus报java.lang.ClassNotFoundException org.mybatis.logging.LoggerFactory解决
3. Spring boot 整合mybatis报错ClassNotFoundException: org.mybatis.logging.LoggerFactory