Spring Boot动态数据库连接Spring Data JPA
Spring Boot动态数据库连接是一种将应用程序连接到不同数据库的技术,它允许您在运行时动态选择数据库。 在Spring Boot应用程序中,您可以使用配置文件来设置数据库连接,但这样做的问题是您必须重新启动应用程序才能使用新的数据库。 要实现动态数据库连接,您可以使用Spring Data JPA框架,它提供了一个通用的Repository接口来访问数据库,并且可以使用注解来指定要连接到哪个数据库。 以下是一个使用Spring Boot和Spring Data JPA来实现动态数据库连接的示例: 1. 首先,您需要在您的pom.xml文件中添加以下依赖:
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2. 接下来,您需要在您的应用程序配置文件中添加数据库连接信息。您可以添加多个数据源,并为每个数据源指定唯一的名称。
spring.datasource.url=jdbc:mysql://localhost:3306/db1
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
dynamic.datasource.datasource1.url=jdbc:mysql://localhost:3306/db2
dynamic.datasource.datasource1.username=root
dynamic.datasource.datasource1.password=password
dynamic.datasource.datasource1.driver-class-name=com.mysql.jdbc.Driver
3. 创建一个动态数据源配置类,用于在运行时选择要使用的数据库。
public class DynamicDataSourceConfig {
@Bean
@ConfigurationProperties("dynamic.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSource dataSource() {
return dataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean
@ConfigurationProperties(prefix = "dynamic.datasource")
public Map<String, DataSourceProperties> dataSourcePropertiesMap() {
return new HashMap<>();
}
@Bean
public AbstractRoutingDataSource routingDataSource() {
Map<Object, Object> targetDataSources = new HashMap<>();
DataSource primaryDataSource = dataSource();
targetDataSources.put("primary", primaryDataSource);
dataSourcePropertiesMap().forEach((key, value) -> {
DataSource dataSource = value.initializeDataSourceBuilder().build();
targetDataSources.put(key, dataSource);
});
AbstractRoutingDataSource dataSource = new AbstractRoutingDataSource() {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getDataSourceKey();
}
};
dataSource.setTargetDataSources(targetDataSources);
dataSource.setDefaultTargetDataSource(primaryDataSource);
return dataSource;
}
}
4. 创建一个数据源上下文持有者类,用于在线程范围内存储当前要使用的数据源。
public class DynamicDataSourceContextHolder {
private static final ThreadLocal<String> CONTEXT_HOLDER = ThreadLocal.withInitial(() -> "primary");
public static void setDataSourceKey(String dataSourceKey) {
CONTEXT_HOLDER.set(dataSourceKey);
}
public static String getDataSourceKey() {
return CONTEXT_HOLDER.get();
}
public static void clearDataSourceKey() {
CONTEXT_HOLDER.remove();
}
}
5. 创建一个切面类,用于在访问数据库之前切换数据源。
public class DynamicDataSourceAspect {
@Pointcut("@annotation(com.example.demo.dynamicdatasource.annotation.DataSource)")
public void dataSourcePointcut() {
}
@Around("dataSourcePointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
DataSource annotation = signature.getMethod().getAnnotation(DataSource.class);
if (annotation == null) {
DynamicDataSourceContextHolder.setDataSourceKey("primary");
} else {
DynamicDataSourceContextHolder.setDataSourceKey(annotation.value());
}
try {
return point.proceed();
} finally {
DynamicDataSourceContextHolder.clearDataSourceKey();
}
}
}
6. 在您的Repository类中使用@DataSource注释来指定要使用的数据源。
public interface UserRepository extends JpaRepository<User, Long> {
@DataSource("datasource1")
@Query("select * from users")
List<User> findAllFromDataSource1();
@DataSource("datasource2")
@Query("select * from users")
List<User> findAllFromDataSource2();
}
现在,您可以在运行时动态选择要使用的数据库。要使用不同的数据库,请在访问数据库之前调用DynamicDataSourceContextHolder.setDataSourceKey(dataSourceKey)方法,并在访问数据库后调用DynamicDataSourceContextHolder.clearDataSourceKey()方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)