当前位置: 首页 > news >正文

2017辽宁建设厅查询网站温州网站推广排名

2017辽宁建设厅查询网站,温州网站推广排名,中英双语网站建设合同,网站在国内服务器在国外demo使用的时SpringBoot3.x、JDK17、MybatisPlus3.5.x、MySQL8 从数据中加载数据源 定义接口#xff0c;指定数据源#xff0c;从不同数据库获取数据 创建数据源表#xff0c;用于指定不同数据源#xff0c;程序自动动态获取 项目版本依赖关系 demo中所用到的工具以及…demo使用的时SpringBoot3.x、JDK17、MybatisPlus3.5.x、MySQL8 从数据中加载数据源 定义接口指定数据源从不同数据库获取数据 创建数据源表用于指定不同数据源程序自动动态获取 项目版本依赖关系 demo中所用到的工具以及版本号如下 pom文件 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcn.molu/groupIdartifactIdmgzyf-api/artifactIdversion2.4.1/versiondescription基于 Java 17 SpringBoot 3 。/descriptionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.1.5/version !-- lookup parent from repository --relativePath//parentpropertiesmaven.compiler.source17/maven.compiler.sourcemaven.compiler.target17/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncodinghutool.version5.8.15/hutool.versionmysql.version8.0.28/mysql.versiondruid.version1.2.16/druid.versionmybatis-plus.version3.5.3.1/mybatis-plus.versionlombok-mapstruct-binding.version0.2.0/lombok-mapstruct-binding.version/propertiesdependencies!-- Lombok --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId!--编译测试环境不打包在lib--scopeprovided/scope/dependency!-- 允许使用Lombok的Java Bean类中使用MapStruct注解 (Lombok 1.18.20) --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok-mapstruct-binding/artifactIdversion${lombok-mapstruct-binding.version}/versionscopeprovided/scope/dependency!-- hutool工具包 --dependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion${hutool.version}/version/dependency!-- web支持 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- aop --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId/dependency!-- 连接池 --dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactId/dependency!-- MySQL驱动 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql.version}/version/dependency!-- 阿里druid工具包 --dependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactIdversion${druid.version}/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion2.0.40/version/dependency!-- mybatis-plus --dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion${mybatis-plus.version}/version/dependency!-- 自定义配置类支持 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-configuration-processor/artifactIdoptionaltrue/optional/dependency/dependenciesbuildfinalName${project.artifactId}/finalNamepluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/project一、配置文件配置类型 1.1、配置文件配置 配置两个数据源tets01 数据库和 test02 数据库 默认使用 master 主数据源切换时只需要配置 DataSource 注解来切换即可 application.yml server:port: 8989spring:jackson:## 默认序列化时间格式date-format: yyyy-MM-dd HH:mm:ss## 默认序列化时区time-zone: GMT8datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverdruid:# 主数据源test01数据库master:url: jdbc:mysql://127.0.0.1:3306/test01?zeroDateTimeBehaviorconvertToNulluseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiautoReconnecttrueallowMultiQueriestrueusername: xxxpassword: 123driver-class-name: com.mysql.cj.jdbc.Driver# 从数据源test02数据库slave:# 是否开启从库多数据源情况下请打开enable: true# 如果时SQL server、Oracle等数据库这里需要改成对应的驱动配置url: jdbc:mysql://127.0.0.1:3306/test02?zeroDateTimeBehaviorconvertToNulluseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiautoReconnecttrueallowMultiQueriestrueusername: xxxpassword: 123driver-class-name: com.mysql.cj.jdbc.Driverinitial-size: 15min-idle: 15max-active: 200max-wait: 60000time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000validation-query: test-while-idle: truetest-on-borrow: falsetest-on-return: falsepool-prepared-statements: falseconnection-properties: false1.2、数据源配置类 读取 application 配置文件中的数据源信息并由Spring统一管理以便后续使用 DataSourceConfig import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;/*** author 陌路* apiNote 设置数据源* date 2023/12/31 10:16* tool Created by IntelliJ IDEA*/ Configuration public class DataSourceConfig {/*通过配置类将配置文件中配置的数据库信息转换成datasource并添加到DynamicDataSource中同时通过Bean将DynamicDataSource注入Spring中进行管理后期在进行动态数据源添加时会用到。*//*** 配置主数据源默认使用该数据源并且主数据源只能配置一个** return DataSource* description 该数据源是在application配置文件master中所配置的*/BeanConfigurationProperties(spring.datasource.druid.master)public DataSource masterDataSource() {return DruidDataSourceBuilder.create().build();}/*** 配置从数据源可以配置多个目前只配置了一个test02** return DataSource* description 该数据源是在application配置文件slave中所配置的*/BeanConfigurationProperties(spring.datasource.druid.slave)public DataSource slaveDataSource() {return DruidDataSourceBuilder.create().build();}/*** 配置动态数据源的核心配置项** return DynamicDataSource*/PrimaryBean(name dynamicDataSource)public DynamicDataSource createDynamicDataSource() {MapObject, Object dataSourceMap new HashMap();// 默认的数据源主数据源DataSource defaultDataSource masterDataSource();// 配置主数据源默认使用该数据源并且主数据源只能配置一个dataSourceMap.put(DataSourceType.MASTER.name(), defaultDataSource);// 配置从数据源可以配置多个目前只配置了一个test02dataSourceMap.put(DataSourceType.SLAVE.name(), slaveDataSource());// 配置动态数据源默认使用主数据源如果有从数据源配则使用从数据库中读取源并加载到dataSourceMap中return new DynamicDataSource(defaultDataSource, dataSourceMap);} }1.3、配置数据源枚举类 该枚举类主要用于数据源的指定使用 MASTER 库还是使用 SLAVE 库 如果有多个数据源可以在这里继续指定即可 DataSourceType /*** author 陌路* apiNote 动态数据源类型* date 2023/12/31 10:23* tool Created by IntelliJ IDEA*/ public enum DataSourceType {// 注意枚举项要和 DataSourceConfig 中的 createDynamicDataSource()方法dataSourceMap的key保持一致/*** 主库*/MASTER,/*** 从库*/SLAVE, }1.4、线程局部变量 线程局部变量不同于普通变量每个线程都有自己的副本互不影响。 多线程情况下也能保证数据源能够有序的切换而不会造成数据的混乱 DynamicDataSourceContextHolder import lombok.extern.slf4j.Slf4j;/*** author 陌路* apiNote 线程局部变量不同于普通变量每个线程都有自己的副本互不影响。* date 2023/12/31 10:05* tool Created by IntelliJ IDEA* description 创建一个类用于实现ThreadLocal主要是通过getsetremove方法来获取、设置、删除当前线程对应的数据源。*/ Slf4j public class DynamicDataSourceContextHolder {//此类提供线程局部变量。这些变量不同于它们的正常对应关系是每个线程访问一个线程(通过get、set方法),有自己的独立初始化变量的副本。private static final ThreadLocalString DATASOURCE_HOLDER new ThreadLocal();/*** 设置数据源** param dataSourceName 数据源名称*/public static void setDataSource(String dataSourceName) {log.info(切换数据源到{}, dataSourceName);DATASOURCE_HOLDER.set(dataSourceName);}/*** 获取当前线程的数据源** return 数据源名称*/public static String getDataSource() {return DATASOURCE_HOLDER.get();}/*** 删除当前数据源*/public static void removeDataSource() {log.info(删除当前数据源{}, getDataSource());DATASOURCE_HOLDER.remove();} }1.5、添加切换的数据源核心 定义一个动态数据源类实现AbstractRoutingDataSource通过determineCurrentLookupKey方法与上述实现的ThreadLocal类中的get方法进行关联实现动态切换数据源。 切换数据源后具体查询哪个数据库由此类决定 DynamicDataSource import com.alibaba.druid.pool.DruidDataSource; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.BeanUtils; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;import javax.sql.DataSource; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.Objects;/*** author 陌路* apiNote 实现动态数据源根据AbstractRoutingDataSource路由到不同数据源中* date 2023/12/31 10:08* tool Created by IntelliJ IDEA* description 定义一个动态数据源类实现AbstractRoutingDataSource通过determineCurrentLookupKey方法与上述实现的ThreadLocal类中的get方法进行关联实现动态切换数据源。*/ Slf4j public class DynamicDataSource extends AbstractRoutingDataSource {/*代码中还实现了一个动态数据源类的构造方法主要是为了设置默认数据源以及以Map保存的各种目标数据源。其中Map的key是设置的数据源名称value则是对应的数据源DataSource*/// 数据源列表多数据源情况下具体使用哪一个数据源由此获取private final MapObject, Object targetDataSourceMap;/*** 构造方法设置默认数据源和目标多数据源** param defaultDataSource 默认主数据源只能有一个* param targetDataSources 从数据源可以是多个*/public DynamicDataSource(DataSource defaultDataSource, MapObject, Object targetDataSources) {super.setDefaultTargetDataSource(defaultDataSource);super.setTargetDataSources(targetDataSources);this.targetDataSourceMap targetDataSources;// 配置完成后更新数据源配置列表将TargetDataSources中的连接信息放入resolvedDataSources管理super.afterPropertiesSet();}/*** 动态数据源的切换核心* 决定使用哪个数据源** return Object*/Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSource();}/*** 校验数据源是否存在** param key 数据源保存的key* return 返回结果true存在false不存在*/public boolean existsDataSource(String key) {return Objects.nonNull(this.targetDataSourceMap) Objects.nonNull(this.targetDataSourceMap.get(key));} }1.6、数据源注解类 此注解可以配置在类上也可以配置在方法上 优先级方法 类 当方法上加了此注解时类上配置的注解将会失效 当类中所有方法都没有此注解而类上存在时那么该类中所有方法都将使用该类上的数据源 方法和类上都不添加该注解时默认使用 master 数据源 DataSource import java.lang.annotation.*;/*** 自定义多数据源切换注解* p* 优先级先方法后类如果方法覆盖了类上的数据源类型以方法的为准否则以类上的为准*/ Inherited Documented Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD, ElementType.TYPE}) public interface DataSource {/*** 切换数据源名称默认是主数据源test01*/public DataSourceType value() default DataSourceType.MASTER; }1.7、动态数据源切面核心 是否需要切换数据源或者具体使用哪个数据源由此类通过解析 DataSource 注解来决定 不添加或者解析不到该注解时则使用默认的数据源master DataSourceAspect import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.aspectj.lang.reflect.MethodSignature; import java.util.Objects;/*** author 陌路* apiNote 多数据源切换* date 2023/12/31 13:06* tool Created by IntelliJ IDEA*/ Aspect Order(1) Component public class DataSourceAspect {// 配置织入点为DataSource 注解Pointcut(annotation(cn.molu.system.common.datasource.DataSource) || within(cn.molu.system.common.datasource.DataSource))public void dsPointCut() {}/*** * 环绕通知** param point 切入点* return Object* throws Throwable 异常*/Around(dsPointCut())public Object around(ProceedingJoinPoint point) throws Throwable {DataSource dataSource getDataSource(point);if (Objects.nonNull(dataSource) StringUtils.isNotEmpty(dataSource.value().name())) {// 将用户自定义配置的数据源添加到线程局部变量中DynamicDataSourceContextHolder.setDataSource(dataSource.value().name());}try {return point.proceed();} finally {// 在执行完方法之后销毁数据源 DynamicDataSourceContextHolder.removeDataSource();}}/*** 获取需要切换的数据源* 注意顺序为方法类方法上加了注解后类上的将不会生效* 注意当类上配置后方法上没有该注解那么当前类中的所有方法都将使用类上配置的数据源*/public DataSource getDataSource(ProceedingJoinPoint point) {MethodSignature signature (MethodSignature) point.getSignature();// 从方法上获取注解DataSource dataSource AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);// 方法上不存在时再从类上匹配return Objects.nonNull(dataSource) ? dataSource : AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);} }1.8、启动类修改 上述中我们自定义了数据源的配置这里据需要将 DataSourceAutoConfiguration 自动配置的数据源排除否则项目启动时可能会出现异常导致项目无法正常运行 SystemApplication // 排除数据源自动配置使用自定义数据源否则会出现循环依赖报错 SpringBootApplication(exclude DataSourceAutoConfiguration.class) public class SystemApplication {public static void main(String[] args) {SpringApplication.run(SystemApplication.class, args);log.info(项目启动成功http://127.0.0.1:8989);} }到此配置类型的多数据源的切换就完成了 不足和缺陷 每次添加数据源时都需要在 application 配置文件中添加线上环境时每次都需要替换新的 application 文件当数据库密码修改或者切换服务器时维护成本高不够便利 以上不足和缺陷将在以下内容中逐一解决 二、数据库动态获取类型 数据源信息配置在数据库中便于维护 在以上代码的基础上进行修改所新增的代码以及变更的代码将会给出具体的说明 在以上代码的基础上新增SysDbInfo、LoadDataSourceRunner【2个新增】 修改变更的类DataSourceConfig、DynamicDataSource【2个改动】 以下类不做任何改动DynamicDataSourceContextHolder、DataSourceType、DataSourceAspect、DataSource、SystemApplication【5个未作改动】 修改配置文件 改动内容仅去除了从数据库的配置信息不再需要在配置文件中配置从库数据 server:port: 8989spring:jackson:## 默认序列化时间格式date-format: yyyy-MM-dd HH:mm:ss## 默认序列化时区time-zone: GMT8datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverdruid:master:url: jdbc:mysql://127.0.0.1:3306/test01?zeroDateTimeBehaviorconvertToNulluseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiautoReconnecttrueallowMultiQueriestrueusername: xxxpassword: 123driver-class-name: com.mysql.cj.jdbc.Driverslave:# 是否开启从库多数据源情况下请打开并且将配置信息配置到sys_db_info表中项目启动时会自动加载enable: trueinitial-size: 15min-idle: 15max-active: 200max-wait: 60000time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000validation-query: test-while-idle: truetest-on-borrow: falsetest-on-return: falsepool-prepared-statements: falseconnection-properties: false 2.1、数据源实体类 SysDbInfo import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.ToString; import lombok.experimental.Accessors; import java.io.Serial; import java.io.Serializable;/*** author 陌路* apiNote 数据源实体类* date 2023/12/31 10:29* tool Created by IntelliJ IDEA*/ Data ToString EqualsAndHashCode NoArgsConstructor Accessors(chain true) TableName(value sys_db_info) public class SysDbInfo implements Serializable {SerialTableField(exist false)private static final long serialVersionUID 8115921127536664152L; /* -- 建表语句 CREATE TABLE sys_db_info (id int unsigned NOT NULL AUTO_INCREMENT COMMENT 主键Id,url varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 数据库URL,username varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 用户名,password varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 密码,driver_class_name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 数据库驱动,db_name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 数据库名称,db_key varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 数据库key即保存Map中的key(保证唯一并且和DataSourceType中的枚举项保持一致包括大小写),status int NOT NULL DEFAULT 0 COMMENT 是否停用0-正常1-停用,remark varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 备注说明,PRIMARY KEY (id) USING BTREE,UNIQUE KEY UNI_DB_INFO_DBKEY (db_key) USING BTREE COMMENT 数据库的key必须唯一并且要和DataSourceType中的枚举项保持一致 ) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin ROW_FORMATDYNAMIC;*//*** 数据库地址*/private String url;/*** 数据库用户名*/private String username;/*** 密码*/private String password;/*** 数据库驱动*/private String driverClassName;/*** 数据库key即保存Map中的key(保证唯一)* 定义一个key用于作为DynamicDataSource中Map中的key。* 这里的key需要和DataSourceType中的枚举项保持一致*/private String dbKey;/*** 数据库名称*/private String dbName;/*** 是否停用0-正常1-停用*/private Integer status;/*** 备注*/private String remark; }以下是实体类所对应的SQL语句 CREATE TABLE sys_db_info (id int unsigned NOT NULL AUTO_INCREMENT COMMENT 主键Id,url varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 数据库URL,username varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 用户名,password varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 密码,driver_class_name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 数据库驱动,db_name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 数据库名称,db_key varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 数据库key即保存Map中的key(保证唯一并且和DataSourceType中的枚举项保持一致包括大小写),status int NOT NULL DEFAULT 0 COMMENT 是否停用0-正常1-停用,remark varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 备注说明,PRIMARY KEY (id) USING BTREE,UNIQUE KEY UNI_DB_INFO_DBKEY (db_key) USING BTREE COMMENT 数据库的key必须唯一并且要和DataSourceType中的枚举项保持一致 ) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin ROW_FORMATDYNAMIC;-- 添加数据库配置信息此处按照自己的需求配置对应的数据库即可 INSERT INTO sys_db_info (id, url, username, password, driver_class_name, db_name, db_key, status, remark) VALUES (1, jdbc:mysql://127.0.0.1:3306/test02?zeroDateTimeBehaviorconvertToNulluseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiautoReconnecttrueallowMultiQueriestrue, xxx, 123, com.mysql.cj.jdbc.Driver, test02, SLAVE, 0, 连接test02数据库); INSERT INTO sys_db_info (id, url, username, password, driver_class_name, db_name, db_key, status, remark) VALUES (2, jdbc:mysql://127.0.0.1:3306/test03?zeroDateTimeBehaviorconvertToNulluseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiautoReconnecttrueallowMultiQueriestrue, xxx, 123, com.mysql.cj.jdbc.Driver, test03, SLAVE2, 1, 链接test03数据库);2.2、初始化加载数据源 项目启动时执行此代码访问数据库加载数据库中配置的数据源信息 LoadDataSourceRunner import cn.hutool.core.util.StrUtil; import cn.molu.system.mapper.SysDbInfoMapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component;import java.util.ArrayList; import java.util.List;/*** author 陌路* apiNote 查询数据源* date 2023/12/31 10:41* tool Created by IntelliJ IDEA* CommandLineRunner 项目启动时执行*/ Slf4j Component public class LoadDataSourceRunner implements CommandLineRunner {/*** 是否启用从库多数据源配置*/Value(${spring.datasource.druid.slave.enable})private boolean enabled;Resourceprivate DynamicDataSource dynamicDataSource;Resourceprivate SysDbInfoMapper dbInfoMapper;/*** 项目启动时加载数据源*/Overridepublic void run(String... args) {if (enabled) return;refreshDataSource();}/*** 刷新数据源*/public void refreshDataSource() {ListSysDbInfo dbInfos dbInfoMapper.selectList(new LambdaQueryWrapperSysDbInfo().eq(SysDbInfo::getStatus, 0));if (CollectionUtils.isEmpty(dbInfos)) return;ListSysDbInfo ds new ArrayList();log.info(开始加载数据源);for (SysDbInfo info : dbInfos) {if (StrUtil.isAllNotBlank(info.getUrl(), // 数据库连接地址info.getDriverClassName(), // 数据库驱动info.getUsername(), // 数据库用户名info.getPassword(), // 数据库密码info.getDbKey() // 数据源key)) {ds.add(info);log.info(加载到数据源 --- dbName{}、dbKey{}、remark{}, info.getDbName(), info.getDbKey(), info.getRemark());}}dynamicDataSource.createDataSource(ds);log.info(数据源加载完成);} }2.3、数据源配置类改动 该配置类稍作改动去除了从配置文件中加载从数据源slave只加载主数据源master DataSourceConfig import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;/*** author 陌路* apiNote 设置数据源* date 2023/12/31 10:16* tool Created by IntelliJ IDEA*/ Configuration public class DataSourceConfig {/*通过配置类将配置文件中的配置的数据库信息转换成datasource并添加到DynamicDataSource中同时通过Bean将DynamicDataSource注入Spring中进行管理后期在进行动态数据源添加时会用到。*//*** 配置主数据源默认使用该数据源并且主数据源只能配置一个** return DataSource* description 该数据源是在application配置文件master中所配置的*/BeanConfigurationProperties(spring.datasource.druid.master)public DataSource masterDataSource() {return DruidDataSourceBuilder.create().build();}/*** 配置从数据源可以配置多个* p现在已经改为数据库配置如果有多个数据源请在sys_db_info表中添加即可* 不需要在application中配置此方法已注释配置也不会生效p/** return DataSource* description 该数据源是在application配置文件slave中所配置的*/ // Bean // ConfigurationProperties(spring.datasource.druid.slave)public DataSource slaveDataSource() {return DruidDataSourceBuilder.create().build();}/*** 配置动态数据源的核心配置项** return DynamicDataSource*/PrimaryBean(name dynamicDataSource)public DynamicDataSource createDynamicDataSource() {MapObject, Object dataSourceMap new HashMap();// 默认数据源DataSource defaultDataSource masterDataSource();// 配置主数据源默认使用该数据源并且主数据源只能配置一个dataSourceMap.put(DataSourceType.MASTER.name(), defaultDataSource);// 配置从数据源可以配置多个目前已注释不需要application中配置如果有多个数据源请在sys_db_info表中添加即可 // dataSourceMap.put(DataSourceType.SLAVE.name(), slaveDataSource());// 配置动态数据源默认使用主数据源如果有从数据源配则使用从数据库中读取源并加载到dataSourceMap中return new DynamicDataSource(defaultDataSource, dataSourceMap);} }2.4、添加读取到的数据源 改动添加切换的数据源类将数据库中读取出来的数据源列表逐一添加以便后续使用 DynamicDataSource import com.alibaba.druid.pool.DruidDataSource; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.BeanUtils; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import javax.sql.DataSource; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.Objects;/*** author 陌路* apiNote 实现动态数据源根据AbstractRoutingDataSource路由到不同数据源中* date 2023/12/31 10:08* tool Created by IntelliJ IDEA* description 定义一个动态数据源类实现AbstractRoutingDataSource通过determineCurrentLookupKey方法与上述实现的ThreadLocal类中的get方法进行关联实现动态切换数据源。*/ Slf4j public class DynamicDataSource extends AbstractRoutingDataSource {/*代码中还实现了一个动态数据源类的构造方法主要是为了设置默认数据源以及以Map保存的各种目标数据源。其中Map的key是设置的数据源名称value则是对应的数据源DataSource*/// 数据源列表多数据源情况下具体使用哪一个数据源由此获取private final MapObject, Object targetDataSourceMap;/*** 构造方法设置默认数据源和目标多数据源** param defaultDataSource 默认主数据源只能有一个* param targetDataSources 从数据源可以是多个*/public DynamicDataSource(DataSource defaultDataSource, MapObject, Object targetDataSources) {super.setDefaultTargetDataSource(defaultDataSource);super.setTargetDataSources(targetDataSources);this.targetDataSourceMap targetDataSources;// 配置完成后更新数据源配置列表将TargetDataSources中的连接信息放入resolvedDataSources管理 // super.afterPropertiesSet();}/*** 动态数据源的切换核心* 决定使用哪个数据源** return Object*/Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSource();}/*** 添加数据源信息** param dataSources 数据源实体集合*/public void createDataSource(ListSysDbInfo dataSources) {try {if (CollectionUtils.isNotEmpty(dataSources)) {for (SysDbInfo ds : dataSources) {//校验数据库是否可以连接Class.forName(ds.getDriverClassName());DriverManager.getConnection(ds.getUrl(), ds.getUsername(), ds.getPassword());//定义数据源DruidDataSource dataSource new DruidDataSource();BeanUtils.copyProperties(ds, dataSource);//申请连接时执行validationQuery检测连接是否有效这里建议配置为TRUE防止取到的连接不可用dataSource.setTestOnBorrow(true);//建议配置为true不影响性能并且保证安全性。//申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。dataSource.setTestWhileIdle(true);//用来检测连接是否有效的sql要求是一个查询语句。dataSource.setValidationQuery(select 1 );dataSource.init();// 将数据源放入Map中key为数据源名称要和DataSourceType中的枚举项对应包括大小写并且保证唯一this.targetDataSourceMap.put(ds.getDbKey(), dataSource);}// 更新数据源配置列表这里主要是从数据源super.setTargetDataSources(this.targetDataSourceMap);// 将TargetDataSources中的连接信息放入resolvedDataSources管理super.afterPropertiesSet();}} catch (ClassNotFoundException | SQLException e) {log.error(---解析数据源出错---{}, e.getMessage());}}/*** 校验数据源是否存在** param key 数据源保存的key* return 返回结果true存在false不存在*/public boolean existsDataSource(String key) {return Objects.nonNull(this.targetDataSourceMap) Objects.nonNull(this.targetDataSourceMap.get(key));} }2.5、SysDbInfo相关 用于向数据库查询数据 import cn.molu.system.common.datasource.SysDbInfo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper;Mapper public interface SysDbInfoMapper extends BaseMapperSysDbInfo {}到此动态数据源相关就完成了可以启动项目试一下 注意说明 1、master主数据库一定要有并且可以连接否则项目无法启动 2、slave从数据库可以有也可以没有也可以时很多个 3、slave从数据库可以是其他数据库Oracle、SQL serve等对应修改配置即可 4、DataSourceType枚举中的枚举项一定要和数据库中配置的dbkey保持一致 5、使用的时候之间使用DataSource注解指定数据源即可 2.6、使用用例 动态数据源的使用 /*** 用户控制器** author 陌路* since 2023/12/31*/ RestController RequiredArgsConstructor// 此注解用于指定具体使用哪个数据源 DataSource(DataSourceType.SLAVE) RequestMapping(/api/v1/users) public class SysUserController {private final SysUserService userService;/*** 用户分页列表* param queryParams 查询参数* return 用户分页列表*/GetMapping(/page) // 使用类上的数据源SLAVEpublic PageResultUserPageVO getUserPage(UserPageQuery queryParams) {IPageUserPageVO result userService.getUserPage(queryParams);return PageResult.success(result);}/*** 删除用户** param ids 用户ID多个以英文逗号(,)分割* return 删除结果*/DeleteMapping(/{ids})DataSource(DataSourceType.MASTER) // 在方法上则类上的配置失效public ResultBoolean deleteUsers(PathVariable String ids) {boolean result userService.deleteUsers(ids);return Result.judge(result);}}不切换数据源使用默认 不加DataSource注解使用默认数据源 java /*** 用户控制器** author 陌路* since 2023/12/31*/ RestController RequiredArgsConstructor RequestMapping(/api/v1/users) public class SysUserController {private final SysUserService userService;/*** 用户分页列表* param queryParams 查询参数* return 用户分页列表*/GetMapping(/page)public PageResultUserPageVO getUserPage(UserPageQuery queryParams) {IPageUserPageVO result userService.getUserPage(queryParams);return PageResult.success(result);}/*** 删除用户** param ids 用户ID多个以英文逗号(,)分割* return 删除结果*/DeleteMapping(/{ids})public ResultBoolean deleteUsers(PathVariable String ids) {boolean result userService.deleteUsers(ids);return Result.judge(result);}}以上就是配置动态数据源的过程了可以根据不同需求使用配置文件的形式或者使用数据库配置的形式 我这里没有将测试过程以及结果贴出来请自行测试使用。。。
http://www.pierceye.com/news/107796/

