哈尔滨网站设计报价,网销是做什么的,广州seo网站排名优化,19网站建设目录 一、前言二、操作1、引入依赖2、配置默认数据库 13、定义数据源实体和 Repository4、定义动态数据源5、配置数据源6、定义切换数据源注解7、定义切面类8、使用注解切换数据源 一、前言
通过切面注解方式根据不同业务动态切换数据库
二、操作
1、引入依赖
dependen… 目录 一、前言二、操作1、引入依赖2、配置默认数据库 13、定义数据源实体和 Repository4、定义动态数据源5、配置数据源6、定义切换数据源注解7、定义切面类8、使用注解切换数据源 一、前言
通过切面注解方式根据不同业务动态切换数据库
二、操作
1、引入依赖
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-jpa/artifactId/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId/dependencydependencygroupIdcom.zaxxer/groupIdartifactIdHikariCP/artifactId/dependency
/dependencies2、配置默认数据库 1
在 application.properties 或 application.yml 配置数据库 1 信息
spring.datasource.urljdbc:mysql://localhost:3306/db1
spring.datasource.usernameroot
spring.datasource.passwordpassword
spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver3、定义数据源实体和 Repository
数据源实体 DataSourceConfig.java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;Entity
public class DataSourceEntity {IdGeneratedValue(strategy GenerationType.IDENTITY)private Long id;private String url;private String username;private String password;private String driverClassName;private String dataSourceKey; // 新增字段// Getters 和 Setterspublic Long getId() {return id;}public void setId(Long id) {this.id id;}public String getUrl() {return url;}public void setUrl(String url) {this.url url;}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return password;}public void setPassword(String password) {this.password password;}public String getDriverClassName() {return driverClassName;}public void setDriverClassName(String driverClassName) {this.driverClassName driverClassName;}public String getDataSourceKey() {return dataSourceKey;}public void setDataSourceKey(String dataSourceKey) {this.dataSourceKey dataSourceKey;}
}Repository 接口 DataSourceConfigRepository.java
import org.springframework.data.jpa.repository.JpaRepository;public interface DataSourceConfigRepository extends JpaRepositoryDataSourceEntity, Long {
}4、定义动态数据源
动态数据源上下文持有者 DynamicDataSourceContextHolder.java
public class DynamicDataSourceContextHolder {private static final ThreadLocalString contextHolder new ThreadLocal();public static void setDataSourceKey(String key) {contextHolder.set(key);}public static String getDataSourceKey() {return contextHolder.get();}public static void clearDataSourceKey() {contextHolder.remove();}
}动态数据源类 DynamicDataSource.java
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource {Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSourceKey();}
}5、配置数据源
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;Configuration
public class DataSourceConfig {Autowiredprivate DataSourceConfigRepository dataSourceConfigRepository;PrimaryBeanpublic DataSource dataSource() {DynamicDataSource dynamicDataSource new DynamicDataSource();MapObject, Object targetDataSources new HashMap();// 从数据库 1 的 datasource 表加载所有数据源ListDataSourceEntity dataSourceConfigs dataSourceConfigRepository.findAll();for (DataSourceEntity config : dataSourceConfigs) {HikariDataSource dataSource new HikariDataSource();dataSource.setJdbcUrl(config.getUrl());dataSource.setUsername(config.getUsername());dataSource.setPassword(config.getPassword());dataSource.setDriverClassName(config.getDriverClassName());targetDataSources.put(config.getId().toString(), dataSource);if (db1.equals(config.getDataSourceKey())) { // 假设表中有一个字段表示数据源的 keydynamicDataSource.setDefaultTargetDataSource(dataSource);}}dynamicDataSource.setTargetDataSources(targetDataSources);return dynamicDataSource;}
}6、定义切换数据源注解
import java.lang.annotation.*;Target({ElementType.METHOD, ElementType.TYPE})
Retention(RetentionPolicy.RUNTIME)
Documented
public interface DataSourceSwitch {String value() default db1;
}7、定义切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;
import java.util.List;Aspect
Component
public class DataSourceSwitchAspect {Autowiredprivate DataSourceConfigRepository dataSourceConfigRepository;Before(annotation(com.example.annotation.DataSourceSwitch))public void before(JoinPoint point) {MethodSignature signature (MethodSignature) point.getSignature();Method method signature.getMethod();DataSourceSwitch dataSourceSwitch method.getAnnotation(DataSourceSwitch.class);if (dataSourceSwitch ! null) {String dataSourceKey dataSourceSwitch.value();ListDataSourceEntity dataSourceConfigs dataSourceConfigRepository.findAll();for (DataSourceConfig config : dataSourceConfigs) {if (dataSourceKey.equals(config.getDataSourceKey())) {DynamicDataSourceContextHolder.setDataSourceKey(config.getId().toString());break;}}}}After(annotation(com.example.annotation.DataSourceSwitch))public void after(JoinPoint point) {DynamicDataSourceContextHolder.clearDataSourceKey();}
}8、使用注解切换数据源
import com.example.annotation.DataSourceSwitch;
import com.example.entity.User;
import com.example.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;Service
public class UserService {Autowiredprivate UserRepository userRepository;DataSourceSwitch(db1)public ListUser getUsersFromDb1() {return userRepository.findAll();}DataSourceSwitch(db2) // 假设 db2 是从 datasource 表获取的数据源 keypublic ListUser getUsersFromDb2() {return userRepository.findAll();}
}