mybatis配置双数据源/多数据源的实践方式
作者:sayyy
前言
- spring boot 2.0.0.RELEASE
- maven 3.5
- eclipse 4.9.0
- mybatis 1.3.2
- mybatis generator 1.3.2
- pagehelper(mybatis 分页插件) 1.2.5
- oracle 12c
在spring boot项目中,使用mybatis操作数据库,很方便。经过亲测,比jpa好用。
mybatis提供了代码生成器mybatis generator。使用mybatis generator可以很方便的生成mybatis代码。
mybatis分页插件Mybatis-PageHelper,很好的解决了分页问题。
spring boot项目默认提供1个数据源,多个数据源时,需要手动进行一些处理,如下。
概念
- 数据源:javax.sql.DataSource类型。起到作为连接数据库的桥梁的作用。
- mybatis SessionFactory:org.apache.ibatis.session.SqlSessionFactory类型。mybatis通过该类获取数据源。
- Mybatis PageHelper:mybatis分页插件,通过该插件可以很方便的实现分页。
- mybatis generator:mybatis代码生成工具,通过该工具可以很方便的生成mybatis代码。
步骤简述
- 先配置2个数据源,分别连2个数据库。
- 再配置2个mybatis,使mybatis能够工作。
- 然后配置2个mybatis的分页插件,可以使用pagehelper处理分页。
- 最后,配置2个mybatis generator,能够生成2个mybatis的代码。
配置2个数据源
spring boot AutoConfigure提供的DataSourceAutoConfiguration类,自动配置数据源。因此,先禁用DataSourceAutoConfiguration类。
...
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class})
...
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
假设,要配置两个数据源,连接两个数据库,分别为db1、db2,需要做如下操作:
1,在application.properties配置文件中添加如下db1和db2的jdbc配置。
spring.datasource.db1.driverClassName =oracle.jdbc.OracleDriver spring.datasource.db1.jdbcUrl=jdbc:oracle:thin:@<db1 ip>/db1 spring.datasource.db1.username=xxx spring.datasource.db1.password=xxx spring.datasource.db1.platform=oracle spring.datasource.db2.driverClassName =oracle.jdbc.OracleDriver spring.datasource.db2.jdbcUrl=jdbc:oracle:thin:@<db2 ip>/db2 spring.datasource.db2.username=xxx spring.datasource.db2.password=xxx spring.datasource.db2.platform=oracle
2,添加db1数据源配置类PrimaryMybatisConfiguration,db2数据源配置类Db2MybatisConfiguration。
3,类PrimaryMybatisConfiguration中,添加db1 DataSourcebean。类Db2MybatisConfiguration中,添加db2 DataSourcebean。
- PrimaryMybatisConfiguration
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.db1")
@Primary
public DataSource dataSource() {
log.info("config primaryDataSource success.");
return DataSourceBuilder.create().build();
}
- Db2MybatisConfiguration
@Bean(name = "db2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.db2")
public DataSource dataSource() {
log.info("config db2DataSource success.");
return DataSourceBuilder.create().build();
}
至此,两个数据源(db1、db2),添加完成。
注:上面代码中,默认的数据源实现类:com.zaxxer.hikari.HikariDataSource。
配置2个mybatis
mybatis spring boot AutoConfigure提供的MybatisAutoConfiguration类,自动配置Mybatis。因此,先禁用MybatisAutoConfiguration类。
...
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
MybatisAutoConfiguration.class})
...
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
假设,要配置两个mybatis,分别使用db1数据源、db2数据源,需要做如下操作:
1,在application.properties配置文件中添加如下2个mybatis配置和对应的@Configuration类。
- 使用db1数据源的mybatis的配置文件
spring.datasource.db1.extend.mybatisMapperLocations=classpath:config/mybatis/mapper/*.xml
- 使用db1数据源的mybatis的@Configuration类
...
@Configuration
@ConfigurationProperties(prefix = "spring.datasource.db1.extend")
public class PrimaryMybatisProperties {
private String mybatisMapperLocations;
...
}
- 使用db2数据源的mybatis的配置文件
spring.datasource.db2.extend.mybatisMapperLocations=classpath:config/mybatis/mapper2/*.xml
- 使用db2数据源的mybatis的@Configuration类
...
@Configuration
@ConfigurationProperties(prefix = "spring.datasource.db2.extend")
public class Db2MybatisProperties {
private String mybatisMapperLocations;
...
}
2,配置2个mybatis的SqlSessionFactory
- PrimaryMybatisConfiguration
@Configuration
@MapperScan(basePackages = { "xxx.db.mapper" },sqlSessionFactoryRef="primarySqlSessionFactory")
public class PrimaryMybatisConfiguration {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private PrimaryMybatisProperties property;
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.db1")
@Primary
public DataSource dataSource() {
log.info("config primaryDataSource success.");
return DataSourceBuilder.create().build();
}
@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(
@Qualifier("primaryDataSource") DataSource dataSource) {
try {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(this.property.getMybatisMapperLocations()));
log.info("config primarySqlSessionFactory success.");
return sessionFactory.getObject();
} catch (Exception e) {
log.error("config primarySqlSessionFactory failure.", e);
return null;
}
}
@Bean(name = "primarySqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "primaryTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(
@Qualifier("primaryDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
- Db2MybatisConfiguration
@Configuration
@MapperScan(basePackages = { "xxx.db2.mapper" },sqlSessionFactoryRef="db2SqlSessionFactory")
public class Db2MybatisConfiguration {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private Db2MybatisProperties property;
@Bean(name = "db2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.db2")
public DataSource dataSource() {
log.info("config db2DataSource success.");
return DataSourceBuilder.create().build();
}
@Bean(name = "db2SqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
@Qualifier("db2DataSource") DataSource dataSource) {
try {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(this.property.getMybatisMapperLocations()));
log.info("config db2SqlSessionFactory success.");
return sessionFactory.getObject();
} catch (Exception e) {
log.error("config db2SqlSessionFactory failure.", e);
return null;
}
}
@Bean(name = "db2SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "db2TransactionManager")
public DataSourceTransactionManager transactionManager(
@Qualifier("db2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
至此,2个mybatis的SqlSessionFactory已配置完成。此时,2个mybatis已经可以工作。接下来需要配置分页插件。
配置2个mybatis的分页插件
pagehelper spring boot AutoConfigure提供的PageHelperAutoConfiguration类,自动配置Mybatis的分页插件。因此,先禁用PageHelperAutoConfiguration类。
...
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
MybatisAutoConfiguration.class,
PageHelperAutoConfiguration.class })
...
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
假设,要配置两个mybatis的分页插件,需要做如下操作:
1,在application.properties配置文件中添加如下2个mybatis分页插件的配置和对应的@Configuration类。
- 使用db1数据源的mybatis分页插件的配置文件
spring.datasource.db1.extend.pagehelperDialect=Oracle spring.datasource.db1.extend.pagehelperReasonable=true spring.datasource.db1.extend.pagehelperSupportMethodsArguments=true spring.datasource.db1.extend.pagehelperOffsetAsPageNum=true spring.datasource.db1.extend.pagehelperRowBoundsWithCount=true spring.datasource.db1.extend.pagehelperParams=count=countSql;pageNum=pageNumKey;pageSize=pageSizeKey;
- 使用db1数据源的mybatis分页插件的@Configuration类
...
@Configuration
@ConfigurationProperties(prefix = "spring.datasource.db1.extend")
public class PrimaryMybatisProperties {
private String mybatisMapperLocations;
private String pagehelperDialect;
private String pagehelperReasonable;
private String pagehelperSupportMethodsArguments;
private String pagehelperParams;
private String pagehelperOffsetAsPageNum;
private String pagehelperRowBoundsWithCount;
...
}
- 使用db2数据源的mybatis分页插件的配置文件
spring.datasource.db2.extend.pagehelperDialect=Oracle spring.datasource.db2.extend.pagehelperReasonable=true spring.datasource.db2.extend.pagehelperSupportMethodsArguments=true spring.datasource.db2.extend.pagehelperOffsetAsPageNum=true spring.datasource.db2.extend.pagehelperRowBoundsWithCount=true spring.datasource.db2.extend.pagehelperParams=count=countSql;pageNum=pageNumKey;pageSize=pageSizeKey;
- 使用db2数据源的mybatis分页插件的@Configuration类
...
@Configuration
@ConfigurationProperties(prefix = "spring.datasource.db2.extend")
public class Db2MybatisProperties {
private String mybatisMapperLocations;
private String pagehelperDialect;
private String pagehelperReasonable;
private String pagehelperSupportMethodsArguments;
private String pagehelperParams;
private String pagehelperOffsetAsPageNum;
private String pagehelperRowBoundsWithCount;
...
}
2,配置2个mybatis的SqlSessionFactory,增加分页插件
- PrimaryMybatisConfiguration
@Configuration
@MapperScan(basePackages = { "xxx.db.mapper" },sqlSessionFactoryRef="primarySqlSessionFactory")
public class PrimaryMybatisConfiguration {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private PrimaryMybatisProperties property;
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.db1")
@Primary
public DataSource dataSource() {
log.info("config primaryDataSource success.");
return DataSourceBuilder.create().build();
}
@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(
@Qualifier("primaryDataSource") DataSource dataSource) {
try {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(this.property.getMybatisMapperLocations()));
//分页插件
Interceptor interceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect", this.property.getPagehelperDialect());
properties.setProperty("reasonable", this.property.getPagehelperReasonable());
properties.setProperty("supportMethodsArguments",this.property.getPagehelperSupportMethodsArguments());
properties.setProperty("params",this.property.getPagehelperParams());
interceptor.setProperties(properties);
sessionFactory.setPlugins(new Interceptor[] {interceptor});
log.info("config primarySqlSessionFactory success.");
return sessionFactory.getObject();
} catch (Exception e) {
log.error("config primarySqlSessionFactory failure.", e);
return null;
}
}
@Bean(name = "primarySqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "primaryTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(
@Qualifier("primaryDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
- Db2MybatisConfiguration
@Configuration
@MapperScan(basePackages = { "xxx.db2.mapper" },sqlSessionFactoryRef="db2SqlSessionFactory")
public class Db2MybatisConfiguration {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private Db2MybatisProperties property;
@Bean(name = "db2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.db2")
public DataSource dataSource() {
log.info("config db2DataSource success.");
return DataSourceBuilder.create().build();
}
@Bean(name = "db2SqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
@Qualifier("db2DataSource") DataSource dataSource) {
try {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(this.property.getMybatisMapperLocations()));
//分页插件
Interceptor interceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect", this.property.getPagehelperDialect());
properties.setProperty("reasonable", this.property.getPagehelperReasonable());
properties.setProperty("supportMethodsArguments",this.property.getPagehelperSupportMethodsArguments());
properties.setProperty("params",this.property.getPagehelperParams());
interceptor.setProperties(properties);
sessionFactory.setPlugins(new Interceptor[] {interceptor});
log.info("config db2SqlSessionFactory success.");
return sessionFactory.getObject();
} catch (Exception e) {
log.error("config db2SqlSessionFactory failure.", e);
return null;
}
}
@Bean(name = "db2SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "db2TransactionManager")
public DataSourceTransactionManager transactionManager(
@Qualifier("db2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
配置2个mybatis generator
1,在pom.xml中引入mybatis generator
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> ... <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- mybatis generator 自动生成代码插件 --> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> <dependencies> <dependency> <groupId>com.oracle.jdbc</groupId> <artifactId>ojdbc7</artifactId> <version>12.1.0.1</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
2, 配置2个mybatis generator配置文件。
- 使用db1数据源的mybatis generator的配置文件generatorConfig.xml.
- 使用db1数据源的mybatis generator的配置文件generatorConfig2.xml.
3,使用mvn执行mybatis generator命令。
- 使用db1数据源的mybatis generator生成代码命令
mvn -Dmybatis.generator.configurationFile=src/main/resources/generatorConfig.xml mybatis-generator:generate
- 使用db2数据源的mybatis generator生成代码命令
mvn -Dmybatis.generator.configurationFile=src/main/resources/generatorConfig2.xml mybatis-generator:generate
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