相关文章:

  • 天津网站制作报价阿里云需要网站建设方案书
  • 做最好的美食分享网站网站建设客户需求分析
  • 如何重建网站广州市服务好的网站制作排名
  • 做一名优秀网站设计师计划网站描述怎样写
  • 网页二级网站怎么做网监关闭的网站怎么恢复
  • 甘肃省建设监理协会 官方网站国内知名公关公司
  • 如何将网站和域名绑定阿里云1M做网站
  • 南城网站建设公司咨询东莞智通人才网最新招聘
  • app建设网站公司哪家好php网站修改代码
  • 哪些网上订餐的网站做的好地情网站建设
  • 重庆推广网站的方法国内最近的新闻大事
  • 网站需要备案吗网站怎么推广软文
  • 做设计开哪个素材网站的会员好手机免费网站建设哪家公司好
  • 征婚网站认识的男人做定投保做高级电工题的网站
  • 学做饼干的网站汕头建设学校的网站
  • asp.net做网站原理工资卡app下载
  • 做齐鲁油官方网站集团网站建设报价
  • 网站的收录情况怎么查企业网银怎么登录
  • 网站开发会计处理wordpress阅读随机增加
  • 兰州做网站公司哪家好公司网站建设是什么意思
  • 小区物业管理网站开发报告deal 网站要怎么做
  • seo站长助手wordpress 注册侧边栏
  • 做网站是要编程吗那些网站是html5做的
  • 网站开发图在网站做电子画册
  • 怎样建一个英文网站wordpress 多用户商城
  • 制作一个自适应网站源码app在线生成器
  • Dw做html网站项目管理软件有哪些
  • 天津网站建设定制软件开发服务公司
  • 做企业网站cms减肥网站源码
  • 建设工程检测预约网站猎头公司怎么找