SpringBoot+Mybatis+Druid动态数据源配置实战

版权申诉
10 下载量 4 浏览量 更新于2024-09-11 1 收藏 97KB PDF 举报
"通过springboot+mybatis+druid配置动态数据源" 在现代企业级应用中,经常需要处理多个数据库,比如分离读写操作、分布式系统或是多租户环境。在这种情况下,动态数据源的配置变得至关重要。本教程将详细讲解如何在Spring Boot项目中结合MyBatis和Druid实现动态数据源的配置。 首先,我们来看一下建数据库和表的部分。创建了两个不同的数据库,分别是`demo1`和`demo2`,各自包含了一张用户表`user`和角色表`role`。`user`表有`id`和`name`两个字段,`role`表也有`id`和`name`字段,用于存储用户角色信息。 接下来,我们需要在项目的`pom.xml`文件中引入相应的依赖。Spring Boot、MyBatis和Druid的相关依赖必不可少,还需要一个支持动态数据源的库,例如`druid-spring-boot-starter`。这里省略了具体的XML配置,但通常会包括以下依赖: ```xml <dependencies> <!-- Spring Boot Starter Data JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- MyBatis for Spring Boot --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>版本号</version> </dependency> <!-- Druid 数据源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>版本号</version> </dependency> </dependencies> ``` 然后,我们需要配置Spring Boot的主配置类,声明动态数据源。这里会使用Druid的数据源,因为Druid提供了很好的监控和管理功能。在`application.yml`或`application.properties`中,我们可以这样配置: ```yaml spring: datasource: dynamic: primary: db1 # 主数据源名称 datasources: db1: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/demo1 username: root password: password db2: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/demo2 username: root password: password ``` 接下来,我们需要创建一个自定义的动态数据源类,继承`AbstractRoutingDataSource`,并重写`determineCurrentLookupKey`方法来根据业务逻辑选择当前要使用的数据源: ```java import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { // 这里可以根据具体业务逻辑返回数据源key,如:db1或db2 return DataSourceContextHolder.getDataSource(); } } ``` 同时,创建一个数据源上下文持有类`DataSourceContextHolder`,用于在业务代码中切换数据源: ```java import org.springframework.util.StringUtils; import javax.sql.DataSource; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Map; public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); public static void setDataSource(String dataSource) { contextHolder.set(dataSource); } public static String getDataSource() { return contextHolder.get(); } public static void clearDataSource() { contextHolder.remove(); } public static DataSource getDataSourceProxy(DataSource dataSource) { if (dataSource == null || StringUtils.isEmpty(contextHolder.get())) { return dataSource; } return (DataSource) Proxy.newProxyInstance( DataSource.class.getClassLoader(), new Class[]{DataSource.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { setDataSource(contextHolder.get()); try { return method.invoke(dataSource, args); } finally { clearDataSource(); } } }); } } ``` 最后,我们需要在MyBatis的配置中使用自定义的动态数据源,并在启动类上添加`@EnableTransactionManagement`注解以启用事务管理: ```java @Configuration @EnableTransactionManagement public class MyBatisConfig { @Autowired private DataSourceProperties properties; @Bean @Primary public DataSource dynamicDataSource() { DynamicDataSource dynamicDataSource = new DynamicDataSource(); dynamicDataSource.setDefaultTargetDataSource(getTargetDataSource(properties)); Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("db1", getTargetDataSource(properties, "db1")); targetDataSources.put("db2", getTargetDataSource(properties, "db2")); dynamicDataSource.setTargetDataSources(targetDataSources); return dynamicDataSource; } private DataSource getTargetDataSource(DataSourceProperties properties, String dsName) { return DataSourceBuilder.create(properties.getConfigLocation()) .prefix(dsName) .type(DataSource.class) .build(); } @Bean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { MyBatisSqlSessionFactoryBean factory = new MyBatisSqlSessionFactoryBean(); factory.setDataSource(dataSource); return factory.getObject(); } } ``` 现在,你的Spring Boot项目已经配置好了动态数据源。在业务代码中,你可以通过`DataSourceContextHolder`切换数据源,使得不同的操作可以连接到不同的数据库。这将大大提高系统的灵活性和可扩展性。 总结,配置动态数据源的关键步骤包括: 1. 引入相关依赖。 2. 在配置文件中声明多个数据源。 3. 创建自定义动态数据源类和数据源上下文持有类。 4. 在MyBatis配置中使用自定义的动态数据源。 5. 在业务代码中切换数据源。 这个过程不仅可以帮助你实现多数据库的灵活切换,还能确保在不同数据库之间进行无缝操作,是大型复杂系统中的重要设计模式。