# multiple-datasource **Repository Path**: chenhu1001/multiple-datasource ## Basic Information - **Project Name**: multiple-datasource - **Description**: Spring Boot集成Mybatis实现多数据源支持 - **Primary Language**: Java - **License**: LGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2022-03-17 - **Last Updated**: 2025-01-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: Java ## README # multiple-datasource ## 1、背景   在实际项目开发过程中,时不时会遇到多数据源的情况,本文详细介绍下Spring Boot集成Mybatis实现多数据源支持。 ## 2、集成过程 ### 工程结构   首先代码工程结构如下: org.spring.springboot.config.datasource 包含了多数据源的配置,同样有第三个数据源,按照前几个复制即可;resources/mapper目录下面有两个模块,分别是 Mybatis 不同数据源需要扫描的mapper.xml 目录。 ```java ├── pom.xml └── src └── main ├── java │ └── com │ └── clang │ ├── Application.java │ ├── config │ │ └── datasource │ │ ├── ClusterDataSourceConfig.java │ │ └── MasterDataSourceConfig.java │ ├── controller │ │ └── UserRestController.java │ ├── dao │ │ ├── cluster │ │ │ └── CityDao.java │ │ └── master │ │ └── UserDao.java │ ├── domain │ │ ├── City.java │ │ └── User.java │ └── service │ ├── UserService.java │ └── impl │ └── UserServiceImpl.java └── resources ├── application.properties └── mapper ├── cluster │ └── CityMapper.xml └── master └── UserMapper.xml ``` ### pom.xml ```java 4.0.0 com.clang springboot-mybatis-mutil-datasource 0.0.1-SNAPSHOT jar springboot-mybatis-mutil-datasource Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 2.3.8.RELEASE UTF-8 UTF-8 1.8 2.1.4 8.0.11 1.1.24 org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis-spring-boot} mysql mysql-connector-java ${mysql-connector} com.alibaba druid ${druid} org.springframework.boot spring-boot-maven-plugin ``` ### 配置数据源 ```java ## master 数据源配置 master.datasource.url=jdbc:mysql://localhost:3306/db_master?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8 master.datasource.username=root master.datasource.password=root master.datasource.driverClassName=com.mysql.cj.jdbc.Driver ## cluster 数据源配置 cluster.datasource.url=jdbc:mysql://localhost:3306/db_cluster?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8 cluster.datasource.username=root cluster.datasource.password=root cluster.datasource.driverClassName=com.mysql.cj.jdbc.Driver ``` ### 多数据源配置类 ```java @Configuration // 扫描 Mapper 接口并容器管理 @MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory") public class MasterDataSourceConfig { // 精确到 master 目录,以便跟其他数据源隔离 static final String PACKAGE = "com.clang.dao.master"; static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml"; @Value("${master.datasource.url}") private String url; @Value("${master.datasource.username}") private String user; @Value("${master.datasource.password}") private String password; @Value("${master.datasource.driverClassName}") private String driverClass; @Bean(name = "masterDataSource") @Primary public DataSource masterDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClass); dataSource.setUrl(url); dataSource.setUsername(user); dataSource.setPassword(password); return dataSource; } @Bean @Primary public DataSourceTransactionManager masterTransactionManager() { return new DataSourceTransactionManager(masterDataSource()); } @Bean(name = "masterSqlSessionFactory") @Primary public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(masterDataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(MasterDataSourceConfig.MAPPER_LOCATION)); return sessionFactory.getObject(); } } ```   @Primary 标志这个 Bean 如果在多个同类 Bean 候选时,该 Bean 优先被考虑。「多数据源配置的时候注意,必须要有一个主数据源,用 @Primary 标志该 Bean」 @MapperScan 扫描 Mapper 接口并容器管理,包路径精确到 master,为了和下面 cluster 数据源做到精确区分 @Value 获取全局配置文件 application.properties 的 kv 配置,并自动装配 sqlSessionFactoryRef 表示定义了 key ,表示一个唯一 SqlSessionFactory 实例。   同理可得,从数据源 ClusterDataSourceConfig 配置如下: ```java @Configuration @MapperScan(basePackages = ClusterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "clusterSqlSessionFactory") public class ClusterDataSourceConfig { static final String PACKAGE = "com.clang.dao.cluster"; static final String MAPPER_LOCATION = "classpath:mapper/cluster/*.xml"; @Value("${cluster.datasource.url}") private String url; @Value("${cluster.datasource.username}") private String user; @Value("${cluster.datasource.password}") private String password; @Value("${cluster.datasource.driverClassName}") private String driverClass; @Bean(name = "clusterDataSource") public DataSource clusterDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClass); dataSource.setUrl(url); dataSource.setUsername(user); dataSource.setPassword(password); return dataSource; } @Bean(name = "clusterTransactionManager") public DataSourceTransactionManager clusterTransactionManager() { return new DataSourceTransactionManager(clusterDataSource()); } @Bean(name = "clusterSqlSessionFactory") public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("clusterDataSource") DataSource clusterDataSource) throws Exception { final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(clusterDataSource); sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(ClusterDataSourceConfig.MAPPER_LOCATION)); return sessionFactoryBean.getObject(); } } ```   上面数据配置分别扫描 Mapper 接口,com.clang.dao.master(对应 xml classpath:mapper/master ) 和 com.clang.dao.cluster(对应 xml classpath:mapper/cluster ) 包中对应的 UserDAO 和 CityDAO 。 都有 @Mapper 标志为 Mybatis 的并通过容器管理的 Bean。Mybatis 内部会使用反射机制运行去解析相应 SQL。