最近首次在真实项目中,实践用SpingBoot整合 Mybatis、MybatisPlus、Spring、多数据源等常见SSH整合问题。
遇到一个难题,MybatisPlus遇到了经典的问题“Statement not bound”。
如果是Mybatis,很容易解决,扫描到Mapper接口文件和Mapper.xml文件,肯定能搞定。
这次整合进了MybatisPlus,之前了解过但是对运作原理不太熟悉。
百度了好几次,官网文档查看了记下,花了6个小时,都没能找到解决办法。
第2天早上,在最后2种可疑问题,与另外一个同事交流了下。
参考他们项目的配置,整合Mybatis MybatisPlus DataSource,没问题。
2个项目对比下,大概率确认是 多数据源导致的 MybatisPlus没有配置成功。
但这只是表象,参考MybatisPlus官网多数据源配置,也不行。
另外,如果是多数据源的问题,最有可能是运行的时候,数据库没切换成功,但不可能是Mapper没有绑定成功。
因此,最终结论是 原项目中的 数据源配置和 别人的配置不同。
最后,换了种思路搜索,搜索 DataSource、SqlSessionFactory等配置,然后搜到了几篇文字,基本确认就是这个配置问题了。
也和MybatisPlus作者聊了下,说这种配置,需要自己找办法,所以,其他网友遇到的问题,可能和我是一样的。
使用Mybatis-Plus时的SqlSessionFactory的问题
spring boot集成mybatis-plus遇到的问题及解决
主要参考了以上2篇文章搞定的。
------------------------------------
先说明,原理还没搞懂。
大概原因是,MybatisPlus需要用自己的 MybatisSqlSessionFactoryBean,用SqlSessionFactory 可能有问题。
MybatisSqlSessionFactoryBean可以设置各种配置。
pom.xml配置,可能有多的
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>hibernate-validator</artifactId>
<groupId>org.hibernate</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-autoconfigure</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
入口
@Slf4j
@SpringBootApplication
@ServletComponentScan
@EnableScheduling
public class JtnApplication {
}
数据源配置,特意把 Mybatis和MybatisPlus配置分开,方便维护复用
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import com.alibaba.druid.pool.DruidDataSourceFactory;
@Configuration
@ComponentScan(basePackages="com.j.common.web.crud.manager.content")
public class JtnConfig {
@Autowired
private Environment env;
@Bean(name = "dataSource")
public DataSource getDataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", env.getProperty("spring.datasource.driverClassName"));
props.put("url", env.getProperty("spring.datasource.url"));
props.put("username", env.getProperty("spring.datasource.username"));
props.put("password", env.getProperty("spring.datasource.password"));
return DruidDataSourceFactory.createDataSource(props);
}
}
MybaitsPlus核心配置
@Configuration
@MapperScan(basePackages = "com.j.common.web.crud.mapper.content")
public class MybatisPlusConfig {
@Autowired
private DataSource dataSource;
@Autowired
private MybatisPlusProperties properties;
@Autowired
private ResourceLoader resourceLoader = new DefaultResourceLoader();
@Autowired(required = false)
private Interceptor[] interceptors;
@Autowired(required = false)
private DatabaseIdProvider databaseIdProvider;
/**
* mybatis-plus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor page = new PaginationInterceptor();
page.setDialectType("mysql");
return page;
}
/**
* 这里全部使用mybatis-autoconfigure 已经自动加载的资源。不手动指定 配置文件和mybatis-boot的配置文件同步
*
* @return
* @throws IOException
*/
@Bean
public MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean() throws IOException {
MybatisSqlSessionFactoryBean mybatisPlus = new MybatisSqlSessionFactoryBean();
mybatisPlus.setDataSource(dataSource);
mybatisPlus.setVfs(SpringBootVFS.class);
String configLocation = this.properties.getConfigLocation();
if (StringUtils.isNotBlank(configLocation)) {
mybatisPlus.setConfigLocation(this.resourceLoader.getResource(configLocation));
}
mybatisPlus.setConfiguration(properties.getConfiguration());
mybatisPlus.setPlugins(this.interceptors);
MybatisConfiguration mc = new MybatisConfiguration();
mc.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
mc.setMapUnderscoreToCamelCase(false);// 数据库和java都是驼峰,就不需要
mybatisPlus.setConfiguration(mc);
if (this.databaseIdProvider != null) {
mybatisPlus.setDatabaseIdProvider(this.databaseIdProvider);
}
mybatisPlus.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
mybatisPlus.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
mybatisPlus.setMapperLocations(this.properties.resolveMapperLocations());
// 设置mapper.xml文件的路径
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resource = resolver.getResources("classpath:mapper/*.xml");
mybatisPlus.setMapperLocations(resource);
return mybatisPlus;
}
}
在解决的过程中,还遇到若干其它问题。
1.运行总是提示缺包,各种问题。
当天晚上,花了2个小时都没搞定。
第2天,没办法了,重新导入Eclipse,屁事豆没。
经常遇到类似Maven环境问题,在当时的环境下,非常不服气,但是不服气不行啊,知道你服气未知。
第2天重新导入,完全ok,这种不是一次两次了,只可惜每次哥都不服气。
2. MybatisPlus可以支持 把数据库 user_name自动 匹配到 java属性userName.
mc.setMapUnderscoreToCamelCase(true);
但是自己的习惯,mysql 数据库字段全部驼峰命名,MybatisPlus需要手动设置
mc.setMapUnderscoreToCamelCase(false);// 数据库和java都是驼峰,就不需要
3. 之前项目有问题,考虑过 jar包冲突,jar包损坏等各种场景,最终确认都不是。
4. MybatisPlus最早是2.x,后来有了3.x,网上资料不少是2.x的,需要注意。
现有项目用2.x,打算直接用3.x,搞起来,免得总是再升级重构。
5. 用了SpringBoot,mysql驱动貌似升级了。
现在都用这个了, com.mysql.cj.jdbc.Driver。 但是这个名字没以前的简短额。
对于以上自己的配置,都是“仅供参考”,可能还有更简单的办法。
作为初学者,能跑起来,今后用多了,再简化。
一些配置
dev.yml
spring:
application:
name: 11
aop:
proxy-target-class: true
datasource:
url: jdbc:mysql://rm-111.mysql.rds.11.com:3306/b2c?autoReconnect=true&characterEncoding=UTF-8
driverClassName: com.mysql.cj.jdbc.Driver
username: root
password: 11
# 配置了没起作用
mybatis-plus:
configuration:
mapUnderscoreToCamelCase: false
以上是自己解决问题的过程和初步结果,花了大概6小时+2小时+2小时。
后续,在项目中配置 MybatisPlus3.x,再把另外一个项目的MybatisPlus2.x代码迁移整合进现有项目。
最后,未来打算全面使用MybatisPlus3.x,自己比较喜欢 API方式的 crud工具。
Mybatis代码自动生成sql mapper.xml和mapper接口也还行,就是增加修改字段费事一些。
后来又用JFinal封装了一套 CRUD,还可以。
但是有了 MybatisPlus,对比下 生态和长远发展,JFinal对我来说,价值降低了。
最大问题是,专注一套 技术栈,比多套技术栈,维护合作各方面都好很多。
参考资料
使用Mybatis-Plus时的SqlSessionFactory的问题
spring boot集成mybatis-plus遇到的问题及解决
辅助参考资料
MybatisPlus官网
https://mp.baomidou.com/guide/faq.html
Spring Boot MyBatis 通用Mapper插件集成 good
mybatis支持属性使用驼峰的命名
Mybatis Plus的分页插件简介