mybatis配置双数据源/多数据源的实践方式

 更新时间:2025年11月12日 09:03:24   作者:sayyy  
本文介绍了如何在Spring Boot项目中配置两个数据源,两个MyBatis实例,以及如何使用MyBatis Generator和PageHelper插件进行数据库操作和分页,通过配置多个数据源,可以实现对不同数据库的访问,同时,MyBatis Generator可以帮助快速生成MyBatis的Mapper和XML文件,提高开发效率

前言

  • 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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 浅析NIO系列之TCP

    浅析NIO系列之TCP

    NIO即同步非阻塞式IO,它和传统的BIO比较最大的区别在于在执行accept、connect、read、write操作时是非阻塞的。很有利于实现用少量线程来处理多个客户端请求,可以随时让线程切换所处理的客户端,从而可以实现高并发服务器的开发
    2021-06-06
  • 从零开始:快速入门SpringBoot注解的精髓

    从零开始:快速入门SpringBoot注解的精髓

    Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架,它通过使用注解来简化配置和开发过程,使开发人员能够更加专注于业务逻辑的实现,Spring Boot提供了许多注解,用于定义和配置应用程序的各个方面,需要的朋友可以参考下
    2023-10-10
  • SpringCloud之Config配置中心与Redis分布式锁详解

    SpringCloud之Config配置中心与Redis分布式锁详解

    这篇文章主要给大家介绍了SpringCloud Alibaba中Config配置中心,Redis分布式锁,文中有详细的代码示例供大家参考,需要的朋友可以参考阅读
    2023-05-05
  • MyBatisPlus自定义SQL的实现

    MyBatisPlus自定义SQL的实现

    MyBatisPlus提供了自定义SQL功能,允许开发者在Mapper接口中定义方法,并通过XML文件或注解编写SQL语句,本文详解了如何在MP中使用自定义SQL,感兴趣的可以了解一下
    2024-09-09
  • 浅谈java+内存分配及变量存储位置的区别

    浅谈java+内存分配及变量存储位置的区别

    下面小编就为大家带来一篇浅谈java+内存分配及变量存储位置的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • Spring IOC xml方式进行工厂Bean操作详解

    Spring IOC xml方式进行工厂Bean操作详解

    这篇文章主要介绍了Spring IOC xml方式进行工厂Bean操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • JPA如何使用entityManager执行SQL并指定返回类型

    JPA如何使用entityManager执行SQL并指定返回类型

    这篇文章主要介绍了JPA使用entityManager执行SQL并指定返回类型的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • dubbo http流量接入dubbo后端服务方式

    dubbo http流量接入dubbo后端服务方式

    Dubbo协议基于TCP,适用于后端高效RPC通信,但对前端不友好,可通过多协议发布或网关协议转换支持HTTP接入,主流网关如Higress、APISIX可实现协议转换和自动服务发现
    2025-10-10
  • Java 逻辑控制全面详解

    Java 逻辑控制全面详解

    程序的逻辑主要分为三种结构:顺序结构、分支结构、循环结构,顺序结构的所有的代码都是从前向后执行的。有些时候顺序是由“{}”为界限的,下文将全面详细的介绍
    2021-10-10
  • java 优雅关闭线程池的方案

    java 优雅关闭线程池的方案

    这篇文章主要介绍了java 优雅关闭线程池的方案,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-11-11

最新评论