@@ -32,7 +31,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @EnableConfigurationProperties(TenantProperties.class) @PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:kicc-tenant.yml") @RequiredArgsConstructor -public class MybatisConfiguration implements WebMvcConfigurer { +public class MybatisConfiguration { private final TenantProperties tenantProperties; diff --git a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/entity/RedisInfo.java b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/entity/RedisInfo.java deleted file mode 100644 index cc29d65d..00000000 --- a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/entity/RedisInfo.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.cloud.kicc.common.data.entity; - -import java.util.HashMap; -import java.util.Map; - -/** - *
- * redis 响应信息 - *
- * - * @Author: entfrm开发团队-王翔 - * @Date: 2022/2/18 - */ -public class RedisInfo { - - private static Map- * 数据过滤拦截器 - * 目前没有数据过滤需求,后面有了在做 - * 这里思路写个数据过滤拦截器,通过在mybatis中注册,跟分页那种直接全局拦截拼接sql、 - * 不过这边拼接部分放在注解切面中做,只有加了注解的才会有拼接过滤的sql - *
- * - * @Author: entfrm开发团队-王翔 - * @Date: 2022/4/2 - *//* - -public class KiccDataScopeInnerInterceptor implements InnerInterceptor { - - */ -/** - * 全部数据权限 - *//* - - public static final String DATA_SCOPE_ALL = "1"; - - */ -/** - * 自定数据权限 - *//* - - public static final String DATA_SCOPE_CUSTOM = "2"; - - */ -/** - * 部门数据权限 - *//* - - public static final String DATA_SCOPE_DEPT = "3"; - - */ -/** - * 部门及以下数据权限 - *//* - - public static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; - - */ -/** - * 仅本人数据权限 - *//* - - public static final String DATA_SCOPE_SELF = "5"; - - @Override - public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { - - @Override - public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, - ResultHandler resultHandler, BoundSql boundSql) { - - PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql); - String originalSql = boundSql.getSql(); - Object parameterObject = boundSql.getParameterObject(); - - // 查找参数中包含DataScope类型的参数 - DataScope dataScope = findDataScopeObject(parameterObject); - if (dataScope == null) { - return; - } - - LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest()); - if (StringUtils.isNotNull(loginUser)) { - SysUser currentUser = loginUser.getUser(); - // 如果是超级管理员,则不过滤数据 - if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) { - String scopeName = dataScope.getScopeName(); - List- * 动态数据源切换配置 - *
- * - * @Author: entfrm开发团队-王翔 - * @Date: 2022/2/19 - */ -@Configuration(proxyBeanMethods = false) -@AutoConfigureAfter(DataSourceAutoConfiguration.class) -@EnableConfigurationProperties(DataSourceProperties.class) -public class DynamicDataSourceAutoConfiguration { - - @Bean - public DynamicDataSourceProvider dynamicDataSourceProvider(StringEncryptor stringEncryptor, DataSourceProperties properties) { - return new JdbcDynamicDataSourceProvider(stringEncryptor, properties); - } - - @Bean - public DsProcessor dsProcessor() { - return new LastParamDsProcessor(); - } - -} diff --git a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/DynamicDataSourceConfiguration.java b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/DynamicDataSourceConfiguration.java new file mode 100644 index 00000000..f953a04f --- /dev/null +++ b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/DynamicDataSourceConfiguration.java @@ -0,0 +1,55 @@ +package com.cloud.kicc.common.datasource; + +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; +import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator; +import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; +import com.cloud.kicc.common.datasource.dynamic.DynamicDataSourceJdbcProvider; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; + +/** + *+ * 动态数据源切换配置 + *
+ * + * @Author: entfrm开发团队-王翔 + * @Date: 2022/2/19 + */ +@Configuration(proxyBeanMethods = false) +public class DynamicDataSourceConfiguration { + + @Bean + public DynamicDataSourceProvider dynamicDataSourceProvider(DataSourceProperties dataSourceProperties, + DynamicDataSourceProperties dynamicDataSourceProperties, + DefaultDataSourceCreator defaultDataSourceCreator) { + String driverClassName = dataSourceProperties.getDriverClassName(); + String url = dataSourceProperties.getUrl(); + String username = dataSourceProperties.getUsername(); + String password = dataSourceProperties.getPassword(); + DataSourceProperty master = dynamicDataSourceProperties.getDatasource().get(dynamicDataSourceProperties.getPrimary()); + if (master != null) { + driverClassName = master.getDriverClassName(); + url = master.getUrl(); + username = master.getUsername(); + password = master.getPassword(); + } + return new DynamicDataSourceJdbcProvider(dynamicDataSourceProperties, driverClassName, url, username, password); + } + + @Bean + public DataSource dataSource(DynamicDataSourceProperties dynamicDataSourceProperties) { + DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource(); + dataSource.setPrimary(dynamicDataSourceProperties.getPrimary()); + dataSource.setStrict(dynamicDataSourceProperties.getStrict()); + dataSource.setStrategy(dynamicDataSourceProperties.getStrategy()); + dataSource.setP6spy(dynamicDataSourceProperties.getP6spy()); + dataSource.setSeata(dynamicDataSourceProperties.getSeata()); + return dataSource; + } + +} diff --git a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/annotation/EnableDynamicDataSource.java b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/annotation/EnableDynamicDataSource.java index 53fc34be..09d6cce5 100644 --- a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/annotation/EnableDynamicDataSource.java +++ b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/annotation/EnableDynamicDataSource.java @@ -1,6 +1,6 @@ package com.cloud.kicc.common.datasource.annotation; -import com.cloud.kicc.common.datasource.DynamicDataSourceAutoConfiguration; +import com.cloud.kicc.common.datasource.DynamicDataSourceConfiguration; import org.springframework.context.annotation.Import; import java.lang.annotation.*; @@ -17,7 +17,7 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@Import(DynamicDataSourceAutoConfiguration.class) +@Import(DynamicDataSourceConfiguration.class) public @interface EnableDynamicDataSource { } diff --git a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/config/DataSourceProperties.java b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/config/DataSourceProperties.java deleted file mode 100644 index d4fa4a1a..00000000 --- a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/config/DataSourceProperties.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.cloud.kicc.common.datasource.config; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - *- * 多数据源配置属性 - *
- * - * @Author: entfrm开发团队-王翔 - * @Date: 2022/2/19 - */ -@Data -@ConfigurationProperties("spring.datasource") -public class DataSourceProperties { - - /** - * 用户名 - */ - private String username; - - /** - * 密码 - */ - private String password; - - /** - * jdbc_url - */ - private String url; - - /** - * 驱动类型 - */ - private String driverClassName; - - /** - * 查询数据源的SQL - */ - private String queryDsSql = "select * from gen_datasource_conf where del_flag = 0"; - -} diff --git a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/config/JdbcDynamicDataSourceProvider.java b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/config/JdbcDynamicDataSourceProvider.java deleted file mode 100644 index 19c66bf1..00000000 --- a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/config/JdbcDynamicDataSourceProvider.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.cloud.kicc.common.datasource.config; - -import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider; -import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; -import com.cloud.kicc.common.datasource.support.DataSourceConstants; -import org.jasypt.encryption.StringEncryptor; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.Map; - -/** - *- * 初始化多数据源 - * 从数据源中获取 配置信息 - *
- * - * @Author: entfrm开发团队-王翔 - * @Date: 2022/2/19 - */ -public class JdbcDynamicDataSourceProvider extends AbstractJdbcDataSourceProvider { - - private final DataSourceProperties properties; - - private final StringEncryptor stringEncryptor; - - public JdbcDynamicDataSourceProvider(StringEncryptor stringEncryptor, DataSourceProperties properties) { - super(properties.getDriverClassName(), properties.getUrl(), properties.getUsername(), properties.getPassword()); - this.stringEncryptor = stringEncryptor; - this.properties = properties; - } - - /** - * 执行语句获得数据源参数 - * @param statement 语句 - * @return 数据源参数 - * @throws SQLException sql异常 - */ - @Override - protected Map- * 修复 issues - * 参数数据源解析 @DS("#last) - * 查找当前方法中最后一个参数的值当作数据源名称 - *
- * - * @Author: entfrm开发团队-王翔 - * @Date: 2022/2/19 - */ -public class LastParamDsProcessor extends DsProcessor { - - private static final String LAST_PREFIX = "#last"; - - /** - * 抽象匹配条件 匹配才会走当前执行器否则走下一级执行器 - * @param key DS注解里的内容 - * @return 是否匹配 - */ - @Override - public boolean matches(String key) { - if (key.startsWith(LAST_PREFIX)) { - // https://github.com/baomidou/dynamic-datasource-spring-boot-starter/issues/213 - DynamicDataSourceContextHolder.clear(); - return true; - } - return false; - } - - /** - * 抽象最终决定数据源 - * @param invocation 方法执行信息 - * @param key DS注解里的内容 - * @return 数据源名称 - */ - @Override - public String doDetermineDatasource(MethodInvocation invocation, String key) { - Object[] arguments = invocation.getArguments(); - return String.valueOf(arguments[arguments.length - 1]); - } - -} diff --git a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/dynamic/DynamicDataSource.java b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/dynamic/DynamicDataSource.java new file mode 100644 index 00000000..0280f21f --- /dev/null +++ b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/dynamic/DynamicDataSource.java @@ -0,0 +1,45 @@ +package com.cloud.kicc.common.datasource.dynamic; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *+ * 动态数据源 + *
+ * + * @Author: wangxiang4 + * @since: 2023/7/3 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +public class DynamicDataSource { + + /** + * 数据源ID + */ + private String id; + + /** + * 驱动类 + */ + private String driverClass; + + /** + * 数据库链接 + */ + private String url; + + /** + * 数据库账号名 + */ + private String username; + + /** + * 数据库密码 + */ + private String password; + +} diff --git a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/dynamic/DynamicDataSourceJdbcProvider.java b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/dynamic/DynamicDataSourceJdbcProvider.java new file mode 100644 index 00000000..8ebfb553 --- /dev/null +++ b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/dynamic/DynamicDataSourceJdbcProvider.java @@ -0,0 +1,91 @@ +package com.cloud.kicc.common.datasource.dynamic; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; +import com.cloud.kicc.common.datasource.support.DynamicDataSourceConstant; +import com.cloud.kicc.common.datasource.util.ConnUtil; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashMap; +import java.util.Map; + +/** + *+ * 动态数据源初始加载 + *
+ * + * @Author: wangxiang4 + * @since: 2023/7/3 + */ +public class DynamicDataSourceJdbcProvider extends AbstractJdbcDataSourceProvider { + + private final String driverClassName; + private final String url; + private final String username; + private final String password; + private final DynamicDataSourceProperties dynamicDataSourceProperties; + + public DynamicDataSourceJdbcProvider(DynamicDataSourceProperties dynamicDataSourceProperties, + String driverClassName, + String url, + String username, + String password) { + super(driverClassName, url, username, password); + this.dynamicDataSourceProperties = dynamicDataSourceProperties; + this.driverClassName = driverClassName; + this.url = url; + this.username = username; + this.password = password; + } + + @Override + protected Map- * 多数据源相关常量 - *
- * - * @Author: entfrm开发团队-王翔 - * @Date: 2022/2/19 - */ -public interface DataSourceConstants { - - /** - * 数据源名称 - */ - String DS_NAME = "name"; - - /** - * 默认数据源(master) - */ - String DS_MASTER = "master"; - - /** - * jdbc_url - */ - String DS_JDBC_URL = "url"; - - /** - * 用户名 - */ - String DS_USER_NAME = "username"; - - /** - * 密码 - */ - String DS_USER_PWD = "password"; - - /** - * 驱动包名称 - */ - String DS_DRIVER_CLASS_NAME = "driver_class_name"; - -} diff --git a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/support/DynamicDataSourceConstant.java b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/support/DynamicDataSourceConstant.java new file mode 100644 index 00000000..9145edcd --- /dev/null +++ b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/support/DynamicDataSourceConstant.java @@ -0,0 +1,48 @@ +package com.cloud.kicc.common.datasource.support; + +/** + *+ * 数据源常量 + *
+ * + * @Author: wangxiang4 + * @since: 2023/7/3 + */ +public interface DynamicDataSourceConstant { + + /** + * 数据源查询基础 + */ + String DYNAMIC_DATASOURCE_BASE_STATEMENT = "SELECT id, name, driver_class as driverClass, url, username, password FROM sys_datasource"; + + /** + * 数据源查询SQL + */ + String DYNAMIC_DATASOURCE_SINGLE_STATEMENT = DYNAMIC_DATASOURCE_BASE_STATEMENT + " WHERE del_flag = 0 AND id = ?"; + + /** + * 数据源查询SQL + */ + String DYNAMIC_DATASOURCE_GROUP_STATEMENT = DYNAMIC_DATASOURCE_BASE_STATEMENT + " WHERE del_flag = 0"; + + /** + * 数据源错误提示 + */ + String DYNAMIC_DATASOURCE_NOT_FOUND = "数据源信息有误,数据加载失败"; + + /** + * oracle驱动类 + */ + String ORACLE_DRIVER_CLASS = "oracle.jdbc.OracleDriver"; + + /** + * oracle校验 + */ + String ORACLE_VALIDATE_STATEMENT = "select 1 from dual"; + + /** + * 通用校验 + */ + String COMMON_VALIDATE_STATEMENT = "select 1"; + +} diff --git a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/util/ConnUtil.java b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/util/ConnUtil.java new file mode 100644 index 00000000..89bc84d8 --- /dev/null +++ b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/util/ConnUtil.java @@ -0,0 +1,49 @@ +package com.cloud.kicc.common.datasource.util; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +/** + *+ * 数据库工具类 + *
+ * + * @Author: wangxiang4 + * @since: 2023/7/3 + */ +public class ConnUtil { + + /** + * 测试数据库链接 + */ + public static Boolean dbTest(String driverClass, String url, String username, String password) throws Exception { + Connection conn = null; + try { + //测试驱动类 + Class.forName(driverClass); + //创建连接 + conn = DriverManager.getConnection(url, username, password); + conn.setAutoCommit(Boolean.FALSE); + return true; + } finally { + //关闭连接 + dbClose(conn); + } + } + + /** + * 关闭数据库链接 + */ + private static void dbClose(Connection conn) { + try { + //关闭数据源连接 + if (conn != null) { + conn.close(); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/util/DynamicDataSourceUtil.java b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/util/DynamicDataSourceUtil.java new file mode 100644 index 00000000..c36571c8 --- /dev/null +++ b/kicc-common/kicc-common-datasource/src/main/java/com/cloud/kicc/common/datasource/util/DynamicDataSourceUtil.java @@ -0,0 +1,112 @@ +package com.cloud.kicc.common.datasource.util; + +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; +import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; +import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; +import com.cloud.kicc.common.datasource.dynamic.DynamicDataSource; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.map.LRUMap; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Component; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + + +/** + *+ * 动态数据源核心处理工具 + *
+ * + * @Author: wangxiang4 + * @since: 2023/7/3 + */ +@Setter +@Slf4j +@Component +public class DynamicDataSourceUtil { + + public static DynamicRoutingDataSource dynamicRoutingDataSource; + public static DynamicDataSourceProperties dynamicDataSourceProperties; + private static DefaultDataSourceCreator defaultDataSourceCreator; + private static int MAX_DATASOURCE_COUNT = 300; + // 最多保存三百个数据源,按使用率淘汰 + private static LRUMap