下面我将详细讲解 "详解Spring Boot + Mybatis 实现动态数据源" 的完整攻略。
背景介绍
在实际项目开发中,不同的业务代码需要连接到不同的数据库中进行读写操作,而且数据库的配置可能会发生改变,因此需要支持动态切换不同的数据源进行操作。
实现步骤
- 引入必要的依赖
首先,需要在pom.xml
中引入spring-boot-starter-jdbc
、mybatis-spring-boot-starter
以及druid-spring-boot-starter
、mysql-connector-java
等依赖。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
</dependencies>
- 配置数据源信息
在application.yml
中配置数据源信息,包括主数据源和多个从数据源,如下所示:
spring:
datasource:
master:
url: jdbc:mysql://localhost:3306/master?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
slave1:
url: jdbc:mysql://localhost:3306/slave1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
slave2:
url: jdbc:mysql://localhost:3306/slave2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
- 配置数据源动态切换切面
新建DynamicDataSourceAspect
类,通过切面的方式动态切换数据源,代码如下所示:
@Aspect
@Component
public class DynamicDataSourceAspect {
@Pointcut("@annotation(com.example.dynamicdatasourcedemo.annotation.DataSource)")
public void dataSourcePointCut() {
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSource dataSource = method.getAnnotation(DataSource.class);
if (dataSource == null) {
DynamicDataSource.setDataSource(DynamicDataSource.DataSourceType.MASTER);
} else {
DynamicDataSource.setDataSource(dataSource.value());
}
try {
return point.proceed();
} finally {
DynamicDataSource.clearDataSource();
}
}
}
通过 @annotation
注解,判断需要使用哪个数据源;通过 DynamicDataSource.setDataSource()
方法切换数据源。注意:这里使用的是 ThreadLocal 保证数据源切换的线程安全。
- 配置 Mybatis
在application.yml
中配置 Mybatis,如下所示:
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
其中,mapper-locations
是 mapper 文件的路径,configuration
是 mybatis 的一些全局配置,例如驼峰命名法。
- 操作数据源
在 Service 层中,通过注解将方法标记为使用哪个数据源,如下所示:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@DataSource(DynamicDataSource.DataSourceType.SLAVE1)
public List<User> listUser() {
return userMapper.listUser();
}
@DataSource(DynamicDataSource.DataSourceType.SLAVE2)
public List<User> listUser2() {
return userMapper.listUser();
}
@Transactional
@DataSource(DynamicDataSource.DataSourceType.MASTER)
public void saveUser(User user) {
userMapper.saveUser(user);
}
}
其中,@DataSource
注解表示使用哪个数据源。
- 完成
至此,动态数据源的配置已经完成。可以启动项目,通过调用 Service 层的方法进行数据源的动态切换。
示例说明
这里提供两个示例,用于说明数据源的动态切换。
- 列出用户信息示例
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/list")
public List<User> listUser() {
return userService.listUser();
}
@RequestMapping("/list2")
public List<User> listUser2() {
return userService.listUser2();
}
}
在 Controller 层中,对外暴露两个 API,分别调用 listUser()
和 listUser2()
方法。
- 新增用户信息示例
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/save")
public String saveUser(User user) {
userService.saveUser(user);
return "success";
}
}
在 Controller 层中,对外暴露一个 API,调用 saveUser()
方法。注意:这里使用了 Spring 的事务管理,需要在 Service 层的方法上添加 @Transactional
注解。
结语
以上就是 “详解Spring Boot + Mybatis 实现动态数据源” 的完整攻略和两个示例。如有需要,也可以在其中添加其他数据源,并按照以上步骤进行配置。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Spring Boot + Mybatis 实现动态数据源 - Python技术站