文章目录
-
- [1. 环境准备](#1. 环境准备)
- [2. 创建Spring Boot项目](#2. 创建Spring Boot项目)
- [3. 添加依赖](#3. 添加依赖)
- [4. 配置多数据源](#4. 配置多数据源)
- [5. 配置MyBatis-Plus](#5. 配置MyBatis-Plus)
- [6. 使用多数据源](#6. 使用多数据源)
- [7. 创建Mapper接口](#7. 创建Mapper接口)
- [8. 实体类定义](#8. 实体类定义)
- [9. 测试多数据源](#9. 测试多数据源)
- [10. 注意事项](#10. 注意事项)
-
- [10.1 事务导致多数据源失效问题](#10.1 事务导致多数据源失效问题)
- [10.2 ClickHouse的事务支持](#10.2 ClickHouse的事务支持)
- [10.3 数据源切换的性能开销](#10.3 数据源切换的性能开销)
- [10.4 数据源配置的优先级](#10.4 数据源配置的优先级)
- [11. 总结](#11. 总结)
使用Spring Boot 3.x + MyBatis-Plus + MySQL 8.0 + ClickHouse 24 实现多数据源配置
在现代的应用程序开发中,使用多个数据源已经成为一种常见的需求。例如,我们可能需要在同一个应用中使用MySQL作为主数据库,同时使用ClickHouse来处理大量的分析数据。本文将介绍如何使用Spring Boot 3.x、MyBatis-Plus、MySQL 8.0和ClickHouse 24,结合dynamic-datasource-spring-boot-starter
实现多数据源配置。
1. 环境准备
在开始之前,确保你已经准备好以下环境:
- JDK 17 或更高版本
- Spring Boot 3.x
- MySQL 8.0
- ClickHouse 24
- Maven 或 Gradle
2. 创建Spring Boot项目
首先,创建一个新的Spring Boot项目。你可以使用Spring Initializr来生成项目骨架,选择以下依赖:
- Spring Web
- MyBatis Framework
- MySQL Driver
- ClickHouse Driver
3. 添加依赖
在pom.xml
中添加以下依赖:
xml
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.0.0</springBoot>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- MySQL Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- ClickHouse JDBC driver -->
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.3.2</version>
</dependency>
<!-- Dynamic Datasource -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
</dependencies>
4. 配置多数据源
在application.yml
中配置MySQL和ClickHouse的数据源:
yaml
spring:
datasource:
dynamic:
primary: master # 设置默认的数据源
strict: false # 是否严格匹配数据源,不严格匹配时,找不到对应数据源会使用默认数据源
datasource:
master:
url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&connectTimeout=30000&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
dw:
url: jdbc:clickhouse://localhost:8123/mzdb?timezone=Asia/Shanghai&socket_timeout=600000&connect_timeout=60000
username: default
password:
driver-class-name: com.clickhouse.jdbc.ClickHouseDriver
5. 配置MyBatis-Plus
在Spring Boot中配置MyBatis-Plus,确保它能够支持多数据源。
java
@Configuration
@MapperScan("com.example.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
6. 使用多数据源
在代码中使用@DS
注解来指定使用哪个数据源。@DS
注解可以放在类或方法上。
@DS
注解可以使用在mapper接口上,也可以使用在方法上,也可以使用在Service类上,取决于业务中需要实现的作用域
java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List<User> getUsers() {
return userMapper.selectList(null);
}
@DS("clickhouse") // 切换为clickhouse数据源
public List<DwOperationRecordMapper> getAnalyticsData() {
return analyticsMapper.selectList(null);
}
}
7. 创建Mapper接口
创建对应的Mapper接口,并使用@Mapper
注解标记。
java
/**
* 主数据源
*/
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
}
/**
* 副数据源
*/
@Mapper
@DS("dw") //切换为clickhouse数据源
public interface DwOperationRecordMapper extends BaseMapper<DwOperationRecord> {
}
8. 实体类定义
定义对应的实体类,并使用@TableName
注解指定表名。
java
/**
* 主数据源
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "sys_user")
public class SysUser {
//账号状态_启用
public final static Integer FORBIDDEN = 0;
@TableId(type = IdType.AUTO)
private Long id;
@Schema(description = "姓名")
private String name;
@Schema(description = "密码")
private String password;
@Schema(description = "账号名")
private String userName;
@Schema(description = "手机号")
private String phone;
}
/**
* 副数据源
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@TableName("DWS_OPERATION_RECORD")
public class DwOperationRecord implements Serializable {
/**
* 手术记录id
*/
@TableField(value = "surgical_id",exist = false)
@Schema(description = "手术记录id")
private String surgicalId;
/**
* 病案号
*/
@Schema(description ="病案号")
private String patientid;
/**
* 姓名
*/
@Schema(description ="姓名")
private String name;
/**
* 性别
*/
@Schema(description ="性别")
private String sex;
}
9. 测试多数据源
编写测试类,验证多数据源是否正常工作。
java
@SpringBootTest
public class MultiDataSourceTest {
@Autowired
private UserService userService;
@Test
public void testMySQLDataSource() {
List<SysUser> users = userService.getUsers();
Assert.notEmpty(users, "MySQL数据源查询失败");
}
@Test
public void testClickHouseDataSource() {
List<DwOperationRecord> list = userService.list();
Assert.notEmpty(list, "ClickHouse数据源查询失败");
}
}
10. 注意事项
10.1 事务导致多数据源失效问题
在使用多数据源时,如果开启了事务(@Transactional
),可能会导致数据源切换失效。这是因为Spring的事务管理机制默认会绑定一个数据源,事务开启后不会动态切换数据源。
解决方案:
-
禁用事务
如果业务场景允许,可以在切换数据源的方法上禁用事务:
java@DS("dw") @Transactional(rollbackFor = SQLException.class, propagation = Propagation.NOT_SUPPORTED) // 禁用事务 public List<DwOperationRecord> getDwOperationRecord() { return dwOperationRecordMapper.selectList(null); }
-
使用
@DSTransactional
注解
dynamic-datasource-spring-boot-starter
提供了@DSTransactional
注解,支持多数据源事务管理。需要在主数据源上开启事务,其他数据源不支持事务。java@Transactional(rollbackFor = SQLException.class) // 主数据源事务 public void updateUserAndLog(SysUser user) { userMapper.updateById(user); logToClickhouse(user); // 切换到ClickHouse } @DS("clickhouse") public void logToClickhouse(SysUser user) { dwOperationRecordMapper.insert(new DwOperationRecord(user.getId(), "UPDATE", LocalDateTime.now())); }
-
手动控制事务
如果必须使用事务,可以手动控制事务的提交和回滚:
java@Autowired private DataSourceTransactionManager transactionManager; // 默认使用主数据源 public void updateUserAndLog(SysUser user) { DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(definition); try { userMapper.updateById(user); logToClickhouse(user); // 切换到ClickHouse transactionManager.commit(status); } catch (Exception e) { transactionManager.rollback(status); throw e; } }
10.2 ClickHouse的事务支持
ClickHouse本身不支持事务(ACID),因此在使用ClickHouse时,无法使用事务管理。如果需要保证数据一致性,可以通过业务逻辑或补偿机制来实现。
10.3 数据源切换的性能开销
频繁切换数据源可能会带来一定的性能开销,尤其是在高并发场景下。建议尽量减少数据源切换的次数,或者通过缓存机制优化数据访问。
10.4 数据源配置的优先级
如果同时配置了spring.datasource.url
和dynamic-datasource
,dynamic-datasource
会覆盖默认的spring.datasource
配置。确保只使用一种配置方式,避免冲突。
11. 总结
通过以上步骤,我们成功地在Spring Boot 3.x项目中配置了MySQL和ClickHouse的多数据源,并使用MyBatis-Plus进行数据操作。dynamic-datasource-spring-boot-starter
使得多数据源的切换变得非常简单,只需通过@DS
注解即可轻松切换数据源。
在实际项目中,多数据源的配置可能会更加复杂,例如涉及到事务管理、读写分离等。但通过本文的介绍,你已经掌握了基本的配置方法,可以根据实际需求进行扩展和优化。
注意事项:
- 事务管理在多数据源场景下需要特别处理,避免数据源切换失效。
- ClickHouse不支持事务,需通过业务逻辑保证数据一致性。
- 尽量减少数据源切换的频率,优化性能。
希望本文对你有所帮助,祝你在使用Spring Boot开发多数据源应用时顺利!