MyBatis-Plus多数据源支持
通过 MyBatis-Plus 的多数据源支持,开发者可以轻松实现读写分离业务模块分离以及其他复杂的多数据源场景。通过简单的注解配置,动态数据源切换变得十分灵活和高效。
在现代企业应用中,常常需要与多个数据库交互,比如分布式数据库、读写分离、业务拆分等场景。MyBatis-Plus 作为 MyBatis 的增强工具,支持多数据源的集成,可以帮助开发者轻松管理和切换多个数据库连接。
一、MyBatis-Plus 多数据源的使用场景
- 业务拆分:不同业务模块使用不同的数据库,比如用户信息存储在一个数据库,订单信息存储在另一个数据库。
- 读写分离:通过主从数据库配置,将写操作指向主库,读操作指向从库。
- 分布式数据库:不同的数据库实例存储不同的数据,通过路由规则选择不同的数据源。
二、MyBatis-Plus 多数据源的实现原理
MyBatis-Plus 多数据源的实现依赖于 Spring 框架的多数据源支持。通过为不同的数据源配置独立的 DataSource
和 SqlSessionFactory
,实现多个数据库连接的管理。结合 DynamicDataSource
,可以根据业务需求动态切换数据源。
三、配置步骤
1. 引入依赖
首先,确保项目中已经引入了 MyBatis-Plus 和相关的数据库驱动。以 MySQL 为例,可以在 pom.xml
文件中引入以下依赖:
<dependencies>
<!-- MyBatis-Plus Starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- MySQL 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
2. 配置多数据源
在 application.yml
中配置多个数据源。这里我们配置两个 MySQL 数据源,分别为 master
和 slave
数据源,模拟读写分离的场景。
spring:
datasource:
master:
url: jdbc:mysql://localhost:3306/master_db?useSSL=false&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
url: jdbc:mysql://localhost:3306/slave_db?useSSL=false&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
mapper-locations: classpath:mapper/**/*.xml
type-aliases-package: com.example.demo.model
master
:主库,处理写操作。slave
:从库,处理读操作。
3. 配置数据源 DataSource
接下来,我们为 master
和 slave
数据源分别配置 DataSource
。创建一个 DataSourceConfig
类,定义不同的数据源和动态数据源的切换。
package com.example.demo.config;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.YmlDynamicDataSourceProvider;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
// 主数据源 master
@Bean(name = "masterDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
// 从数据源 slave
@Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
// 动态数据源
@Bean
public DynamicDataSourceProvider dynamicDataSourceProvider() {
return new YmlDynamicDataSourceProvider();
}
}
4. 配置 DynamicDataSource
实现动态数据源切换
使用 MyBatis-Plus 提供的 @DS
注解,可以很方便地实现数据源的动态切换。在 @Service
层或者 @Mapper
层,通过 @DS
注解来指定不同的数据源。
package com.example.demo.service;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// 使用主库(master)进行操作
@DS("master")
public void saveUser(User user) {
userMapper.insert(user);
}
// 使用从库(slave)进行查询
@DS("slave")
public List<User> getAllUsers() {
return userMapper.selectList(null);
}
}
@DS("master")
:表示该方法将使用master
数据源。@DS("slave")
:表示该方法将使用slave
数据源。
在这个例子中,saveUser()
方法使用主库 master
进行写操作,getAllUsers()
方法使用从库 slave
进行查询。
5. 创建 Mapper
接口
与单一数据源的配置类似,我们需要创建 Mapper 接口用于数据库的操作。这里使用 MyBatis-Plus 的 BaseMapper
接口来进行 CRUD 操作。
package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
6. 测试多数据源切换
编写 UserController
来测试多数据源的读写分离。
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
// 保存用户(写操作,使用主库)
@PostMapping
public String saveUser(@RequestBody User user) {
userService.saveUser(user);
return "用户保存成功";
}
// 查询所有用户(读操作,使用从库)
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
}
POST /users
:调用saveUser()
方法,使用主库master
进行写操作。GET /users
:调用getAllUsers()
方法,使用从库slave
进行查询操作。
四、常见场景
1. 读写分离
在实际应用中,常见的多数据源场景是 读写分离。写操作指向主库,而读操作指向从库。通过 MyBatis-Plus 提供的动态数据源切换,开发者只需在代码中标注 @DS("master")
和 @DS("slave")
,就能轻松实现读写分离。
例如:
- 插入数据时使用
master
数据源:@DS("master") public void insertData(User user) { userMapper.insert(user); }
- 查询数据时使用
slave
数据源:@DS("slave") public List<User> selectAllUsers() { return userMapper.selectList(null); }
2. 不同业务模块使用不同数据库
在某些系统中,不同的业务模块会使用不同的数据库,例如用户模块和订单模块分别使用不同的数据源。这时我们可以通过 @DS
注解为不同的业务模块配置不同的数据源。
例如:
- 用户模块使用
user_db
数据源:@DS("user_db") public User findUserById(Long id) { return userMapper.selectById(id); }
- 订单模块使用
order_db
数据源:@DS("order_db") public Order findOrderById(Long id) { return orderMapper.selectById(id); }
3. 动态切换数据源
MyBatis-Plus 支持基于业务逻辑或其他条件动态切换数据源。例如,可以根据用户的地理位置选择不同的数据库进行查询。
public User getUserBasedOnRegion(String region, Long id) {
if ("US".equals(region)) {
return userService.findUserById(id); // 使用 US 数据源
} else {
return userService.findUserByIdInOtherRegion(id); // 使用其他数据源
}
}
五、注意事项
- 数据源的一致性:在使用多数据源时,需要考虑数据的一致性问题,特别是在
涉及事务的场景下。
2. 事务管理:MyBatis-Plus 结合 Spring 的事务管理可以实现跨数据源的事务控制,但需要特别注意不同数据源之间的事务隔离。
3. 性能优化:合理使用从库可以减轻主库的压力,但要确保从库的数据及时同步,避免读到不一致的数据。
六、总结
通过 MyBatis-Plus 的多数据源支持,开发者可以轻松实现 读写分离、业务模块分离 以及其他复杂的多数据源场景。通过简单的注解配置,动态数据源切换变得十分灵活和高效。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)