SpringBoot-Guide项目:SpringBoot+MyBatis多数据源配置实战
springboot-guide SpringBoot2.0+从入门到实战! 项目地址: https://gitcode.com/gh_mirrors/sp/springboot-guide
前言
在实际企业级应用开发中,随着业务规模的增长,单数据源往往难以满足需求。我们可能需要同时连接多个数据库,或者将不同业务模块的数据分散到不同的数据源中。本文将基于SpringBoot-Guide项目,详细介绍如何在SpringBoot中整合MyBatis实现多数据源配置。
一、环境准备
1.1 技术栈选择
- 开发工具:IntelliJ IDEA
- 构建工具:Maven
- Java版本:JDK 8
- 框架版本:
- Spring Boot 2.1.0+
- MyBatis 3.5.6+
- 数据库:MySQL 5.7+
注意:Spring Boot 2.0+版本在数据源配置上与1.x版本有差异,本文会特别指出这些变化。
1.2 数据库准备
我们需要准备两个数据库,分别命名为erp
和erp2
,并在每个数据库中创建两张表:
用户表(user)结构:
CREATE TABLE `user` (
`id` int(13) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(33) DEFAULT NULL COMMENT '姓名',
`age` int(3) DEFAULT NULL COMMENT '年龄',
`money` double DEFAULT NULL COMMENT '账户余额',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
工资表(money)结构:
CREATE TABLE `money` (
`id` int(33) NOT NULL AUTO_INCREMENT COMMENT '主键',
`basic` int(33) DEFAULT NULL COMMENT '基本工资',
`reward` int(33) DEFAULT NULL COMMENT '奖金',
`punishment` int(33) DEFAULT NULL COMMENT '惩罚金',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
二、项目配置
2.1 Maven依赖配置
在pom.xml中添加必要的依赖:
<dependencies>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis Spring Boot Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring Boot Test Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2.2 多数据源配置
在application.properties中配置两个数据源:
# 应用端口
server.port=8335
# 数据源1配置
spring.datasource.hikari.db1.jdbc-url=jdbc:mysql://localhost:3306/erp?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.hikari.db1.username=root
spring.datasource.hikari.db1.password=yourpassword
spring.datasource.hikari.db1.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源2配置
spring.datasource.hikari.db2.jdbc-url=jdbc:mysql://localhost:3306/erp2?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.hikari.db2.username=root
spring.datasource.hikari.db2.password=yourpassword
spring.datasource.hikari.db2.driver-class-name=com.mysql.cj.jdbc.Driver
重要提示:Spring Boot 2.0+版本必须使用
spring.datasource.hikari.jdbc-url
而非1.x版本的spring.datasource.url
,否则会报错。
三、核心实现
3.1 数据源配置类
我们需要为每个数据源创建独立的配置类:
数据源1配置类:
@Configuration
@MapperScan(basePackages = "com.example.db1.dao",
sqlSessionTemplateRef = "db1SqlSessionTemplate")
public class DataSource1Config {
@Bean(name = "db1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.hikari.db1")
@Primary
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db1SqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(
@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "db1TransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(
@Qualifier("db1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "db1SqlSessionTemplate")
@Primary
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
数据源2配置类:
@Configuration
@MapperScan(basePackages = "com.example.db2.dao",
sqlSessionTemplateRef = "db2SqlSessionTemplate")
public class DataSource2Config {
@Bean(name = "db2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.hikari.db2")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db2SqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
@Qualifier("db2DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "db2TransactionManager")
public DataSourceTransactionManager transactionManager(
@Qualifier("db2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "db2SqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
关键点说明:
@Primary
注解标记默认数据源@MapperScan
指定每个数据源对应的DAO包路径- 每个数据源需要独立的
SqlSessionFactory
和TransactionManager
3.2 实体类定义
用户实体(User.java):
public class User {
private Integer id;
private String name;
private Integer age;
private Double money;
// 省略getter/setter和toString方法
}
工资实体(Money.java):
public class Money {
private Integer id;
private Integer basic;
private Integer reward;
private Integer punishment;
// 省略getter/setter和toString方法
}
3.3 DAO层实现
数据源1的UserDao:
@Qualifier("db1SqlSessionTemplate")
public interface UserDao {
@Select("SELECT * FROM user WHERE name = #{name}")
User findUserByName(String name);
}
数据源2的MoneyDao:
@Qualifier("db2SqlSessionTemplate")
public interface MoneyDao {
@Select("SELECT * FROM money WHERE id = #{id}")
Money findMoneyById(@Param("id") int id);
}
3.4 Service层实现
UserService:
@Service
public class UserService {
@Autowired
private UserDao userDao;
public User selectUserByName(String name) {
return userDao.findUserByName(name);
}
}
MoneyService:
@Service
public class MoneyService {
@Autowired
private MoneyDao moneyDao;
public Money selectMoneyById(int id) {
return moneyDao.findMoneyById(id);
}
}
3.5 Controller层实现
UserController:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/query")
public User testQuery() {
return userService.selectUserByName("张三");
}
}
MoneyController:
@RestController
@RequestMapping("/money")
public class MoneyController {
@Autowired
private MoneyService moneyService;
@GetMapping("/query")
public Money testQuery() {
return moneyService.selectMoneyById(1);
}
}
四、启动与测试
4.1 启动类
@SpringBootApplication
public class MultiDataSourceApplication {
public static void main(String[] args) {
SpringApplication.run(MultiDataSourceApplication.class, args);
}
}
4.2 测试验证
启动应用后,可以通过以下方式测试:
- 访问
http://localhost:8335/user/query
测试数据源1 - 访问
http://localhost:8335/money/query
测试数据源2
五、常见问题与解决方案
-
数据源配置问题:
- 错误:
jdbcUrl is required with driverClassName
- 解决:确保使用
spring.datasource.hikari.jdbc-url
而非旧版的spring.datasource.url
- 错误:
-
事务管理问题:
- 在多数据源环境下,跨数据源的事务需要使用分布式事务解决方案如JTA
-
连接池配置:
- 可以为每个数据源单独配置连接池参数,如:
spring.datasource.hikari.db1.maximum-pool-size=20 spring.datasource.hikari.db1.minimum-idle=5
- 可以为每个数据源单独配置连接池参数,如:
六、总结
本文详细介绍了在SpringBoot项目中配置MyBatis多数据源的完整流程,关键点包括:
- 正确配置application.properties中的多数据源参数
- 为每个数据源创建独立的配置类
- 使用@Primary注解标记默认数据源
- 为不同数据源的DAO指定不同的SqlSessionTemplate
- 注意Spring Boot 2.0+版本的数据源配置变化
通过这种配置方式,我们可以轻松实现多数据源的访问,为复杂业务场景下的数据库拆分和扩展提供了基础支持。
springboot-guide SpringBoot2.0+从入门到实战! 项目地址: https://gitcode.com/gh_mirrors/sp/springboot-guide
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考