1. 项目结构
src
├── main
│ ├── java
│ │ └── org
│ │ └── songtang
│ │ └── springbootdynamic
│ │ ├── config
│ │ ├── controller
│ │ ├── entity
│ │ ├── mapper
│ │ │ ├── master
│ │ │ └── slave
│ │ └── service
│ └── resources
│ └── mapper
│ ├── master
│ └── slave
└── test
pom配置
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/>
</parent>
<groupId>org.songtang</groupId>
<artifactId>springboot-dynamic</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
<mysql.version>8.4.0</mysql.version>
<mybatisplus.version>3.5.7</mybatisplus.version>
</properties>
<dependencies>
<!-- SpringBoot相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatisplus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!--mysql 数据库相关-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
</project>
2. 数据源配置类 (DataSourceConfig
)
此类用于配置多个数据源,并将其分别标记为 Primary
和 Secondary
,以便在需要时进行区分。
package org.songtang.springbootdynamic.config;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Primary
@Bean(name = "mainDateSource")
@ConfigurationProperties(prefix = "spring.datasource.main")
public DataSource mainDateSource(){
return DataSourceBuilder.create().build();
}
@Bean(name = "targetDateSource")
@ConfigurationProperties(prefix = "spring.datasource.target")
public DataSource targetDateSource(){
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "mainSessionFactory")
public SqlSessionFactory mainSessionFactory(@Qualifier("mainDateSource")DataSource dataSource) throws Exception{
MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
mybatisSqlSessionFactoryBean.setDataSource(dataSource);
mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/master/*.xml"));
return mybatisSqlSessionFactoryBean.getObject();
}
@Bean(name = "targetSessionFactory")
public SqlSessionFactory SessionFactory(@Qualifier("targetDateSource")DataSource dataSource) throws Exception{
MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/slave/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean(name = "mainTransactionManager")
public DataSourceTransactionManager mainTransactionManager(@Qualifier("mainDateSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "targetTransactionManager")
public DataSourceTransactionManager targetTransactionManager(@Qualifier("targetDateSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
3. 数据源映射配置类
MasterMapperConfig
和 SlaveMapperConfig
分别配置主数据源和从数据源的 Mapper
。
主数据源配置 (MasterMapperConfig
)
package org.songtang.springbootdynamic.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan(basePackages = "org.songtang.springbootdynamic.mapper.master", sqlSessionFactoryRef = "mainSessionFactory")
public class MasterMapperConfig {
}
从数据源配置 (SlaveMapperConfig
)
package org.songtang.springbootdynamic.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan(basePackages = "org.songtang.springbootdynamic.mapper.slave", sqlSessionFactoryRef = "targetSessionFactory")
public class SlaveMapperConfig {
}
4. 实体类 (Member
)
Member
实体类用于表示数据库中的成员数据,并与 master
和 slave
两个数据源交互。
package org.songtang.springbootdynamic.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@TableName("member")
@Data
public class Member extends BaseEntity{
private String name;
private String phone;
private Double amount;
}
5. Mapper 接口
Mapper 接口用于定义与数据库交互的方法。
主数据源 Mapper (MasterMapper
)
package org.songtang.springbootdynamic.mapper.master;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.songtang.springbootdynamic.entity.Member;
@Mapper
public interface MasterMapper extends BaseMapper<Member> {
// 主数据源相关操作
}
从数据源 Mapper (SlaveMapper
)
package org.songtang.springbootdynamic.mapper.slave;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.songtang.springbootdynamic.entity.Member;
@Mapper
public interface SlaveMapper extends BaseMapper<Member> {
// 从数据源相关操作
}
6. 控制器 (Controller
)
控制器类用于定义对外暴露的 API 接口,用于操作不同数据源的数据。
package org.songtang.springbootdynamic.controller;
import org.songtang.springbootdynamic.entity.Member;
import org.songtang.springbootdynamic.service.YourService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api")
public class MultiDataSourceController {
@Autowired
private YourService yourService;
// 使用主数据源插入数据
@PostMapping("/master")
public void addMasterEntity(@RequestBody Member masterEntity) {
yourService.addMaster(masterEntity);
}
// 使用从数据源插入数据
@PostMapping("/slave")
public void addSlaveEntity(@RequestBody Member slaveEntity) {
yourService.addSlave(slaveEntity);
}
}
7. 使用示例
在项目中,可以通过调用控制器的 API 来测试不同数据源的功能:
- 插入主数据源的数据: 通过
/api/master
接口插入数据 - 插入从数据源的数据: 通过
/api/slave
接口插入数据
8. application.yml
配置
application.yml
文件中需要配置主数据源和从数据源的连接信息:
spring:
datasource:
main:
url: jdbc:mysql://localhost:3306/masterdb
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
target:
url: jdbc:mysql://localhost:3306/slavedb
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
总结
通过以上配置,您可以在 Spring Boot 项目中成功实现多数据源的管理,分离不同的数据库操作。这样可以轻松处理不同数据源之间的事务以及数据交互,确保应用的高效性和可扩展性。