commit 72b79413c0e4f951f411be75f574b8cc1fc154e1
Author: Cui YongXing <2835316714@qq.com>
Date: Wed Sep 11 09:39:48 2024 +0800
1
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..30d555d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,33 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/
+logs
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..0bc51bb
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,16 @@
+#指定构建镜像的起始镜像
+FROM anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/dragonwell:17.0.4.0.4.8-standard-ga-8.6
+#定义时区参数
+ENV TZ=Asia/Shanghai
+#设置时区
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone
+
+#挂载目录
+VOLUME ["/home/logs/cloud-etl-datasources"]
+
+#拷贝执行jar报
+COPY ./cloud-datasources-server/target/cloud-datasources.jar /home/app.jar
+
+ENTRYPOINT ["java","-Dfile.encoding=utf-8","-jar"]
+
+CMD ["/home/app.jar"]
diff --git a/cloud-datasources-client/pom.xml b/cloud-datasources-client/pom.xml
new file mode 100644
index 0000000..d376e59
--- /dev/null
+++ b/cloud-datasources-client/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ com.muyu
+ cloud-etl-datasources
+ 1.0.0
+
+
+ cloud-datasources-client
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ com.muyu
+ cloud-datasources-common
+
+
+ com.muyu
+ cloud-common-etl
+ 1.0.0
+ compile
+
+
+ com.muyu
+ cloud-datasources-remote
+ 1.0.0
+ compile
+
+
+
diff --git a/cloud-datasources-client/src/main/java/com/muyu/client/basic/DataSourceConfig.java b/cloud-datasources-client/src/main/java/com/muyu/client/basic/DataSourceConfig.java
new file mode 100644
index 0000000..f9501e7
--- /dev/null
+++ b/cloud-datasources-client/src/main/java/com/muyu/client/basic/DataSourceConfig.java
@@ -0,0 +1,7 @@
+package com.muyu.client.basic;
+
+import com.muyu.common.domain.DataSources;
+
+public interface DataSourceConfig {
+ public DataSources queryById(Long id);
+}
diff --git a/cloud-datasources-client/src/main/java/com/muyu/client/basic/basic/DataSourceConfig.java b/cloud-datasources-client/src/main/java/com/muyu/client/basic/basic/DataSourceConfig.java
new file mode 100644
index 0000000..d7e5de3
--- /dev/null
+++ b/cloud-datasources-client/src/main/java/com/muyu/client/basic/basic/DataSourceConfig.java
@@ -0,0 +1,7 @@
+package com.muyu.client.basic.basic;
+
+import com.muyu.common.domain.DataSources;
+
+public interface DataSourceConfig {
+ public DataSources queryById(Long id);
+}
diff --git a/cloud-datasources-client/src/main/java/com/muyu/client/basic/basic/impl/DataSourceConfigImpl.java b/cloud-datasources-client/src/main/java/com/muyu/client/basic/basic/impl/DataSourceConfigImpl.java
new file mode 100644
index 0000000..c068f59
--- /dev/null
+++ b/cloud-datasources-client/src/main/java/com/muyu/client/basic/basic/impl/DataSourceConfigImpl.java
@@ -0,0 +1,20 @@
+package com.muyu.client.basic.basic.impl;
+
+import com.muyu.client.basic.basic.DataSourceConfig;
+import com.muyu.common.domain.DataSources;
+import com.muyu.remote.DataSourcesRemote;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class DataSourceConfigImpl implements DataSourceConfig {
+
+ @Autowired
+ private DataSourcesRemote dataSourcesRemote;
+
+
+ @Override
+ public DataSources queryById(Long id) {
+ return dataSourcesRemote.queryById(id).getData();
+ }
+}
diff --git a/cloud-datasources-client/src/main/java/com/muyu/client/basic/impl/DataSourceConfigImpl.java b/cloud-datasources-client/src/main/java/com/muyu/client/basic/impl/DataSourceConfigImpl.java
new file mode 100644
index 0000000..9db0203
--- /dev/null
+++ b/cloud-datasources-client/src/main/java/com/muyu/client/basic/impl/DataSourceConfigImpl.java
@@ -0,0 +1,22 @@
+package com.muyu.client.basic.impl;
+
+import com.muyu.client.basic.DataSourceConfig;
+import com.muyu.common.domain.DataSources;
+import com.muyu.remote.DataSourcesRemote;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class DataSourceConfigImpl implements DataSourceConfig {
+
+ @Autowired
+ private DataSourcesRemote dataSourcesRemote;
+
+
+ @Override
+ public DataSources queryById(Long id) {
+ return dataSourcesRemote.queryById(id).getData();
+ }
+
+
+}
diff --git a/cloud-datasources-client/src/main/java/com/muyu/client/mysql/MySqlDataSource.java b/cloud-datasources-client/src/main/java/com/muyu/client/mysql/MySqlDataSource.java
new file mode 100644
index 0000000..d67e9ce
--- /dev/null
+++ b/cloud-datasources-client/src/main/java/com/muyu/client/mysql/MySqlDataSource.java
@@ -0,0 +1,178 @@
+package com.muyu.client.mysql;
+
+
+import com.muyu.client.basic.DataSourceConfig;
+import com.muyu.common.core.domain.Result;
+import com.muyu.common.core.utils.SpringUtils;
+import com.muyu.common.data.base.BaseDataAbsSource;
+import com.muyu.common.domain.DataSources;
+
+import com.muyu.etl.domain.DataValue;
+import com.muyu.etl.enums.DataType;
+
+
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.sql.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+@Log4j2
+@Component
+public class MySqlDataSource extends BaseDataAbsSource {
+
+
+
+ @Autowired
+ private DataSourceConfig dataSourcesRemote;
+
+
+ @Override
+ public DataValue getDataValue() {
+
+ return null;
+ }
+
+ @Override
+ public DataValue[] getRow () {
+// MySqlQuery query = getQuery();
+// String sql = query.getSql();
+// Long dataSourceId = query.getDataSourceId();
+// ConcurrentHashMap map = new ConcurrentHashMap<>();
+//
+// DataSources dataSources = dataSourcesService.getById(dataSourceId);
+//
+// HikariConfig hikariConfig = new HikariConfig();
+// hikariConfig.setPoolName("HikariCP 连接池");
+// hikariConfig.setDriverClassName(dataSources.getDriverName());
+// hikariConfig.setJdbcUrl(dataSources.getUrl(dataSources)); // 修正这里
+// hikariConfig.setUsername(dataSources.getUserName());
+// hikariConfig.setPassword(dataSources.getUserPwd());
+// hikariConfig.setMinimumIdle(2);
+// hikariConfig.setMaximumPoolSize(10);
+//
+// HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);
+//
+// DataValue[] dataValues = null;
+//
+// try {
+// PreparedStatement preparedStatement = conn.prepareStatement(sql);
+// ResultSet resultSet = preparedStatement.executeQuery();
+// ResultSetMetaData metaData = resultSet.getMetaData();
+// int columnCount = metaData.getColumnCount();
+// if (resultSet.next()){
+// for (int i = 1; i < columnCount; i++) {
+// if (resultSet.isFirst()){
+// String columnTypeName = metaData.getColumnTypeName(i);
+// DatabaseMetaData metadataColumns = conn.getMetaData();
+// ResultSet columns = metadataColumns.getColumns(null, null, metaData.getTableName(i), metaData.getColumnName(i));
+// String remarks =null;
+// while (columns.next()){
+// remarks = columns.getString("REMARKS");
+// log.info("字段备注:"+remarks);
+// }
+// DataValue build = DataValue.builder()
+// .key(metaData.getColumnName(i))
+// .label(remarks)
+// .value(resultSet.getObject(i, DataType.convertType(columnTypeName)))
+// .type(DataType.findBySqlType(columnTypeName))
+// .build();
+// map.put(i,build);
+// dataValues[i-1]=build;
+// }
+// }
+// }
+//
+//
+// } catch (SQLException e) {
+// throw new RuntimeException(e);
+// }
+// return dataValues;
+ return null;
+ }
+
+ @Override
+ public DataValue[][] getRows () {
+
+ MySqlQuery query = getQuery();
+ Integer one = Math.toIntExact(query.getOne());
+ Integer two = query.getTwo();
+ String sql = query.getSql();
+ Long dataSourceId = query.getDataSourceId();
+ ConcurrentHashMap map = new ConcurrentHashMap<>();
+
+ DataSources dataSources = dataSourcesRemote.queryById(dataSourceId);
+
+ HikariConfig hikariConfig = new HikariConfig();
+ hikariConfig.setPoolName("HikariCP 连接池");
+ hikariConfig.setDriverClassName(dataSources.getDriverName());
+ hikariConfig.setJdbcUrl(dataSources.getUrl(dataSources)); // 修正这里
+ hikariConfig.setUsername(dataSources.getUserName());
+ hikariConfig.setPassword(dataSources.getUserPwd());
+ hikariConfig.setMinimumIdle(2);
+ hikariConfig.setMaximumPoolSize(10);
+
+ DataValue[][] dataValues = new DataValue[one][two];
+
+ HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);
+ try {
+ Connection conn = hikariDataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery();
+ ResultSetMetaData metaData = resultSet.getMetaData();
+ int columnCount = metaData.getColumnCount();
+ int c = 0;
+ while (resultSet.next()){
+ for (int i = 1; i <= columnCount; i++) {
+ if (resultSet.isFirst()){
+ String columnTypeName = metaData.getColumnTypeName(i);
+ DatabaseMetaData metaDataColumns = conn.getMetaData();
+ ResultSet columns = metaDataColumns.getColumns(null, null, metaData.getTableName(i), metaData.getColumnName(i));
+ String remarks =null;
+
+ while (columns.next()){
+ remarks = columns.getString("REMARKS");
+
+ log.info("字段备注:"+remarks);
+ }
+ DataValue build = DataValue.builder()
+ .key(metaData.getColumnName(i))
+ .label(remarks)
+ .value(resultSet.getObject(i, DataType.convertType(columnTypeName)))
+ .type(DataType.findBySqlType(columnTypeName))
+ .build();
+ map.put(i,build);
+ dataValues[c][i-1]=build;
+ }else {
+ DataValue build = DataValue.builder()
+ .key(metaData.getColumnName(i))
+ .label(map.get(i).getLabel())
+ .value(resultSet.getObject(i, map.get(i).getType().getTargetType()))
+ .type(map.get(i).getType())
+ .build();
+ dataValues[c][i-1]=build;
+ }
+ }
+ c++;
+ }
+
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }finally {
+ close(hikariDataSource); // 关闭数据源
+ }
+
+ return dataValues;
+ }
+ private static void close(HikariDataSource dataSource) {
+ if (dataSource != null) {
+ dataSource.close();
+ }
+ }
+
+}
diff --git a/cloud-datasources-client/src/main/java/com/muyu/client/mysql/MySqlQuery.java b/cloud-datasources-client/src/main/java/com/muyu/client/mysql/MySqlQuery.java
new file mode 100644
index 0000000..885b3a6
--- /dev/null
+++ b/cloud-datasources-client/src/main/java/com/muyu/client/mysql/MySqlQuery.java
@@ -0,0 +1,25 @@
+package com.muyu.client.mysql;
+
+import com.muyu.common.data.base.BaseQuery;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MySqlQuery extends BaseQuery {
+
+ private String sql;
+
+ private String params;
+
+ private Long one;
+
+ private Integer two;
+}
diff --git a/cloud-datasources-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/cloud-datasources-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000..aec4a62
--- /dev/null
+++ b/cloud-datasources-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1,2 @@
+com.muyu.client.mysql.MySqlDataSource
+com.muyu.client.basic.impl.DataSourceConfigImpl
diff --git a/cloud-datasources-common/pom.xml b/cloud-datasources-common/pom.xml
new file mode 100644
index 0000000..5028802
--- /dev/null
+++ b/cloud-datasources-common/pom.xml
@@ -0,0 +1,42 @@
+
+
+ 4.0.0
+
+ com.muyu
+ cloud-etl-datasources
+ 1.0.0
+
+
+ cloud-datasources-common
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+ com.muyu
+ cloud-common-core
+
+
+ mysql
+ mysql-connector-java
+ 8.0.33
+
+
+
+ redis.clients
+ jedis
+ 3.5.1
+
+
+ com.muyu
+ cloud-common-etl
+ 1.0.0
+
+
+
+
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseDataAbsSource.java b/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseDataAbsSource.java
new file mode 100644
index 0000000..ca8c3e6
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseDataAbsSource.java
@@ -0,0 +1,21 @@
+package com.muyu.common.data.base;
+
+/**
+ * @Author:zhangzhihao
+ * @name:BaseDataAbsSource
+ * @Date:2024/8/28 19:07
+ * 数据接入抽象类
+ */
+public abstract class BaseDataAbsSource implements BaseDataSource{
+
+
+ @Override
+ public void setQuery(BaseQuery baseQuery){
+ BaseQueryHandler.set(baseQuery);
+ }
+
+ @Override
+ public T getQuery(){
+ return BaseQueryHandler.get();
+ }
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseDataSource.java b/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseDataSource.java
new file mode 100644
index 0000000..7c3df5a
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseDataSource.java
@@ -0,0 +1,28 @@
+package com.muyu.common.data.base;
+
+/**
+ * @Author:zhangzhihao
+ * @name:BaseDataSource
+ * @Date:2024/8/28 18:50
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+
+import com.muyu.etl.domain.DataValue;
+
+/**
+ * 数据源基准
+ */
+public interface BaseDataSource {
+
+ public void setQuery(BaseQuery baseQuery);
+
+ public T getQuery();
+
+ public DataValue getDataValue();
+
+ DataValue[] getRow();
+
+ DataValue[][] getRows();
+
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseQuery.java b/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseQuery.java
new file mode 100644
index 0000000..b576c5d
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseQuery.java
@@ -0,0 +1,20 @@
+package com.muyu.common.data.base;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * @Author:zhangzhihao
+ * @name:BaseQuery
+ * @Date:2024/8/28 18:54
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BaseQuery {
+ private Long dataSourceId;
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseQueryHandler.java b/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseQueryHandler.java
new file mode 100644
index 0000000..9d89612
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/data/base/BaseQueryHandler.java
@@ -0,0 +1,24 @@
+package com.muyu.common.data.base;
+
+/**
+ * @Author:zhangzhihao
+ * @name:BaseQueryHandler
+ * @Date:2024/8/28 19:02
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+
+/**
+ * 基础查询
+ */
+public class BaseQueryHandler {
+ private static final ThreadLocal BASE_QUERY_THREAD_LOCAL = new ThreadLocal<>();
+
+ public static void set(BaseQuery baseQuery){
+ BASE_QUERY_THREAD_LOCAL.set(baseQuery);
+ }
+
+ public static T get(){
+ return (T) BASE_QUERY_THREAD_LOCAL.get();
+ }
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/data/redis/RedisDataSource.java b/cloud-datasources-common/src/main/java/com/muyu/common/data/redis/RedisDataSource.java
new file mode 100644
index 0000000..6fd05db
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/data/redis/RedisDataSource.java
@@ -0,0 +1,23 @@
+package com.muyu.common.data.redis;
+
+
+import com.muyu.common.data.base.BaseDataAbsSource;
+import com.muyu.etl.domain.DataValue;
+
+
+public class RedisDataSource extends BaseDataAbsSource {
+ @Override
+ public DataValue getDataValue () {
+ return null;
+ }
+
+ @Override
+ public DataValue[] getRow () {
+ return new DataValue[0];
+ }
+
+ @Override
+ public DataValue[][] getRows () {
+ return new DataValue[0][];
+ }
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/data/redis/RedisQuery.java b/cloud-datasources-common/src/main/java/com/muyu/common/data/redis/RedisQuery.java
new file mode 100644
index 0000000..668aa26
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/data/redis/RedisQuery.java
@@ -0,0 +1,8 @@
+package com.muyu.common.data.redis;
+
+
+import com.muyu.common.data.base.BaseQuery;
+
+
+public class RedisQuery extends BaseQuery {
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/AssetAccredit.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/AssetAccredit.java
new file mode 100644
index 0000000..c00c5dc
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/AssetAccredit.java
@@ -0,0 +1,57 @@
+package com.muyu.common.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.muyu.common.core.annotation.Excel;
+import com.muyu.common.core.web.domain.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * @Author:zhangzhihao
+ * @name:assetAccredit
+ * @Date:2024/8/30 9:29
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@SuperBuilder
+@TableName(value="asset_accredit")
+public class AssetAccredit extends BaseEntity {
+ /**
+ * 主键
+ */
+ @TableId(type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 接入id
+ */
+ @Excel(name = "数据源ID")
+ private Long basicId;
+
+ /**
+ * 表id
+ */
+ @Excel(name = "表ID")
+ private Long tableId;
+
+ /**
+ * 部门id
+ */
+ @Excel(name = "部门ID")
+ private Long deptId;
+
+ /**
+ * 用户id
+ */
+ @Excel(name = "用户ID")
+ private Long userId;
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/DataSources.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/DataSources.java
new file mode 100644
index 0000000..565512c
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/DataSources.java
@@ -0,0 +1,119 @@
+package com.muyu.common.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.muyu.common.core.annotation.Excel;
+import com.muyu.common.pool.base.BaseConfig;
+import com.muyu.common.core.web.domain.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * 数据来源表;
+ * @author : http://www.chiner.pro
+ * @date : 2024-8-21
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+@TableName(value="data_sources")
+public class DataSources extends BaseEntity {
+
+ /** id */
+ @TableId(type = IdType.AUTO)
+ private Long id ;
+
+ /** 数据来源类型 */
+ @Excel(name = "数据来源类型")
+ private String type ;
+
+
+ /** 数据来源名称 */
+ @Excel(name = "数据来源名称")
+ private String name ;
+
+ /** 数据来源地址ip */
+ @Excel(name = "数据来源地址ip")
+ private String ip ;
+
+ /** 来源地址端口号 */
+ @Excel(name = "来源地址端口号")
+ private String port ;
+
+ /** 存放数据库名称 */
+ @Excel(name = "存放数据库名称")
+ private String databaseName ;
+
+ /** 数据库登录名 */
+ @Excel(name = "数据库登录名")
+ private String userName ;
+
+ /** 数据库登录密码 */
+ @Excel(name = "数据库登录密码")
+ private String userPwd ;
+
+ /** 参数 */
+ @Excel(name = "连接参数配置")
+ private String param ;
+
+ /** 状态 1初始化 2不初始化 */
+ @Excel(name = "是否初始化:1初始化,2不初始化")
+ private Integer status ;
+
+ /** 初始连接数量 */
+ @Excel(name = "初始连接数量")
+ private Integer initCount;
+
+ /** 最大连接数量 */
+ @Excel(name = "最大连接数量")
+ private Integer maxCount;
+
+ /** 最大等待时间 */
+ @Excel(name = "最大等待时间")
+ private Integer maxTime;
+
+ /** 最大等待次数 */
+ @Excel(name = "最大等待次数")
+ private Integer maxFrequency;
+
+ /** 驱动 com.mysql.cj.jdbc.Driver */
+ @Excel(name = "连接驱动")
+ private String driverName;
+
+ /**
+ * 获取mysql数据库连接
+ * @return
+ */
+ public String getUrl(DataSources dataSources){
+
+ StringBuilder urlSb = new StringBuilder(BaseConfig.MYSQLJDBCPRO);
+ urlSb.append(dataSources.ip);//拼接ip
+ urlSb.append(":");
+ urlSb.append(dataSources.port); //拼接端口
+ urlSb.append("/");
+ urlSb.append(dataSources.databaseName);//拼接数据库
+ urlSb.append("?");
+ urlSb.append(dataSources.param);//useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+ return urlSb.toString();
+ }
+ /**
+ * 获取mysql数据库连接
+ * @return
+ */
+ public String getOracleUrl(DataSources dataSources){
+
+ StringBuilder urlSb = new StringBuilder(BaseConfig.ORACLEJDBCPRO);
+ urlSb.append(dataSources.ip);//拼接ip
+ urlSb.append(":");
+ urlSb.append(dataSources.port); //拼接端口
+ urlSb.append(":");
+ urlSb.append(dataSources.getParam());//PDB
+ return urlSb.toString();
+ }
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/DictionaryData.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/DictionaryData.java
new file mode 100644
index 0000000..3e5246a
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/DictionaryData.java
@@ -0,0 +1,50 @@
+package com.muyu.common.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.muyu.common.core.annotation.Excel;
+import com.muyu.common.core.web.domain.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DictionaryData
+ * @Date:2024/8/25 9:39
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+@TableName(value="dictionary_data")
+public class DictionaryData extends BaseEntity {
+
+ /**
+ * id
+ * */
+ @Excel(name = "主键ID")
+ private Long id;
+ /**
+ * 字典表id
+ * */
+ @Excel(name = "字典表ID")
+ private Long dictionaryId;
+ /**
+ * 字典标签
+ * */
+ @Excel(name = "字典标签")
+ private String label;
+ /**
+ * 字典值
+ * */
+ @Excel(name = "字典值")
+ private String val;
+
+ @Excel(name = "是否修改")
+ private Boolean isEdit=false;
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/InvokeLog.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/InvokeLog.java
new file mode 100644
index 0000000..f6492ad
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/InvokeLog.java
@@ -0,0 +1,35 @@
+package com.muyu.common.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.muyu.common.core.annotation.Excel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @Author:zhangzhihao
+ * @name:addInvoke
+ * @Date:2024/9/4 20:26
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class InvokeLog {
+ @Excel(name = "主键")
+ @TableId
+ private Long id;
+
+ @Excel(name = "用户ID")
+ private Long userId;
+
+ @Excel(name = "调用方法")
+ private String methodName;
+
+ @Excel(name = "调用时间")
+ private Date time;
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/Structure.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/Structure.java
new file mode 100644
index 0000000..d871537
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/Structure.java
@@ -0,0 +1,78 @@
+package com.muyu.common.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.muyu.common.core.annotation.Excel;
+import com.muyu.common.core.web.domain.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+@TableName(value ="structure",autoResultMap = true) //数据库表相关
+public class Structure extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 主键 */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /** 表id */
+ @Excel(name = "表id")
+ private Long tableId;
+
+ /** 字段名称 */
+ @Excel(name = "字段名称")
+ private String columnName;
+
+ /** 字段注释 */
+ @Excel(name = "字段注释")
+ private String columnRemark;
+
+ /** 是否主键 'Y'是主键 'N'不是主键 */
+ @Excel(name = "是否主键 'Y'是主键 'N'不是主键")
+ private String isPrimary;
+
+ /** 数据类型 */
+ @Excel(name = "数据类型")
+ private String columnType;
+
+ /** 映射类型 */
+ @Excel(name = "映射类型")
+ private String javaType;
+
+ /** 字段长度 */
+ @Excel(name = "字段长度")
+ private String columnLength;
+
+ /** 小数位数 */
+ @Excel(name = "小数位数")
+ private String columnDecimals;
+
+ /** 是否为空 'Y'是 'N'不是 */
+ @Excel(name = "是否为空 'Y'是 'N'不是")
+ private String isNull;
+
+ /** 默认值 */
+ @Excel(name = "默认值")
+ private String defaultValue;
+
+ /** 是否字典 'Y'是 'N'不是 */
+ @Excel(name = "是否字典 'Y'是 'N'不是")
+ private String isDictionary;
+
+ /** 映射字典 */
+ @Excel(name = "映射字典")
+ private String dictionaryTable;
+
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/TableInfo.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/TableInfo.java
new file mode 100644
index 0000000..f511953
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/TableInfo.java
@@ -0,0 +1,67 @@
+package com.muyu.common.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.muyu.common.core.annotation.Excel;
+import com.muyu.common.core.web.domain.BaseEntity;
+import com.muyu.common.domain.resp.TableInfoResp;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+@TableName(value ="table_info") //数据库表相关
+public class TableInfo extends BaseEntity {
+
+
+
+ /** 主键 */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ @Excel(name = "数据源ID")
+ private Long basicId;
+
+ /** 表名称/数据库 */
+ @Excel(name = "表名称/数据库")
+ private String tableName;
+
+ /** 表备注 */
+ @Excel(name = "表备注")
+ private String tableRemark;
+
+ /** 表备注 */
+ @Excel(name = "数据来源类型")
+ private String type;
+
+ /** 数据量 */
+ @Excel(name = "数据量")
+ private Long dataNum;
+
+ /** 是否核心 'Y'是 'N'不是 */
+ @Excel(name = "是否核心 'Y'是 'N'不是")
+ private String isCenter;
+
+ @Excel(name = "父ID")
+ private Long parentId;
+
+
+ public static TableInfoResp toTableInfoResp(TableInfo tableInfo) {
+ return TableInfoResp.builder()
+ .id(tableInfo.id)
+ .basicId(tableInfo.basicId)
+ .tableName(tableInfo.tableName)
+ .tableRemark(tableInfo.tableRemark)
+ .isCenter(tableInfo.isCenter)
+ .dataNum(tableInfo.dataNum)
+ .build();
+ }
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/req/AssetAccreditReq.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/req/AssetAccreditReq.java
new file mode 100644
index 0000000..b1248b5
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/req/AssetAccreditReq.java
@@ -0,0 +1,38 @@
+package com.muyu.common.domain.req;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * @Author:zhangzhihao
+ * @name:assetAccreditReq
+ * @Date:2024/8/30 9:31
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@SuperBuilder
+public class AssetAccreditReq {
+ /**
+ * 接入id
+ */
+ private Long basicId;
+
+ /**
+ * 表id
+ */
+ private Long tableId;
+
+ /**
+ * 部门id
+ */
+ private Long deptId;
+
+ /**
+ * 用户id
+ */
+ private Long userId;
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/req/AssetModel.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/req/AssetModel.java
new file mode 100644
index 0000000..442c99c
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/req/AssetModel.java
@@ -0,0 +1,103 @@
+package com.muyu.common.domain.req;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.muyu.common.core.web.domain.BaseEntity;
+import com.muyu.common.domain.DictionaryData;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:AssetModel
+ * @Date:2024/8/25 9:36
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+@TableName(value="asset_model")
+public class AssetModel extends BaseEntity {
+
+ /**
+ *主键
+ *
+ * **/
+ private Long id;
+ /**
+ *数据资产id
+ *
+ * **/
+ private Long dataAssetId;
+ /**
+ *字段名字
+ *
+ * **/
+ private String name;
+ /**
+ *
+ *字段备注
+ * **/
+ private String comment;
+ /**
+ *
+ *是否主键
+ * **/
+ private String isPrimaryKey;
+ /**
+ *数据类型
+ *
+ * **/
+ private String type;
+ /**
+ *映射数据字典
+ *
+ * **/
+ private String mappingType;
+ /**
+ *长度
+ *
+ * **/
+ private String length;
+ /**
+ *小数位
+ *
+ * **/
+ private String decimalPlaces;
+ /**
+ *
+ *是否不可以为空
+ * **/
+ private String isNull;
+ /**
+ *
+ *是否是字典
+ * **/
+ private String isDict;
+ /**
+ *是否是默认值
+ *
+ * **/
+ private String defaultValue;
+ /**
+ *字典key
+ *
+ * **/
+ private String dictKey;
+ /**
+ *
+ * 字典key
+ * */
+ private Long dictionaryId;
+
+ /**
+ * 字典信息
+ * */
+ private List dictionaryDataList;
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/req/DataSourcesReq.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/req/DataSourcesReq.java
new file mode 100644
index 0000000..86b4f49
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/req/DataSourcesReq.java
@@ -0,0 +1,28 @@
+package com.muyu.common.domain.req;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataSourcesReq
+ * @Date:2024/8/21 20:55
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class DataSourcesReq {
+
+ /** 数据来源名称 */
+ private String name ;
+
+ /** 存放数据库名称 */
+ private String databaseName ;
+
+ private Integer pageNum=1;
+ private Integer pageSize=3;
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/resp/AssetAccreditResp.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/resp/AssetAccreditResp.java
new file mode 100644
index 0000000..4824006
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/resp/AssetAccreditResp.java
@@ -0,0 +1,28 @@
+package com.muyu.common.domain.resp;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author:zhangzhihao
+ * @name:AssetAccreditResp
+ * @Date:2024/8/31 19:02
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class AssetAccreditResp {
+
+
+
+ private Long basicId;
+
+ private Long tableId;
+
+
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/domain/resp/TableInfoResp.java b/cloud-datasources-common/src/main/java/com/muyu/common/domain/resp/TableInfoResp.java
new file mode 100644
index 0000000..e48f3d5
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/domain/resp/TableInfoResp.java
@@ -0,0 +1,47 @@
+package com.muyu.common.domain.resp;
+
+import com.muyu.common.core.annotation.Excel;
+import com.muyu.common.domain.TableInfo;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class TableInfoResp {
+
+ /**
+ * id
+ */
+ private Long id;
+
+ private Long basicId;
+
+ /**
+ * 表名称/数据库
+ */
+ private String tableName;
+
+ /**
+ * 表备注
+ */
+ private String tableRemark;
+
+ /** 数据量 */
+ private Long dataNum;
+
+ /** 是否核心 'Y'是 'N'不是 */
+ private String isCenter;
+
+ /**
+ * 子内容
+ */
+ private List children;
+
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/pool/BasePool.java b/cloud-datasources-common/src/main/java/com/muyu/common/pool/BasePool.java
new file mode 100644
index 0000000..7ef3cc2
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/pool/BasePool.java
@@ -0,0 +1,43 @@
+package com.muyu.common.pool;
+
+/**
+ * @Author:zhangzhihao
+ * @name:BasePool
+ * @Date:2024/8/22 17:42
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ * 提供了一个连接池的准则
+ */
+public interface BasePool {
+
+ /**
+ * 初始化
+ */
+ public void init();
+
+ /**
+ * 获取连接
+ * @return
+ */
+ public T getConn();
+
+ /**
+ * 归还连接
+ * @param conn
+ */
+ public void replease(T conn);
+
+ /**
+ * 创建连接
+ * @return
+ */
+ public T createConn();
+
+ /**
+ * 关闭连接
+ */
+ public void closeConn();
+
+
+
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/pool/HikariPool.java b/cloud-datasources-common/src/main/java/com/muyu/common/pool/HikariPool.java
new file mode 100644
index 0000000..c0c09f2
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/pool/HikariPool.java
@@ -0,0 +1,30 @@
+package com.muyu.common.pool;
+
+
+import com.muyu.common.domain.DataSources;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import jakarta.validation.constraints.NotNull;
+
+//连接池供所有连接是调用
+public class HikariPool {
+ public static HikariDataSource instance = null;
+ @NotNull
+ public static synchronized HikariDataSource getHikariDataSource(DataSources dataSources) {
+ if(instance == null) {
+ HikariConfig hikariConfig = new HikariConfig();
+ hikariConfig.setPoolName("HikariCP 连接池");
+ hikariConfig.setDriverClassName(dataSources.getDriverName());
+ hikariConfig.setJdbcUrl(dataSources.getUrl(dataSources));
+ hikariConfig.setUsername(dataSources.getUserName());
+ hikariConfig.setPassword(dataSources.getUserPwd());
+ hikariConfig.setMaximumPoolSize(10);
+ hikariConfig.setMinimumIdle(2);
+ hikariConfig.setConnectionTimeout(60000); // 连接超时时间(毫秒)
+ hikariConfig.setIdleTimeout(600000);
+ instance = new HikariDataSource(hikariConfig);
+ }
+ return instance;
+ }
+}
+
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/pool/MysqlPool.java b/cloud-datasources-common/src/main/java/com/muyu/common/pool/MysqlPool.java
new file mode 100644
index 0000000..3a672eb
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/pool/MysqlPool.java
@@ -0,0 +1,218 @@
+package com.muyu.common.pool;
+
+import com.muyu.common.domain.DataSources;
+import com.muyu.common.pool.base.BaseConfig;
+import com.muyu.common.pool.exeption.MysqlConnException;
+import lombok.extern.log4j.Log4j2;
+
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Queue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @Author:zhangzhihao
+ * @name:MysqlPool
+ * @Date:2024/8/22 17:21
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ * Mysql连接池信息
+ */
+@Log4j2
+public class MysqlPool implements BasePool {
+
+ /**
+ * 等待队列
+ */
+ private Queue mysqlConnQueue = null;
+
+ /**
+ * 活动队列
+ */
+ private Queue activeMysqlConnQueue =null;
+
+
+ /**
+ * 记录队列连接总数
+ */
+ private AtomicInteger count = new AtomicInteger();
+
+ /**
+ * mysql基础配置
+ */
+ public DataSources dataSources;
+
+
+ /**
+ * 实例化连接池,加载驱动
+ * @param dataSources
+ */
+ public MysqlPool(DataSources dataSources){
+ log.info("MySQL连接池实例化完成");
+ this.dataSources=dataSources;
+ BaseConfig.driver(dataSources.getDriverName());
+ }
+
+ /**
+ * 初始化连接池
+ */
+ @Override
+ public void init() {
+ Integer maxCount = this.dataSources.getMaxCount();
+ Integer initCount = this.dataSources.getInitCount();
+ this.mysqlConnQueue = new LinkedBlockingQueue(maxCount);
+ this.activeMysqlConnQueue=new LinkedBlockingQueue(maxCount);
+
+
+ for (Integer i = 0; i < initCount; i++) {
+
+ this.mysqlConnQueue.offer(createConn());
+ count.incrementAndGet();
+ }
+ log.info("MySQL连接池初始化完成");
+ }
+
+ /**
+ *1.获取当前的毫秒 用来计算获取连接是否超时
+ * 2.判断队列当中是否还有空闲连接
+ * 3如何有连接我们获取连接进行返回了
+ * 4如何没有 判断是否达到最大的连接数
+ * 5如何达到最大连接数量则进行等待(自旋)
+ * 6如何没有达到最大连接数量额进行创建一个连接
+ * 7、放到使用队列当中,然后在进行返回
+ * 8如果连接超时的话则进行抛出异常
+ * @return
+ */
+ @Override
+ public Connection getConn() {
+ long startTime = System.currentTimeMillis();
+ while (true){
+ //从空闲队列当中取出放入活动队列
+ Connection conn = this.mysqlConnQueue.poll();
+ if (conn!=null){
+ this.activeMysqlConnQueue.offer(conn);
+ return conn;
+ }
+
+ //如果当前的连接数量小于最大的连接数量的时候就进行创建新的连接
+ if (count.get() < dataSources.getMaxCount()){
+ Connection mysqlConn = createConn();
+ this.activeMysqlConnQueue.offer(mysqlConn);
+ count.incrementAndGet();
+ return mysqlConn;
+ }
+
+ if ((System.currentTimeMillis() - startTime)>this.dataSources.getMaxTime()){
+ throw new MysqlConnException("连接超时!");
+ }
+ // 等待一段时间再尝试
+ try {
+ TimeUnit.MILLISECONDS.sleep(100);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException("等待连接时中断", e);
+ }
+ }
+ }
+
+
+ /**
+ * 归还连接
+ * @param conn
+ */
+ @Override
+ public void replease(Connection conn) {
+ //删除活动队列当中的连接
+ if (this.activeMysqlConnQueue.remove(conn)){
+ //把这个连接放入到空闲队列当中
+ this.mysqlConnQueue.offer(conn);
+ }
+ }
+
+
+ /**
+ * 获取mysql连接信息
+ * @return
+ */
+ @Override
+ public Connection createConn(){
+ String url = this.dataSources.getUrl(dataSources);
+ String userName = this.dataSources.getUserName();
+ String userPwd = this.dataSources.getUserPwd();
+ Connection mysqlConn=null;
+ try {
+ mysqlConn = DriverManager.getConnection(url, userName, userPwd);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ log.info("初始化了一个数据库连接:{ip:"+this.dataSources.getIp()+" port:"+this.dataSources.getPort()+"databaseName"+this.dataSources.getDatabaseName()+" }");
+ return mysqlConn;
+ }
+
+ @Override
+ public void closeConn() {
+ closeBaseConn();
+ closeActiveConn();
+ }
+
+
+ /**
+ * 关闭空闲连接
+ */
+ public void closeBaseConn() {
+ //从空闲连接当中拿出一个连接 准备进行关闭
+ //如何拿出的这个链接为null 表示以列当中没有连接信息
+ Connection poll = this.mysqlConnQueue.poll();
+ if (poll!=null){
+ try {
+ poll.close();
+ } catch (SQLException e) {
+ try {
+ //判断这个接是否被关闭了,如果连接被关闭则不需要放入队列当中
+ //如何这个链接没有被关闭 则放入队列当中 尝试下次关闭
+ if (!poll.isClosed()){
+ this.mysqlConnQueue.offer(poll);
+ }
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }finally {
+ closeBaseConn();
+ }
+
+ }
+
+ }
+ /**
+ * 关闭活动连接
+ */
+ public void closeActiveConn() {
+ //从空闲连接当中拿出一个连接 准备进行关闭
+ //如何拿出的这个链接为null 表示以列当中没有连接信息
+ Connection poll = this.activeMysqlConnQueue.poll();
+ if (poll!=null){
+ try {
+ poll.close();
+ } catch (SQLException e) {
+ try {
+ //判断这个接是否被关闭了,如果连接被关闭则不需要放入队列当中
+ //如何这个链接没有被关闭 则放入队列当中 尝试下次关闭
+ if (!poll.isClosed()){
+ this.activeMysqlConnQueue.offer(poll);
+ }
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }finally {
+ closeActiveConn();
+ }
+ }
+
+ }
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/pool/OraclePool.java b/cloud-datasources-common/src/main/java/com/muyu/common/pool/OraclePool.java
new file mode 100644
index 0000000..ac8ad7c
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/pool/OraclePool.java
@@ -0,0 +1,211 @@
+package com.muyu.common.pool;
+
+import com.muyu.common.domain.DataSources;
+import com.muyu.common.pool.base.BaseConfig;
+import com.muyu.common.pool.exeption.OracleConnException;
+import lombok.extern.log4j.Log4j2;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Queue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @Author:zhangzhihao
+ * @name:OraclePool
+ * @Date:2024/8/22 17:21
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ * Oracle连接池信息
+ */
+@Log4j2
+public class OraclePool implements BasePool {
+
+ /**
+ * 等待队列
+ */
+ private Queue oracleConnQueue = null;
+
+ /**
+ * 活动队列
+ */
+ private Queue activeOracleConnQueue =null;
+
+
+ /**
+ * 记录队列连接总数
+ */
+ private AtomicInteger count = new AtomicInteger();
+
+ /**
+ * oracle基础配置
+ */
+ public DataSources dataSources;
+
+
+ /**
+ * 实例化连接池,加载驱动
+ * @param dataSources
+ */
+ public OraclePool(DataSources dataSources){
+ log.info("oracle连接池实例化完成");
+ this.dataSources=dataSources;
+ BaseConfig.driver(dataSources.getDriverName());
+ }
+
+ /**
+ * 初始化连接池
+ */
+ @Override
+ public void init() {
+ Integer maxCount = this.dataSources.getMaxCount();
+ Integer initCount = this.dataSources.getInitCount();
+ this.oracleConnQueue = new LinkedBlockingQueue(maxCount);
+ this.activeOracleConnQueue=new LinkedBlockingQueue(maxCount);
+
+
+ for (Integer i = 0; i < initCount; i++) {
+
+ this.oracleConnQueue.offer(createConn());
+ count.incrementAndGet();
+ }
+ log.info("oracle连接池初始化完成");
+ }
+
+ /**
+ *1.获取当前的毫秒 用来计算获取连接是否超时
+ * 2.判断队列当中是否还有空闲连接
+ * 3如何有连接我们获取连接进行返回了
+ * 4如何没有 判断是否达到最大的连接数
+ * 5如何达到最大连接数量则进行等待(自旋)
+ * 6如何没有达到最大连接数量额进行创建一个连接
+ * 7、放到使用队列当中,然后在进行返回
+ * 8如果连接超时的话则进行抛出异常
+ * @return
+ */
+ @Override
+ public Connection getConn() {
+ long startTime = System.currentTimeMillis();
+ while (true){
+ //从空闲队列当中取出放入活动队列
+ Connection conn = this.oracleConnQueue.poll();
+ if (conn!=null){
+ this.activeOracleConnQueue.offer(conn);
+ return conn;
+ }
+
+ //如果当前的连接数量小于最大的连接数量的时候就进行创建新的连接
+ if (count.get() < dataSources.getMaxCount()){
+ Connection oracleConn = createConn();
+ this.activeOracleConnQueue.offer(oracleConn);
+ count.incrementAndGet();
+ return oracleConn;
+ }
+
+ if ((System.currentTimeMillis() - startTime)>this.dataSources.getMaxTime()){
+ throw new OracleConnException("连接超时!");
+ }
+ }
+ }
+
+
+ /**
+ * 归还连接
+ * @param conn
+ */
+ @Override
+ public void replease(Connection conn) {
+ //删除活动队列当中的连接
+ if (this.activeOracleConnQueue.remove(conn)){
+ //把这个连接放入到空闲队列当中
+ this.oracleConnQueue.offer(conn);
+ }
+ }
+
+
+ /**
+ * 获取oracle连接信息
+ * @return
+ */
+ @Override
+ public Connection createConn(){
+ String url = this.dataSources.getOracleUrl(dataSources);
+ String userName = this.dataSources.getUserName();
+ String userPwd = this.dataSources.getUserPwd();
+ Connection oracleConn=null;
+ try {
+ oracleConn = DriverManager.getConnection(url, userName, userPwd);
+
+
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ log.info("初始化了一个数据库连接:{ip:"+this.dataSources.getIp()+" port:"+this.dataSources.getPort()+"databaseName"+this.dataSources.getDatabaseName()+" }");
+ return oracleConn;
+ }
+
+ @Override
+ public void closeConn() {
+ closeBaseConn();
+ closeActiveConn();
+ }
+
+
+ /**
+ * 关闭空闲连接
+ */
+ public void closeBaseConn() {
+ //从空闲连接当中拿出一个连接 准备进行关闭
+ //如何拿出的这个链接为null 表示以列当中没有连接信息
+ Connection poll = this.oracleConnQueue.poll();
+ if (poll!=null){
+ try {
+ poll.close();
+ } catch (SQLException e) {
+ try {
+ //判断这个接是否被关闭了,如果连接被关闭则不需要放入队列当中
+ //如何这个链接没有被关闭 则放入队列当中 尝试下次关闭
+ if (!poll.isClosed()){
+ this.oracleConnQueue.offer(poll);
+ }
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }finally {
+ closeBaseConn();
+ }
+
+ }
+
+ }
+ /**
+ * 关闭活动连接
+ */
+ public void closeActiveConn() {
+ //从空闲连接当中拿出一个连接 准备进行关闭
+ //如何拿出的这个链接为null 表示以列当中没有连接信息
+ Connection poll = this.activeOracleConnQueue.poll();
+ if (poll!=null){
+ try {
+ poll.close();
+ } catch (SQLException e) {
+ try {
+ //判断这个接是否被关闭了,如果连接被关闭则不需要放入队列当中
+ //如何这个链接没有被关闭 则放入队列当中 尝试下次关闭
+ if (!poll.isClosed()){
+ this.activeOracleConnQueue.offer(poll);
+ }
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }finally {
+ closeActiveConn();
+ }
+ }
+
+ }
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/pool/RedisPool.java b/cloud-datasources-common/src/main/java/com/muyu/common/pool/RedisPool.java
new file mode 100644
index 0000000..c735571
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/pool/RedisPool.java
@@ -0,0 +1,156 @@
+package com.muyu.common.pool;
+
+import com.muyu.common.domain.DataSources;
+import com.muyu.common.pool.exeption.RedisConnException;
+import lombok.extern.log4j.Log4j2;
+import redis.clients.jedis.Jedis;
+
+import java.util.Queue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @Author:zhangzhihao
+ * @name:RedisPool
+ * @Date:2024/8/24 18:37
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Log4j2
+public class RedisPool implements BasePool{
+ /**
+ * 空闲队列
+ */
+ private Queue jedisBaseConnQueue = null;
+
+ /**
+ * 活动队列
+ */
+ private Queue jedisActiveConnQueue = null;
+
+ /**
+ * 总连接数
+ */
+ private AtomicInteger count=null;
+
+ /**
+ * redisPoolConfig
+ */
+
+ private DataSources dataSources=null;
+
+ /**
+ * 实例化
+ * @param dataSources
+ */
+ public RedisPool(DataSources dataSources) {
+ log.info("redis连接池实例化完成");
+ this.dataSources = dataSources;
+ }
+
+ @Override
+ public void init() {
+
+ Integer maxCount = this.dataSources.getMaxCount();
+
+ this.jedisBaseConnQueue = new LinkedBlockingQueue(maxCount);
+ this.jedisActiveConnQueue = new LinkedBlockingQueue(maxCount);
+
+ this.count = new AtomicInteger();
+
+ Integer initCount = this.dataSources.getInitCount();
+
+
+ for (Integer i = 0; i < initCount; i++) {
+ this.jedisBaseConnQueue.offer(createConn());
+ count.incrementAndGet();
+ }
+ log.info("redis连接池初始化完成!");
+ }
+
+ @Override
+ public Jedis getConn() {
+ long startTime = System.currentTimeMillis();
+
+
+ while (true){
+ Jedis jedis = this.jedisBaseConnQueue.poll();
+ if (jedis!=null){
+ this.jedisActiveConnQueue.offer(jedis);
+ return jedis;
+ }
+
+ if (count.get() this.dataSources.getMaxTime()){
+ throw new RedisConnException("redis获取连接超时!");
+ }
+
+ }
+
+ }
+
+ @Override
+ public void replease(Jedis conn) {
+ if (this.jedisActiveConnQueue.remove(conn)){
+ this.jedisBaseConnQueue.offer(conn);
+ }else {
+ count.decrementAndGet();
+ }
+
+ }
+
+ @Override
+ public Jedis createConn() {
+ String ip = this.dataSources.getIp();
+ String port = this.dataSources.getPort();
+ Jedis jedis = new Jedis(ip, Integer.parseInt(port));
+ log.info("初始化了一个redis的连接,{ip:"+ip+" port:"+port+"}");
+ return jedis;
+ }
+
+ @Override
+ public void closeConn() {
+ closeJedisBaseConn();
+ closeJedisActiveConn();
+ }
+
+ public void closeJedisBaseConn(){
+ Jedis jedis = this.jedisBaseConnQueue.poll();
+
+ if (jedis!=null){
+ try {
+ jedis.close();
+ } catch (Exception e) {
+ if (!jedis.isConnected()){
+ this.jedisBaseConnQueue.offer(jedis);
+ }
+ throw new RuntimeException(e);
+ }finally {
+ closeJedisBaseConn();
+ }
+ }
+ }
+ public void closeJedisActiveConn(){
+ Jedis jedis = this.jedisActiveConnQueue.poll();
+
+ if (jedis!=null){
+ try {
+ jedis.close();
+ } catch (Exception e) {
+ if (!jedis.isConnected()){
+ this.jedisActiveConnQueue.offer(jedis);
+ }
+ throw new RuntimeException(e);
+ }finally {
+ closeJedisActiveConn();
+ }
+ }
+ }
+
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/pool/base/BaseConfig.java b/cloud-datasources-common/src/main/java/com/muyu/common/pool/base/BaseConfig.java
new file mode 100644
index 0000000..e2181c9
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/pool/base/BaseConfig.java
@@ -0,0 +1,33 @@
+package com.muyu.common.pool.base;
+
+/**
+ * @Author:zhangzhihao
+ * @name:BaseConfig
+ * @Date:2024/8/22 17:03
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public class BaseConfig {
+ /**
+ * mysql连接前缀
+ */
+ public static final String MYSQLJDBCPRO="jdbc:mysql://";
+ public static final String ORACLEJDBCPRO="jdbc:oracle:thin:@";
+ public static final String SHOWTABLES="show TABLES";
+ public static final String SELECTCOUNT="SELECT count(1) as count FROM ";
+ public static final String SHOW_FULL_FIELDS_FROM="SHOW FULL FIELDS FROM ";
+ public static final String SELECT="select ";
+ public static final String SELECTALL="select * from ";
+ public static final String FROM=" from ";
+
+
+
+
+ public static void driver(String driverName){
+ try {
+ Class.forName(driverName);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/pool/exeption/MysqlConnException.java b/cloud-datasources-common/src/main/java/com/muyu/common/pool/exeption/MysqlConnException.java
new file mode 100644
index 0000000..c0eec07
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/pool/exeption/MysqlConnException.java
@@ -0,0 +1,13 @@
+package com.muyu.common.pool.exeption;
+
+/**
+ * @Author:zhangzhihao
+ * @name:MysqlConnException
+ * @Date:2024/8/22 19:04
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public class MysqlConnException extends RuntimeException{
+ public MysqlConnException(String message) {
+ super(message);
+ }
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/pool/exeption/OracleConnException.java b/cloud-datasources-common/src/main/java/com/muyu/common/pool/exeption/OracleConnException.java
new file mode 100644
index 0000000..b669533
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/pool/exeption/OracleConnException.java
@@ -0,0 +1,13 @@
+package com.muyu.common.pool.exeption;
+
+/**
+ * @Author:zhangzhihao
+ * @name:MysqlConnException
+ * @Date:2024/8/22 19:04
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public class OracleConnException extends RuntimeException{
+ public OracleConnException(String message) {
+ super(message);
+ }
+}
diff --git a/cloud-datasources-common/src/main/java/com/muyu/common/pool/exeption/RedisConnException.java b/cloud-datasources-common/src/main/java/com/muyu/common/pool/exeption/RedisConnException.java
new file mode 100644
index 0000000..0835288
--- /dev/null
+++ b/cloud-datasources-common/src/main/java/com/muyu/common/pool/exeption/RedisConnException.java
@@ -0,0 +1,13 @@
+package com.muyu.common.pool.exeption;
+
+/**
+ * @Author:zhangzhihao
+ * @name:MysqlConnException
+ * @Date:2024/8/22 19:04
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public class RedisConnException extends RuntimeException{
+ public RedisConnException(String message) {
+ super(message);
+ }
+}
diff --git a/cloud-datasources-remote/pom.xml b/cloud-datasources-remote/pom.xml
new file mode 100644
index 0000000..c3256b9
--- /dev/null
+++ b/cloud-datasources-remote/pom.xml
@@ -0,0 +1,37 @@
+
+
+ 4.0.0
+
+ com.muyu
+ cloud-etl-datasources
+ 1.0.0
+
+
+ cloud-datasources-remote
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ com.muyu
+ cloud-datasources-common
+
+
+ com.muyu
+ cloud-common-etl
+ 1.0.0
+ compile
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+
+
diff --git a/cloud-datasources-remote/src/main/java/com/muyu/remote/DataSourcesRemote.java b/cloud-datasources-remote/src/main/java/com/muyu/remote/DataSourcesRemote.java
new file mode 100644
index 0000000..cc0628b
--- /dev/null
+++ b/cloud-datasources-remote/src/main/java/com/muyu/remote/DataSourcesRemote.java
@@ -0,0 +1,22 @@
+package com.muyu.remote;
+
+import com.muyu.common.core.domain.Result;
+import com.muyu.common.domain.DataSources;
+import com.muyu.etl.domain.DataValue;
+import com.muyu.remote.factory.DataSourcesFactory;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @author Administrator
+ */
+@EnableFeignClients
+@FeignClient(value = "cloud-etl-datasources",fallbackFactory = DataSourcesFactory.class )
+public interface DataSourcesRemote {
+ @GetMapping("datasources/{id}")
+ public Result queryById(@PathVariable("id") Long id);
+}
diff --git a/cloud-datasources-remote/src/main/java/com/muyu/remote/factory/DataSourcesFactory.java b/cloud-datasources-remote/src/main/java/com/muyu/remote/factory/DataSourcesFactory.java
new file mode 100644
index 0000000..d3bd0d6
--- /dev/null
+++ b/cloud-datasources-remote/src/main/java/com/muyu/remote/factory/DataSourcesFactory.java
@@ -0,0 +1,20 @@
+package com.muyu.remote.factory;
+
+import com.muyu.common.core.domain.Result;
+import com.muyu.common.domain.DataSources;
+import com.muyu.remote.DataSourcesRemote;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DataSourcesFactory implements FallbackFactory {
+ @Override
+ public DataSourcesRemote create(Throwable cause) {
+ return new DataSourcesRemote() {
+ @Override
+ public Result queryById(Long id) {
+ return null;
+ }
+ };
+ }
+}
diff --git a/cloud-datasources-remote/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/cloud-datasources-remote/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000..c88ef31
--- /dev/null
+++ b/cloud-datasources-remote/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1,2 @@
+com.muyu.remote.factory.DataSourcesFactory
+com.muyu.remote.DataSourcesRemote
diff --git a/cloud-datasources-server/pom.xml b/cloud-datasources-server/pom.xml
new file mode 100644
index 0000000..8123d0f
--- /dev/null
+++ b/cloud-datasources-server/pom.xml
@@ -0,0 +1,148 @@
+
+
+ 4.0.0
+
+ com.muyu
+ cloud-etl-datasources
+ 1.0.0
+
+
+ cloud-datasources-server
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ com.muyu
+ cloud-datasources-client
+ 1.0.0
+
+
+
+
+ com.zaxxer
+ HikariCP
+ 4.0.3
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+ com.oracle.database.jdbc
+ ojdbc8
+ 19.3.0.0
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-config
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-sentinel
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+
+ com.mysql
+ mysql-connector-j
+
+
+
+
+ com.muyu
+ cloud-common-datasource
+
+
+
+
+ com.muyu
+ cloud-common-datascope
+
+
+
+
+ com.muyu
+ cloud-common-log
+
+
+
+
+ com.muyu
+ cloud-common-api-doc
+
+
+
+
+ com.muyu
+ cloud-common-xxl
+
+
+ com.muyu
+ cloud-common-rabbit
+
+
+ com.muyu
+ cloud-datasources-common
+
+
+ com.muyu
+ cloud-common-nacos-api
+
+
+ com.muyu
+ cloud-common-etl
+ 1.0.0
+ compile
+
+
+
+
+ cloud-datasources
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
+
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/DataSourcesApplication.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/DataSourcesApplication.java
new file mode 100644
index 0000000..fe0ef7a
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/DataSourcesApplication.java
@@ -0,0 +1,24 @@
+package com.muyu.datasources;
+
+import com.muyu.common.security.annotation.EnableCustomConfig;
+import com.muyu.common.security.annotation.EnableMyFeignClients;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataSourcesApplication
+ * @Date:2024/8/21 14:37
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@EnableCustomConfig
+@EnableMyFeignClients
+@SpringBootApplication
+//@ComponentScan(basePackages = {"com.muyu", "com.muyu.datasources.mysql"})
+public class DataSourcesApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(DataSourcesApplication.class);
+ }
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/AssetAccreditController.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/AssetAccreditController.java
new file mode 100644
index 0000000..745a73e
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/AssetAccreditController.java
@@ -0,0 +1,118 @@
+package com.muyu.datasources.controller;
+
+import com.muyu.common.core.domain.Result;
+import com.muyu.common.core.utils.StringUtils;
+import com.muyu.common.core.utils.bean.BeanUtils;
+import com.muyu.common.domain.AssetAccredit;
+import com.muyu.common.domain.req.AssetAccreditReq;
+import com.muyu.common.log.annotation.Log;
+import com.muyu.common.log.enums.BusinessType;
+import com.muyu.common.security.annotation.RequiresPermissions;
+import com.muyu.common.system.domain.SysDept;
+import com.muyu.datasources.service.AssetAccreditService;
+import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:assetAccreditController
+ * @Date:2024/8/30 9:37
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@RestController
+@RequestMapping("assetAccredit")
+public class AssetAccreditController {
+
+
+ @Autowired
+ private AssetAccreditService assetAccreditService;
+
+
+
+ @PostMapping("/findUserIdList")
+ public Result findUserIdList(@RequestBody AssetAccreditReq req){
+
+ List list = assetAccreditService.findUserIdList(req);
+ return Result.success(list);
+ }
+
+
+
+ /**
+ * 添加用户权限方法
+ * @param req
+ * @return
+ */
+ @Log(title = "添加用户权限",businessType = BusinessType.INSERT)
+ @PostMapping("/addUserAssetAccredit")
+ public Result addUserAssetAccredit(@RequestBody AssetAccreditReq req){
+ AssetAccredit assetAccredit = new AssetAccredit();
+ assetAccredit.setUserId(req.getUserId());
+ assetAccredit.setTableId(req.getTableId());
+ assetAccredit.setBasicId(req.getBasicId());
+
+ boolean save = assetAccreditService.save(assetAccredit);
+ return save?Result.success():Result.error();
+ }
+
+ /**
+ * 删除用户权限方法
+ * @param req
+ * @return
+ */
+ @Log(title = "删除用户权限",businessType = BusinessType.DELETE)
+ @PostMapping("/delUserAssetAccredit")
+ public Result delUserAssetAccredit(@RequestBody AssetAccreditReq req){
+ int i = assetAccreditService.delUserAssetAccredit(req);
+
+ return i>0?Result.success():Result.error();
+ };
+
+
+ @PostMapping("/findDeptIdList")
+ public Result findDeptIdList(@RequestBody AssetAccreditReq req){
+
+ List list = assetAccreditService.findDeptIdList(req);
+ return Result.success(list);
+ }
+
+
+
+
+
+ /**
+ * 添加部门权限方法
+ * @param req
+ * @return
+ */
+ @Log(title = "添加部门权限",businessType = BusinessType.INSERT)
+ @PostMapping("/addDeptAssetAccredit")
+ public Result addDeptAssetAccredit(@RequestBody AssetAccreditReq req){
+ AssetAccredit assetAccredit = new AssetAccredit();
+ assetAccredit.setDeptId(req.getDeptId());
+ assetAccredit.setTableId(req.getTableId());
+ assetAccredit.setBasicId(req.getBasicId());
+
+ boolean save = assetAccreditService.save(assetAccredit);
+ return save?Result.success():Result.error();
+ }
+
+ /**
+ * 删除部门权限方法
+ * @param req
+ * @return
+ */
+ @Log(title = "删除部门权限",businessType = BusinessType.DELETE)
+ @PostMapping("/delDeptAssetAccredit")
+ public Result delDeptAssetAccredit(@RequestBody AssetAccreditReq req){
+ int i = assetAccreditService.delDeptAssetAccredit(req);
+
+ return i>0?Result.success():Result.error();
+ };
+
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/DataSourcesController.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/DataSourcesController.java
new file mode 100644
index 0000000..0abb8de
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/DataSourcesController.java
@@ -0,0 +1,192 @@
+package com.muyu.datasources.controller;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.muyu.common.core.domain.Result;
+import com.muyu.common.core.utils.poi.ExcelUtil;
+import com.muyu.common.domain.DataSources;
+import com.muyu.common.domain.req.DataSourcesReq;
+import com.muyu.common.log.annotation.Log;
+import com.muyu.common.log.enums.BusinessType;
+import com.muyu.datasources.service.DataSourcesService;
+
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.sql.*;
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataSourcesController
+ * @Date:2024/8/21 14:47
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@RestController
+@RequestMapping("datasources")
+public class DataSourcesController {
+
+ @Autowired
+ private DataSourcesService dataSourcesService;
+
+ /**
+ * 通过ID查询单条数据
+ * @param id 主键
+ * @return 实例对象
+ */
+ @GetMapping("/{id}")
+ public Result queryById(@PathVariable("id") Long id){
+ return Result.success(dataSourcesService.getById(id));
+ }
+
+ /**
+ * 查询所有已有数据源
+ * @param req
+ * @return
+ */
+ @PostMapping("/all")
+ public Result> all(@RequestBody DataSourcesReq req){
+ Page dataSourcesPage = dataSourcesService.selectList(req);
+ return Result.success(dataSourcesPage);
+ }
+
+
+ /**
+ * 新增数据来源
+ * @param dataSources 实例对象
+ * @return 实例对象
+ */
+ @Log(title = "新增数据来源",businessType = BusinessType.INSERT)
+ @PostMapping("/addDataSources")
+ public Result add(@RequestBody DataSources dataSources){
+ dataSourcesService.save(dataSources);
+ return Result.success();
+ }
+
+ /**
+ * 更新数据
+ *
+ * @param dataSources 实例对象
+ * @return 实例对象
+ */
+ @Log(title = "更新数据来源配置",businessType = BusinessType.UPDATE)
+ @PutMapping("/updateDataSources")
+ public Result edit(@RequestBody DataSources dataSources){
+ dataSourcesService.updateById(dataSources);
+ return Result.success();
+ }
+
+ /**
+ * 通过主键删除数据
+ *
+ * @param id 主键
+ * @return 是否成功
+ */
+ @Log(title = "删除数据来源",businessType = BusinessType.DELETE)
+ @DeleteMapping("/{id}")
+ public Result deleteById(@PathVariable("id") Long id){
+ return Result.success(dataSourcesService.removeById(id));
+ }
+
+
+ /**
+ * 测试连接
+ * @param dataSources
+ * @return
+ */
+ @PostMapping("/connectDataSources")
+ public Result connectDataSources(@RequestBody DataSources dataSources){
+ int i= dataSourcesService.connectDataSources(dataSources);
+ return i>0?Result.success():Result.error();
+ }
+
+
+ /**
+ * 同步数据结构
+ * @param dataSources
+ * @return
+ */
+ @Log(title = "同步数据结构",businessType = BusinessType.INSERT)
+ @PostMapping("/syncAssetStructure")
+ public Result syncAssetStructure(@RequestBody DataSources dataSources){
+ Integer i = dataSourcesService.syncAssetStructure(dataSources);
+ return Result.success(i);
+ }
+
+ /**
+ * 导出数据
+ * @param response
+ */
+ @PostMapping("/export")
+ public void export(HttpServletResponse response){
+ List list = dataSourcesService.list();
+
+ ExcelUtil util = new ExcelUtil<>(DataSources.class);
+ util.exportExcel(response,list,"连接数据库配置");
+ }
+
+// @PostMapping("/test")
+// public Result test() {
+// // Oracle数据库的JDBC URL
+// String jdbcUrl = "jdbc:oracle:thin:@LAPTOP-A6NCJEU3:1521:XE";
+//
+//
+// String username = "zzh";
+// String password = "123456";
+//
+// Connection conn = null;
+// Statement stmt = null;
+// ResultSet rs = null;
+// String str="";
+// try {
+// // 加载Oracle JDBC驱动
+// Class.forName("oracle.jdbc.driver.OracleDriver");
+//
+// // 建立数据库连接
+// conn = DriverManager.getConnection(jdbcUrl, username, password);
+//
+// // 创建Statement对象
+// stmt = conn.createStatement();
+//
+// // 编写SQL查询语句,从ZZH模式的T_USER表中查询NAME字段
+// String sql = "SELECT TABLE_NAME FROM DBA_TABLES WHERE OWNER = 'ZZH'";
+//
+// // 执行查询
+// rs = stmt.executeQuery(sql);
+//
+//
+// // 遍历ResultSet对象,获取NAME字段的值
+// while (rs.next()) {
+// String name = rs.getString(1);
+// str+=name;
+// System.out.println("NAME: " + name);
+// }
+//
+// }catch (ClassNotFoundException e) {
+// System.out.println("Oracle JDBC Driver类未找到!");
+// e.printStackTrace();
+// } catch (SQLException e) {
+// System.out.println("数据库连接失败或SQL查询出错!");
+// e.printStackTrace();
+// } finally {
+// // 关闭资源
+// try {
+// if (rs != null) {
+// rs.close();
+// }
+// if (stmt != null) {
+// stmt.close();
+// }
+// if (conn != null) {
+// conn.close();
+// }
+// } catch (SQLException e) {
+// e.printStackTrace();
+// }
+// }
+//
+// return Result.success(str);
+// }
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/DataValueController.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/DataValueController.java
new file mode 100644
index 0000000..c98ebfc
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/DataValueController.java
@@ -0,0 +1,118 @@
+package com.muyu.datasources.controller;
+
+import com.muyu.common.core.domain.Result;
+import com.muyu.datasources.service.DataValueService;
+import com.muyu.etl.domain.DataValue;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataKltvController
+ * @Date:2024/8/27 22:17
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Log4j2
+@RestController
+@RequestMapping("dataValue")
+public class DataValueController {
+
+ @Autowired
+ private DataValueService dataValueService;
+
+ /**
+ * 获取表中的值供任务模块调用
+ * @param basicId
+ * @param sql
+ * @return
+ */
+ @PostMapping("/findTableValue")
+ public Result>> findTableValue(@RequestParam("basicId") Long basicId, @RequestParam("sql") String sql){
+
+ long l = System.currentTimeMillis();
+ List> list = dataValueService.findTableValue(basicId,sql);
+
+ long x = System.currentTimeMillis();
+ long l1 = x - l;
+ log.info("耗时:"+l1);
+ return Result.success(list);
+ }
+
+ /**
+ * 获取表中的值供前台调用
+ * @param basicId
+ * @param tableName
+ * @return
+ */
+ @PostMapping("/findTableValueByTableName")
+ public Result findTableValueByTableName(@RequestParam("basicId") Long basicId,@RequestParam("tableName") String tableName){
+ List list = dataValueService.findTableValueByTableName(basicId,tableName);
+ return Result.success(list);
+ }
+
+
+ @PostMapping("/findTableValueContributionRule")
+ public Result>> findTableValueContributionRule(@RequestParam("basicId") Long basicId,@RequestParam("tableId") Long tableId){
+
+ List> list = dataValueService.findTableValueContributionRule(basicId,tableId);
+
+
+ return Result.success(list);
+ }
+
+
+ @PostMapping("/findCount")
+ public Result findCount(@RequestParam("basicId") Long basicId,@RequestParam("sql") String sql){
+ Long count = dataValueService.findCount(basicId,sql);
+ return Result.success(count);
+ }
+
+
+ /**
+ * 获取表中的值供任务模块调用
+ * @param basicId
+ * @param sql
+ * @return
+ */
+ @PostMapping("/findTableValueToArray")
+ public Result findTableValueToArray(@RequestParam("basicId") Long basicId,
+ @RequestParam("sql") String sql,
+ @RequestParam("one") Long one,
+ @RequestParam("two") Integer two){
+
+ long begin = System.currentTimeMillis();
+ DataValue[][] list = dataValueService.findTableValueToArray(basicId,sql,one,two);
+
+
+ long end = System.currentTimeMillis();
+ long time = end - begin;
+ log.info("耗时:"+time);
+ return Result.success(list);
+ }
+
+
+ /**
+ * 测试
+ */
+// @PostMapping("/test")
+// public static void test() {
+// MySqlQuery mySqlQuery = new MySqlQuery();
+// String sql="select id,table_id from asset_accredit";
+// mySqlQuery.setSql(sql);
+// mySqlQuery.setDataSourceId(1L);
+// BaseQueryHandler.set(mySqlQuery);
+//
+//
+// MySqlDataSource mySqlDataSource = new MySqlDataSource();
+// DataValue[][] rows = mySqlDataSource.getRows();
+// System.out.println(rows);
+// }
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/ProductController.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/ProductController.java
new file mode 100644
index 0000000..3ade0a7
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/ProductController.java
@@ -0,0 +1,39 @@
+package com.muyu.datasources.controller;
+
+import com.muyu.common.core.domain.Result;
+import com.muyu.datasources.service.ProductService;
+import com.muyu.etl.domain.DataValue;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @Author:zhangzhihao
+ * @name:ProductController
+ * @Date:2024/9/2 21:12
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Log4j2
+@RestController
+@RequestMapping("/product")
+public class ProductController {
+
+ @Autowired
+ private ProductService productService;
+
+ @PostMapping("/addProduct")
+ public Result addProduct(@RequestParam("basicId") Long basicId, @RequestParam("tableId") Long tableId, @RequestBody DataValue[][] listList){
+ long begin = System.currentTimeMillis();
+
+ int i = productService.addProduct(basicId,tableId,listList);
+
+
+ long end = System.currentTimeMillis();
+
+ long allTime = end - begin;
+ log.info("添加到产品数据库耗时:"+allTime);
+
+ return Result.success(i);
+ }
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/StructureController.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/StructureController.java
new file mode 100644
index 0000000..41d0451
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/StructureController.java
@@ -0,0 +1,41 @@
+package com.muyu.datasources.controller;
+
+import com.muyu.common.core.domain.Result;
+import com.muyu.common.domain.Structure;
+import com.muyu.datasources.service.StructureService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:StructureController
+ * @Date:2024/8/26 20:43
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@RestController
+@RequestMapping("structure")
+public class StructureController {
+
+ @Autowired
+ private StructureService structureService;
+
+ /**
+ * 查询数据结构
+ * @param id
+ * @return
+ */
+ @GetMapping("/findStructureByTableId/{id}")
+ public Result findStructureByTableId(@PathVariable("id") Long id){
+
+ List list = structureService.findStructureByTableId(id);
+
+ return Result.success(list);
+ }
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/TableInfoController.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/TableInfoController.java
new file mode 100644
index 0000000..230f9d5
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/controller/TableInfoController.java
@@ -0,0 +1,147 @@
+package com.muyu.datasources.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.muyu.common.core.domain.Result;
+
+import com.muyu.common.domain.TableInfo;
+import com.muyu.common.domain.resp.AssetAccreditResp;
+import com.muyu.common.domain.resp.TableInfoResp;
+import com.muyu.common.security.utils.SecurityUtils;
+import com.muyu.common.system.domain.LoginUser;
+import com.muyu.common.system.domain.SysUser;
+import com.muyu.datasources.service.AssetAccreditService;
+import com.muyu.datasources.service.DataSourcesService;
+import com.muyu.datasources.service.SysUserService;
+import com.muyu.datasources.service.TableInfoService;
+import jakarta.servlet.http.HttpServletRequest;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.stream.Stream;
+
+
+@RestController
+@RequestMapping("tableInfo")
+public class TableInfoController {
+
+ @Autowired
+ private TableInfoService tableInfoService;
+
+ @Autowired
+ private SysUserService sysUserService;
+
+ @Autowired
+ private AssetAccreditService assetAccreditService;
+
+ @Autowired
+ private HttpServletRequest request;
+
+
+
+
+ @GetMapping("/findAsset")
+ public Result findAsset(){
+ List list = tableInfoService.list();
+
+ List respList = list.stream().filter(tableInfo -> tableInfo.getParentId()==0).map(tableInfo -> {
+ TableInfoResp tableInfoResp = TableInfo.toTableInfoResp(tableInfo);
+ tableInfoResp.setChildren(getAssetChildren(tableInfo, list));
+ return tableInfoResp;
+ }).toList();
+
+ return Result.success(respList);
+ }
+
+ /**
+ * 级联查询
+ * @return
+ */
+ @GetMapping
+ public Result findByTableName() {
+ LoginUser loginUser = SecurityUtils.getLoginUser();
+ SysUser sysUser = loginUser.getSysUser();
+ Long userId = sysUser.getUserId();
+ Long deptId = sysUser.getDeptId();
+ List idList = assetAccreditService.findTableIdAndBasicIdByUserId(userId);
+ List deptIdList = assetAccreditService.findTableIdAndBasicIdByDeptId(deptId);
+ HashSet set = new HashSet<>();
+ for (AssetAccreditResp assetAccreditResp : idList) {
+ Long basicId = assetAccreditResp.getBasicId();
+ Long tableId = assetAccreditResp.getTableId();
+ if (null!=basicId){
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(TableInfo::getBasicId,basicId);
+ List tableInfoList = tableInfoService.list(wrapper);
+ set.addAll(tableInfoList);
+ }
+
+ if (null!=tableId){
+ TableInfo tableInfo = tableInfoService.getById(tableId);
+ set.add(tableInfo);
+ Long parentId = tableInfo.getParentId();
+ TableInfo dataSource = tableInfoService.getById(parentId);
+ set.add(dataSource);
+ }
+ }
+
+ for (AssetAccreditResp assetAccreditResp : deptIdList) {
+ Long basicId = assetAccreditResp.getBasicId();
+ Long tableId = assetAccreditResp.getTableId();
+ if (null!=basicId){
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(TableInfo::getBasicId,basicId);
+ List tableInfoList = tableInfoService.list(wrapper);
+ set.addAll(tableInfoList);
+ }
+
+ if (null!=tableId){
+ TableInfo tableInfo = tableInfoService.getById(tableId);
+ set.add(tableInfo);
+ Long parentId = tableInfo.getParentId();
+ TableInfo dataSource = tableInfoService.getById(parentId);
+ set.add(dataSource);
+ }
+ }
+ List respList = set.stream().filter(tableInfo -> tableInfo.getParentId()==0).map(tableInfo -> {
+ TableInfoResp tableInfoResp = TableInfo.toTableInfoResp(tableInfo);
+ tableInfoResp.setChildren(getChildren(tableInfo, set));
+ return tableInfoResp;
+ }).toList();
+ return Result.success(respList);
+ }
+ @NotNull
+ private static List getChildren(TableInfo tableInfo, HashSet list) {
+ return list.stream().filter(tableInfo1 -> tableInfo1.getParentId().equals(tableInfo.getId())).map(
+ tableInfo2 -> TableInfo.toTableInfoResp(tableInfo2)
+ ).toList();
+ }
+
+
+ @NotNull
+ private static List getAssetChildren(TableInfo tableInfo, List list) {
+ return list.stream().filter(tableInfo1 -> tableInfo1.getParentId().equals(tableInfo.getId())).map(
+ tableInfo2 -> TableInfo.toTableInfoResp(tableInfo2)
+ ).toList();
+ }
+
+
+ /**
+ * 根据id查询数据
+ * @param id
+ * @return
+ */
+ @PostMapping("/findTableName")
+ public Result findTableName(@RequestParam("id") Long id){
+ TableInfo table = tableInfoService.getById(id);
+ return Result.success(table);
+ }
+
+
+
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/AssetAccreditMapper.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/AssetAccreditMapper.java
new file mode 100644
index 0000000..1a68f8b
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/AssetAccreditMapper.java
@@ -0,0 +1,31 @@
+package com.muyu.datasources.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.muyu.common.domain.AssetAccredit;
+import com.muyu.common.domain.req.AssetAccreditReq;
+import com.muyu.common.domain.resp.AssetAccreditResp;
+import com.muyu.common.system.domain.SysDept;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:AssetAccreditMapper
+ * @Date:2024/8/30 9:40
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Mapper
+public interface AssetAccreditMapper extends BaseMapper {
+
+
+ List findUserIdList(AssetAccreditReq req);
+
+
+ List findDeptIdList(AssetAccreditReq req);
+
+ List findTableIdAndBasicIdByUserId(@Param("userId") Long userId);
+
+ List findTableIdAndBasicIdByDeptId(@Param("deptId") Long deptId);
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/DataSourcesMapper.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/DataSourcesMapper.java
new file mode 100644
index 0000000..8a7c2e6
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/DataSourcesMapper.java
@@ -0,0 +1,19 @@
+package com.muyu.datasources.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.muyu.common.domain.DataSources;
+
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataSourcesMapper
+ * @Date:2024/8/21 14:40
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Mapper
+public interface DataSourcesMapper extends BaseMapper {
+
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/DataValueMapper.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/DataValueMapper.java
new file mode 100644
index 0000000..0ebd060
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/DataValueMapper.java
@@ -0,0 +1,15 @@
+package com.muyu.datasources.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.muyu.etl.domain.DataValue;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataKltvMapper
+ * @Date:2024/8/27 15:38
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Mapper
+public interface DataValueMapper extends BaseMapper {
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/ProductMapper.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/ProductMapper.java
new file mode 100644
index 0000000..fb00607
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/ProductMapper.java
@@ -0,0 +1,15 @@
+package com.muyu.datasources.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @Author:zhangzhihao
+ * @name:ProductMapper
+ * @Date:2024/9/2 21:13
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Mapper
+public interface ProductMapper {
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/StructureMapper.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/StructureMapper.java
new file mode 100644
index 0000000..bca42de
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/StructureMapper.java
@@ -0,0 +1,15 @@
+package com.muyu.datasources.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.muyu.common.domain.Structure;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @Author:zhangzhihao
+ * @name:StructureMapper
+ * @Date:2024/8/25 16:49
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Mapper
+public interface StructureMapper extends BaseMapper {
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/SysUserMapper.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/SysUserMapper.java
new file mode 100644
index 0000000..22e6960
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/SysUserMapper.java
@@ -0,0 +1,17 @@
+package com.muyu.datasources.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.muyu.common.system.domain.SysUser;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * @Author:zhangzhihao
+ * @name:SysUserMapper
+ * @Date:2024/8/31 18:49
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Mapper
+public interface SysUserMapper extends BaseMapper {
+ SysUser findUserById(@Param("userId") Long userId);
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/TableInfoMapper.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/TableInfoMapper.java
new file mode 100644
index 0000000..114f527
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/mapper/TableInfoMapper.java
@@ -0,0 +1,19 @@
+package com.muyu.datasources.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.muyu.common.domain.TableInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:TableInfoMapper
+ * @Date:2024/8/25 11:39
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Mapper
+public interface TableInfoMapper extends BaseMapper {
+ List findTableIdByParentId(@Param("basicId") Long basicId);
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/AssetAccreditService.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/AssetAccreditService.java
new file mode 100644
index 0000000..4e800aa
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/AssetAccreditService.java
@@ -0,0 +1,32 @@
+package com.muyu.datasources.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.muyu.common.domain.AssetAccredit;
+import com.muyu.common.domain.req.AssetAccreditReq;
+import com.muyu.common.domain.resp.AssetAccreditResp;
+import com.muyu.common.system.domain.SysDept;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:assetAccreditService
+ * @Date:2024/8/30 9:38
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public interface AssetAccreditService extends IService {
+
+
+ List findUserIdList(AssetAccreditReq req);
+
+
+ int delUserAssetAccredit(AssetAccreditReq req);
+
+ int delDeptAssetAccredit(AssetAccreditReq req);
+
+ List findDeptIdList(AssetAccreditReq req);
+
+ List findTableIdAndBasicIdByUserId(Long userId);
+
+ List findTableIdAndBasicIdByDeptId(Long deptId);
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/DataSourcesService.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/DataSourcesService.java
new file mode 100644
index 0000000..8e08ae7
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/DataSourcesService.java
@@ -0,0 +1,32 @@
+package com.muyu.datasources.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.muyu.common.domain.DataSources;
+import com.muyu.common.domain.req.DataSourcesReq;
+
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataSourcesService
+ * @Date:2024/8/21 14:35
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public interface DataSourcesService extends IService {
+
+
+
+ /**
+ * 查询所有已有数据源
+ * @param req
+ * @return
+ */
+ Page selectList(DataSourcesReq req);
+
+ int connectDataSources(DataSources dataSources);
+
+
+ Integer syncAssetStructure(DataSources dataSources);
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/DataValueService.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/DataValueService.java
new file mode 100644
index 0000000..248d30b
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/DataValueService.java
@@ -0,0 +1,25 @@
+package com.muyu.datasources.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.muyu.etl.domain.DataValue;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataKltvService
+ * @Date:2024/8/27 15:33
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public interface DataValueService extends IService {
+
+ List> findTableValue(Long basicId, String sql);
+
+ List findTableValueByTableName(Long basicId, String tableName);
+
+ List> findTableValueContributionRule(Long basicId, Long tableId);
+
+ Long findCount(Long basicId, String sql);
+
+ DataValue[][] findTableValueToArray(Long basicId, String sql, Long one, Integer two);
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/ProductService.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/ProductService.java
new file mode 100644
index 0000000..b06b0d2
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/ProductService.java
@@ -0,0 +1,13 @@
+package com.muyu.datasources.service;
+
+import com.muyu.etl.domain.DataValue;
+
+/**
+ * @Author:zhangzhihao
+ * @name:ProductControllerService
+ * @Date:2024/9/2 21:12
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public interface ProductService {
+ int addProduct(Long basicId, Long tableId, DataValue[][] listList);
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/StructureService.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/StructureService.java
new file mode 100644
index 0000000..5c0b311
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/StructureService.java
@@ -0,0 +1,16 @@
+package com.muyu.datasources.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.muyu.common.domain.Structure;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:StructureService
+ * @Date:2024/8/25 16:48
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public interface StructureService extends IService {
+ List findStructureByTableId(Long id);
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/SysUserService.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/SysUserService.java
new file mode 100644
index 0000000..124b161
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/SysUserService.java
@@ -0,0 +1,14 @@
+package com.muyu.datasources.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.muyu.common.system.domain.SysUser;
+
+/**
+ * @Author:zhangzhihao
+ * @name:SysUserService
+ * @Date:2024/8/31 18:48
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public interface SysUserService extends IService {
+ SysUser findUserById(Long userId);
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/TableInfoService.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/TableInfoService.java
new file mode 100644
index 0000000..d71b97c
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/TableInfoService.java
@@ -0,0 +1,18 @@
+package com.muyu.datasources.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.muyu.common.domain.TableInfo;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:TableInfoService
+ * @Date:2024/8/25 11:35
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+public interface TableInfoService extends IService {
+ TableInfo selectTableInfoByName(TableInfo tableInfoInsert);
+
+ List findTableIdByParentId(Long basicId);
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/AssetAccreditServiceImpl.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/AssetAccreditServiceImpl.java
new file mode 100644
index 0000000..11ccf87
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/AssetAccreditServiceImpl.java
@@ -0,0 +1,88 @@
+package com.muyu.datasources.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.muyu.common.domain.AssetAccredit;
+import com.muyu.common.domain.req.AssetAccreditReq;
+import com.muyu.common.domain.resp.AssetAccreditResp;
+import com.muyu.common.system.domain.SysDept;
+import com.muyu.datasources.mapper.AssetAccreditMapper;
+import com.muyu.datasources.service.AssetAccreditService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:AssetAccreditServiceImpl
+ * @Date:2024/8/30 9:39
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Service
+public class AssetAccreditServiceImpl extends ServiceImpl implements AssetAccreditService {
+
+ @Autowired
+ private AssetAccreditMapper assetAccreditMapper;
+
+
+ @Override
+ public List findUserIdList(AssetAccreditReq req) {
+ List userIdList = assetAccreditMapper.findUserIdList(req);
+ return userIdList;
+ }
+
+ @Override
+ public int delUserAssetAccredit(AssetAccreditReq req) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ if (null==req.getBasicId()){
+ queryWrapper.eq(AssetAccredit::getUserId,req.getUserId())
+ .eq(AssetAccredit::getTableId,req.getTableId());
+ }else if (null==req.getTableId()){
+ queryWrapper.eq(AssetAccredit::getUserId,req.getUserId())
+ .eq(AssetAccredit::getBasicId,req.getBasicId());
+ }
+
+ int delete = assetAccreditMapper.delete(queryWrapper);
+ return delete;
+ }
+
+ @Override
+ public int delDeptAssetAccredit(AssetAccreditReq req) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ if (null==req.getBasicId()){
+ queryWrapper.eq(AssetAccredit::getDeptId,req.getDeptId())
+ .eq(AssetAccredit::getTableId,req.getTableId());
+ }else if (null==req.getTableId()){
+ queryWrapper.eq(AssetAccredit::getDeptId,req.getDeptId())
+ .eq(AssetAccredit::getBasicId,req.getBasicId());
+ }
+
+ int delete = assetAccreditMapper.delete(queryWrapper);
+ return delete;
+ }
+
+ @Override
+ public List findDeptIdList(AssetAccreditReq req) {
+ List deptIdList = assetAccreditMapper.findDeptIdList(req);
+ return deptIdList;
+ }
+
+ @Override
+ public List findTableIdAndBasicIdByUserId(Long userId) {
+
+
+ List list = assetAccreditMapper.findTableIdAndBasicIdByUserId(userId);
+ return list;
+ }
+
+ @Override
+ public List findTableIdAndBasicIdByDeptId(Long deptId) {
+
+ List list = assetAccreditMapper.findTableIdAndBasicIdByDeptId(deptId);
+ return list;
+ }
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/DataSourceConfigLocalImpl.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/DataSourceConfigLocalImpl.java
new file mode 100644
index 0000000..039341d
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/DataSourceConfigLocalImpl.java
@@ -0,0 +1,22 @@
+package com.muyu.datasources.service.impl;
+
+import com.muyu.client.basic.DataSourceConfig;
+import com.muyu.common.core.domain.Result;
+import com.muyu.common.domain.DataSources;
+import com.muyu.datasources.service.DataSourcesService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+@Service
+@Primary
+public class DataSourceConfigLocalImpl implements DataSourceConfig {
+
+ @Autowired
+ private DataSourcesService dataSourcesService;
+
+ @Override
+ public DataSources queryById(Long id) {
+ return dataSourcesService.getById(id);
+ }
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/DataSourcesServiceImpl.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/DataSourcesServiceImpl.java
new file mode 100644
index 0000000..c81df4e
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/DataSourcesServiceImpl.java
@@ -0,0 +1,547 @@
+package com.muyu.datasources.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.muyu.common.core.utils.StringUtils;
+import com.muyu.common.domain.DataSources;
+import com.muyu.common.domain.Structure;
+import com.muyu.common.domain.TableInfo;
+import com.muyu.common.domain.req.DataSourcesReq;
+import com.muyu.common.pool.MysqlPool;
+import com.muyu.common.pool.OraclePool;
+import com.muyu.common.pool.RedisPool;
+import com.muyu.common.security.utils.SecurityUtils;
+import com.muyu.datasources.mapper.DataSourcesMapper;
+import com.muyu.datasources.service.DataSourcesService;
+import com.muyu.datasources.service.StructureService;
+import com.muyu.datasources.service.TableInfoService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import redis.clients.jedis.Jedis;
+
+import java.sql.*;
+import java.util.Date;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static com.muyu.common.pool.base.BaseConfig.*;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataSourcesServiceImpl
+ * @Date:2024/8/21 14:35
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Log4j2
+@Service
+public class DataSourcesServiceImpl extends ServiceImpl implements DataSourcesService {
+
+
+ @Autowired
+ private DataSourcesMapper dataSourcesMapper;
+
+ @Autowired
+ private TableInfoService tableInfoService;
+
+ @Autowired
+ private StructureService structureService;
+
+
+ private static final Long PARENTID =0L;
+ private static final String DRIVERNAME ="com.mysql.cj.jdbc.Driver";
+ private static final String DRIVERORACLENAME ="oracle.jdbc.driver.OracleDriver";
+ private static final String MYSQL ="mysql";
+ private static final String ORACLE ="oracle";
+ private static final String REDIS ="redis";
+
+ /**
+ * 添加数据来源
+ * @param dataSources
+ * @return
+ */
+ @Override
+ public boolean save(DataSources dataSources) {
+
+ String type = dataSources.getType();
+
+ if (type.equals(MYSQL)){
+ dataSources.setDriverName(DRIVERNAME);
+ }
+ if (type.equals(ORACLE)){
+ dataSources.setDriverName(DRIVERORACLENAME);
+ }
+
+ return super.save(dataSources);
+ }
+
+
+
+
+
+ /**
+ * 分页查询所有数据
+ * @param req
+ * @return
+ */
+ @Override
+ public Page selectList(DataSourcesReq req) {
+
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.like(StringUtils.isNotEmpty(req.getName()), DataSources::getName,req.getName());
+ queryWrapper.like(StringUtils.isNotEmpty(req.getDatabaseName()), DataSources::getDatabaseName,req.getDatabaseName());
+
+ Page page = new Page<>(req.getPageNum(), req.getPageSize());
+
+
+ Page pageList = dataSourcesMapper.selectPage(page, queryWrapper);
+
+
+ return pageList;
+ }
+
+ /**
+ * 测试连接
+ * @param dataSources
+ */
+ @Override
+ public int connectDataSources(DataSources dataSources) {
+ if (dataSources.getType().equals(MYSQL)){
+ MysqlPool mysqlPool = new MysqlPool(dataSources);
+ mysqlPool.init();
+ Connection conn = mysqlPool.getConn();
+ mysqlPool.replease(conn);
+ mysqlPool.closeConn();
+ return 1;
+ }else if (dataSources.getType().equals(REDIS)){
+ RedisPool redisPool = new RedisPool(dataSources);
+ redisPool.init();
+ Jedis conn = redisPool.getConn();
+ redisPool.replease(conn);
+ redisPool.closeConn();
+ return 1;
+ }
+ return 0;
+ }
+
+ private static final ExecutorService threadPool = Executors.newCachedThreadPool();
+ @Override
+ public Integer syncAssetStructure(DataSources dataSources) {
+
+ try {
+ if (dataSources.getType().equals(MYSQL)) {
+ MysqlPool mysqlPool = new MysqlPool(dataSources);
+ mysqlPool.init();
+ Connection conn = mysqlPool.getConn();
+
+
+ TableInfo tableInfoInsert = TableInfo.builder()
+ .basicId(dataSources.getId())
+ .parentId(PARENTID)
+ .tableRemark("")
+ .isCenter("Y")
+ .type("dataSource")
+ .tableName(dataSources.getDatabaseName())
+ .createBy(SecurityUtils.getUsername())
+ .createTime(new Date())
+ .build();
+
+ //添加数据库table_info表
+ tableInfoService.saveOrUpdate(tableInfoInsert,new LambdaUpdateWrapper(TableInfo.class){{
+ eq(TableInfo::getTableName,tableInfoInsert.getTableName());
+ eq(TableInfo::getBasicId,dataSources.getId());
+ }});
+
+ //根据数据库id和数据库名称或表名称查询
+ TableInfo tableInfo = tableInfoService.selectTableInfoByName(tableInfoInsert);
+
+ // 查询所有表信息
+ DatabaseMetaData metaData = conn.getMetaData();
+ ResultSet rs = metaData.getTables(dataSources.getDatabaseName(), null, "%", new String[]{"TABLE"});
+
+ while (rs.next()) {
+ String tableName = rs.getString("TABLE_NAME");
+ String tableRemark = rs.getString("REMARKS");
+
+ try (PreparedStatement preparedStatement = conn.prepareStatement(SELECTCOUNT + tableName)) {
+ ResultSet resultSet = preparedStatement.executeQuery();
+ long count = 0L;
+ if (resultSet.next()) {
+ count = resultSet.getLong("count");
+ }
+
+ TableInfo build = TableInfo.builder()
+ .basicId(dataSources.getId())
+ .tableName(tableName)
+ .tableRemark(tableRemark != null ? tableRemark : "")
+ .parentId(tableInfo.getId())
+ .type("dataTable")
+ .isCenter("Y")
+ .updateBy(SecurityUtils.getUsername())
+ .dataNum(count)
+ .updateTime(new Date())
+ .build();
+ tableInfoService.saveOrUpdate(build, new LambdaUpdateWrapper<>(TableInfo.class) {{
+ eq(TableInfo::getTableName, build.getTableName());
+ eq(TableInfo::getBasicId, dataSources.getId());
+ }});
+ TableInfo table = tableInfoService.selectTableInfoByName(build);
+
+ threadPool.submit(() -> {
+ syncData(conn, dataSources.getDatabaseName(), table);
+ });
+ } catch (SQLException e) {
+ log.error("查询计数失败", e);
+ }
+ }
+
+ try {
+ Thread.sleep(1000);
+ conn.close();
+ mysqlPool.closeConn();
+
+ } catch (SQLException e) {
+ log.error("关闭数据库连接失败", e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ } else if (dataSources.getType().equals(ORACLE)) {
+ OraclePool oraclePool = new OraclePool(dataSources);
+ oraclePool.init();
+ Connection conn = oraclePool.getConn();
+
+ TableInfo tableInfoInsert = TableInfo.builder()
+ .basicId(dataSources.getId())
+ .parentId(PARENTID)
+ .tableRemark("")
+ .isCenter("Y")
+ .type("dataSource")
+ .tableName(dataSources.getDatabaseName())
+ .createBy(SecurityUtils.getUsername())
+ .createTime(new Date())
+ .build();
+
+ // 添加数据库 table_info 表
+ tableInfoService.saveOrUpdate(tableInfoInsert, new LambdaUpdateWrapper<>(TableInfo.class) {{
+ eq(TableInfo::getTableName, tableInfoInsert.getTableName());
+ eq(TableInfo::getBasicId, dataSources.getId());
+ }});
+
+ // 根据数据库 id 和数据库名称查询
+ TableInfo tableInfo = tableInfoService.selectTableInfoByName(tableInfoInsert);
+
+ DatabaseMetaData metaData = conn.getMetaData();
+
+ // 编写 SQL 查询语句,从 ZZH 模式的 T_USER 表中查询 NAME 字段
+ String sql = "SELECT TABLE_NAME FROM DBA_TABLES WHERE OWNER = '" + dataSources.getDatabaseName() + "'";
+
+ // 执行查询
+ PreparedStatement prepared = conn.prepareStatement(sql);
+ ResultSet rs = prepared.executeQuery();
+
+ // 遍历 ResultSet 对象,获取 NAME 字段的值
+ while (rs.next()) {
+ String tableName = rs.getString(1);
+
+ try (PreparedStatement preparedStatement = conn.prepareStatement(SELECTCOUNT + tableName)) {
+ ResultSet resultSet = preparedStatement.executeQuery();
+ long count = 0L;
+ if (resultSet.next()) {
+ count = resultSet.getLong("count");
+ }
+
+ TableInfo build = TableInfo.builder()
+ .basicId(dataSources.getId())
+ .tableName(tableName)
+ .tableRemark("")
+ .parentId(tableInfo.getId())
+ .type("dataTable")
+ .isCenter("Y")
+ .updateBy(SecurityUtils.getUsername())
+ .dataNum(count)
+ .updateTime(new Date())
+ .build();
+ tableInfoService.saveOrUpdate(build, new LambdaUpdateWrapper<>(TableInfo.class) {{
+ eq(TableInfo::getTableName, build.getTableName());
+ eq(TableInfo::getBasicId, dataSources.getId());
+ }});
+ TableInfo table = tableInfoService.selectTableInfoByName(build);
+
+ threadPool.submit(() -> {
+ syncOracleData(conn, dataSources.getDatabaseName(), table);
+ });
+ } catch (SQLException e) {
+ log.error("查询计数失败", e);
+ }
+ }
+
+ try {
+
+ Thread.sleep(1000);
+ conn.close();
+ oraclePool.closeConn();
+ } catch (SQLException e) {
+ log.error("关闭数据库连接失败", e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ } catch (SQLException e) {
+ log.error("数据库操作失败", e);
+ throw new RuntimeException(e);
+ }
+ return 1;
+ }
+
+
+ /**
+ * 同步数据库表结构信息
+ *
+ * @param conn 数据库连接
+ * @param databaseName 数据库名称
+ * @param table 表信息,包含表名和表ID
+ */
+ public void syncData(Connection conn, String databaseName, TableInfo table) {
+ // 创建一个单线程执行器,用于提交保存或更新结构信息的任务
+ ExecutorService threadPool = Executors.newSingleThreadExecutor();
+
+ // 准备SQL查询语句,用于获取指定数据库表的列信息
+ String sql = "SELECT\n" +
+ " COLUMN_NAME,\n" +
+ " COLUMN_COMMENT,\n" +
+ " CASE WHEN COLUMN_KEY = 'PRI' THEN '是' ELSE '否' END AS IS_PRIMARY_KEY,\n" +
+ " CASE\n" +
+ " WHEN DATA_TYPE = 'int' THEN 'Integer'\n" +
+ " WHEN DATA_TYPE = 'bigint' THEN 'Long'\n" +
+ " WHEN DATA_TYPE = 'varchar' THEN 'String'\n" +
+ " WHEN DATA_TYPE = 'decimal' THEN 'BigDecimal'\n" +
+ " WHEN DATA_TYPE = 'tinyint' AND COLUMN_TYPE = 'tinyint(1)' THEN 'Boolean'\n" +
+ " ELSE DATA_TYPE\n" +
+ " END AS GENERIC_DATA_TYPE,\n" +
+ " DATA_TYPE AS ORIGINAL_DATA_TYPE,\n" +
+ " COLUMN_TYPE AS DETAILED_DATA_TYPE,\n" +
+ " CHARACTER_MAXIMUM_LENGTH,\n" +
+ " NUMERIC_SCALE,\n" +
+ " IS_NULLABLE,\n" +
+ " COLUMN_DEFAULT\n" +
+ "FROM\n" +
+ " INFORMATION_SCHEMA.COLUMNS\n" +
+ "WHERE\n" +
+ " TABLE_SCHEMA = ?\n" +
+ " AND TABLE_NAME = ?;";
+
+ // 创建PreparedStatement对象,用于执行SQL查询
+ PreparedStatement ps = null;
+ // 创建ResultSet对象,用于存储查询结果
+ ResultSet resultSet = null;
+
+ try {
+ // 准备SQL语句并设置参数
+ ps = conn.prepareStatement(sql);
+ ps.setString(1, databaseName);
+ ps.setString(2, table.getTableName());
+
+ // 执行查询并处理结果
+ resultSet = ps.executeQuery();
+ while (resultSet.next()) {
+ // 获取列信息并构建Structure对象
+ Structure build = Structure.builder()
+ .tableId(table.getId())
+ .columnName(resultSet.getString(1))
+ .columnRemark(resultSet.getString(2))
+ .isPrimary("是".equals(resultSet.getString(3)) ? "Y" : "N")
+ .javaType(resultSet.getString(4))
+ .columnType(resultSet.getString(6))
+ .columnLength(String.valueOf(resultSet.getInt(7)))
+ .columnDecimals(String.valueOf(resultSet.getInt(8)))
+ .isNull("YES".equals(resultSet.getString(9)) ? "Y" : "N")
+ .defaultValue(resultSet.getString(10))
+ .build();
+
+ // 提交保存或更新结构信息的任务到线程池
+ threadPool.submit(() -> {
+ try {
+ structureService.saveOrUpdate(build, new LambdaUpdateWrapper() {{
+ eq(Structure::getTableId, build.getTableId());
+ eq(Structure::getColumnName, build.getColumnName());
+ eq(Structure::getColumnRemark, build.getColumnRemark());
+ }});
+ } catch (Exception e) {
+ log.error("保存或更新结构信息失败", e);
+ }
+ });
+ }
+
+ // 关闭线程池并等待所有任务完成
+ threadPool.shutdown();
+ threadPool.awaitTermination(1, TimeUnit.MINUTES);
+ } catch (SQLException e) {
+ throw new RuntimeException("Error executing SQL query: " + e.getMessage(), e);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException("Thread interrupted", e);
+ } finally {
+ // 安静地关闭资源
+ closeQuietly(ps);
+ closeQuietly(resultSet);
+ if (!threadPool.isTerminated()) {
+ threadPool.shutdownNow(); // 强制关闭线程池
+ }
+ }
+ }
+
+ /**
+ * 安静地关闭资源,忽略关闭时产生的异常
+ *
+ * @param closeable 需要关闭的资源
+ */
+ private void closeQuietly(AutoCloseable closeable) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (Exception e) {
+ log.error("关闭资源时发生异常", e);
+ }
+ }
+ }
+
+
+ /**
+ * 同步Oracle数据库表结构数据到本地
+ *
+ * @param conn 数据库连接
+ * @param databaseName 数据库名称
+ * @param table 表信息
+ */
+ public void syncOracleData(Connection conn, String databaseName, TableInfo table) {
+ // 创建一个可缓存线程池,用于提交结构更新任务
+ ExecutorService threadPool = Executors.newCachedThreadPool();
+ // 准备执行SQL的PreparedStatement对象
+ PreparedStatement ps = null;
+ try {
+ // 创建SQL,用于查询表的列信息,包括列名、数据类型等
+ String sql = "SELECT \n" +
+ " COLUMN_NAME, \n" +
+ " NULL AS COLUMN_COMMENT, \n" +
+ " CASE \n" +
+ " WHEN DATA_TYPE = 'NUMBER' AND DATA_PRECISION IS NOT NULL AND DATA_SCALE = 0 THEN 'Integer' \n" +
+ " WHEN DATA_TYPE = 'NUMBER' THEN 'BigDecimal' \n" +
+ " WHEN DATA_TYPE = 'VARCHAR2' THEN 'String' \n" +
+ " WHEN DATA_TYPE = 'CHAR' THEN 'String'\n" +
+ " WHEN DATA_TYPE = 'BINARY_FLOAT' OR DATA_TYPE = 'BINARY_DOUBLE' THEN 'Double' -- \n" +
+ " WHEN DATA_TYPE = 'NUMBER' AND DATA_SCALE = 1 AND COLUMN_NAME LIKE '%IS_ACTIVE%' THEN 'Boolean' -- \n" +
+ " ELSE DATA_TYPE \n" +
+ " END AS GENERIC_DATA_TYPE, \n" +
+ " DATA_TYPE AS ORIGINAL_DATA_TYPE, \n" +
+ " DATA_TYPE || '(' || CASE WHEN DATA_LENGTH IS NULL THEN NULL ELSE TO_CHAR(DATA_LENGTH) END \n" +
+ " || CASE WHEN DATA_SCALE IS NULL THEN NULL ELSE ', ' || TO_CHAR(DATA_SCALE) END || ')' AS DETAILED_DATA_TYPE, \n" +
+ " CASE WHEN DATA_TYPE IN ('VARCHAR2', 'CHAR') THEN DATA_LENGTH ELSE NULL END AS CHARACTER_MAXIMUM_LENGTH, \n" +
+ " NULLABLE AS IS_NULLABLE, \n" +
+ " DATA_DEFAULT AS COLUMN_DEFAULT \n" +
+ "FROM \n" +
+ " ALL_TAB_COLUMNS \n" +
+ "WHERE \n" +
+ " OWNER = UPPER(?) \n" +
+ " AND TABLE_NAME = UPPER(?)";
+ // 使用数据库连接预编译SQL
+ ps = conn.prepareStatement(sql);
+ // 设置SQL参数,数据库名称和表名
+ ps.setString(1, databaseName);
+ ps.setString(2, table.getTableName());
+
+ // 执行查询并获取结果集
+ ResultSet resultSet = ps.executeQuery();
+ // 遍历结果集,处理每一行数据
+ while (resultSet.next()) {
+ // 从结果集中提取列信息
+ String columnName = resultSet.getString(1);
+ String columnComment = resultSet.getString(2);
+ String javaType = resultSet.getString(3);
+ String columnType = resultSet.getString(4);
+ String isNullable = resultSet.getString(7);
+ String columnDefault = resultSet.getString(8);
+
+ // 构建表结构信息对象
+ Structure build = Structure.builder()
+ .tableId(table.getId())
+ .columnName(columnName)
+ .columnRemark(columnComment)
+ .isPrimary("N")
+ .javaType(javaType)
+ .columnType(columnType)
+ .isNull("YES".equals(isNullable) ? "Y" : "N")
+ .defaultValue(columnDefault)
+ .build();
+
+ // 提交任务到线程池,异步更新本地表结构信息
+ threadPool.submit(() -> {
+ // 复制结构信息对象,准备更新
+ Structure buildCopy = Structure.builder()
+ .tableId(build.getTableId())
+ .columnName(build.getColumnName())
+ .columnRemark(build.getColumnRemark())
+ .isPrimary(build.getIsPrimary())
+ .javaType(build.getJavaType())
+ .columnType(build.getColumnType())
+ .isNull(build.getIsNull())
+ .defaultValue(build.getDefaultValue())
+ .build();
+
+ // 使用服务保存或更新结构信息
+ structureService.saveOrUpdate(buildCopy, new LambdaUpdateWrapper() {{
+ eq(Structure::getTableId, buildCopy.getTableId());
+ eq(Structure::getColumnName, buildCopy.getColumnName());
+ eq(Structure::getColumnRemark, buildCopy.getColumnRemark());
+ }});
+ });
+ }
+
+ } catch (SQLException e) {
+ // 记录并抛出SQL异常
+ log.error("同步Oracle数据时发生错误", e);
+ throw new RuntimeException("同步Oracle数据时发生错误", e);
+ } finally {
+ // 关闭资源,先关闭PreparedStatement,然后关闭线程池
+ if (ps != null) {
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ log.error("关闭PreparedStatement出错", e);
+ }
+ }
+ threadPool.shutdown();
+ }
+ }
+
+
+// else if (dataSources.getType().equals(REDIS)){
+// RedisPool redisPool = new RedisPool(dataSources);
+// redisPool.init();
+// Jedis jedis = redisPool.getConn();
+// String cursor = ScanParams.SCAN_POINTER_START;
+// ScanParams scanParams = new ScanParams().count(100);
+// HashMap map = new HashMap<>();
+// while (true){
+// ScanResult scanResult = jedis.scan(cursor, scanParams);
+// List keys = scanResult.getResult();
+// for (String key : keys) {
+// String value = jedis.get(key);
+// if (value!=null){
+// map.put(key,value);
+// }
+// }
+// cursor = scanResult.getCursor();
+// if (cursor.equals(ScanParams.SCAN_POINTER_START)){
+// break;
+// }
+// }
+// System.out.println(map);
+// redisPool.replease(jedis);
+// redisPool.closeConn();
+// }
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/DataValueServiceImpl.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/DataValueServiceImpl.java
new file mode 100644
index 0000000..0c7450d
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/DataValueServiceImpl.java
@@ -0,0 +1,323 @@
+package com.muyu.datasources.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.muyu.client.mysql.MySqlDataSource;
+import com.muyu.client.mysql.MySqlQuery;
+import com.muyu.common.data.base.BaseQueryHandler;
+import com.muyu.common.domain.DataSources;
+import com.muyu.common.domain.TableInfo;
+
+import com.muyu.common.pool.MysqlPool;
+import com.muyu.datasources.mapper.DataValueMapper;
+
+import com.muyu.datasources.service.DataValueService;
+import com.muyu.datasources.service.DataSourcesService;
+import com.muyu.datasources.service.TableInfoService;
+import com.muyu.etl.domain.DataValue;
+import com.muyu.etl.enums.DataType;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static com.muyu.common.pool.base.BaseConfig.SELECTALL;
+
+/**
+ * @Author:zhangzhihao
+ * @name:DataKltvServiceImpl
+ * @Date:2024/8/27 15:37
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Log4j2
+@Service
+public class DataValueServiceImpl extends ServiceImpl implements DataValueService {
+
+ @Autowired
+ private DataSourcesService dataSourcesService;
+
+
+ @Autowired
+ private TableInfoService tableInfoService;
+
+
+
+
+
+@Override
+/**
+ * 根据给定的数据库ID和SQL语句查询表数据
+ *
+ * @param basicId 数据库ID,用于获取对应的数据库连接
+ * @param sql 执行的SQL语句
+ * @return 返回查询结果,包含每个字段的数据值列表
+ */
+public List> findTableValue(Long basicId, String sql) {
+
+ // 根据数据库ID获取数据库配置信息
+ DataSources dataSources = dataSourcesService.getById(basicId);
+ // 创建MySQL连接池并初始化
+ MysqlPool mysqlPool = new MysqlPool(dataSources);
+ mysqlPool.init();
+ // 获取数据库连接
+ Connection conn = mysqlPool.getConn();
+
+ // 创建列表用于存储查询结果
+ List> list = new ArrayList<>();
+
+ // 使用try-with-resources确保连接最终被关闭
+ try (conn; PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ // 执行查询并获取结果集
+ ResultSet resultSet = preparedStatement.executeQuery();
+ // 获取结果集的元数据
+ ResultSetMetaData metaData = resultSet.getMetaData();
+ // 获取列数
+ int columnCount = metaData.getColumnCount();
+
+ // 使用ConcurrentHashMap存储列索引与DataValue对象的映射
+ ConcurrentHashMap map = new ConcurrentHashMap<>();
+ // 遍历结果集中的每一行
+ while (resultSet.next()) {
+ // 创建列表存储当前行的数据值
+ ArrayList dataValues = new ArrayList<>();
+ // 遍历每一列
+ for (int i = 1; i <= columnCount; i++) {
+ // 如果是结果集的第一行,初始化DataValue对象
+ if (resultSet.isFirst()) {
+ // 获取列的类型名称
+ String columnTypeName = metaData.getColumnTypeName(i);
+ // 获取数据库元数据
+ DatabaseMetaData metaDataColumns = conn.getMetaData();
+ // 获取列的详细信息
+ ResultSet columns = metaDataColumns.getColumns(null, null, metaData.getTableName(i), metaData.getColumnName(i));
+ // 初始化备注信息
+ String remarks = null;
+
+ // 从列的详细信息中获取备注
+ while (columns.next()) {
+ remarks = columns.getString("REMARKS");
+ log.info("字段备注: " + remarks);
+ }
+
+ // 构建DataValue对象并添加到列表中
+ DataValue build = DataValue.builder()
+ .key(metaData.getColumnName(i))
+ .label(remarks)
+ .value(resultSet.getObject(i, DataType.convertType(columnTypeName)))
+ .type(DataType.findBySqlType(columnTypeName))
+ .build();
+ dataValues.add(build);
+ map.put(i, build);
+ } else {
+ // 非第一行时,使用已有的DataValue对象更新数据值
+ DataValue build = DataValue.builder()
+ .key(metaData.getColumnName(i))
+ .label(map.get(i).getLabel())
+ .value(resultSet.getObject(i, map.get(i).getType().getTargetType()))
+ .type(map.get(i).getType())
+ .build();
+ dataValues.add(build);
+ }
+ }
+ // 将当前行的数据值列表添加到结果列表中
+ list.add(dataValues);
+ }
+ } catch (SQLException e) {
+ // 记录数据库操作日志并抛出运行时异常
+ log.error("数据库操作失败", e);
+ throw new RuntimeException("数据库操作失败", e);
+ } finally {
+ // 释放数据库连接并关闭连接池
+ mysqlPool.replease(conn);
+ mysqlPool.closeConn();
+ }
+
+ // 返回查询结果列表
+ return list;
+}
+
+
+
+ @Override
+ public List findTableValueByTableName(Long basicId, String tableName) {
+
+ ConcurrentHashMap map = new ConcurrentHashMap<>();
+ DataSources dataSources = dataSourcesService.getById(basicId);
+ MysqlPool mysqlPool = new MysqlPool(dataSources);
+ mysqlPool.init();
+ Connection conn = mysqlPool.getConn();
+
+ List list = new ArrayList<>();
+
+ try {
+
+ PreparedStatement preparedStatement = conn.prepareStatement(SELECTALL+tableName+" LIMIT 10");
+
+ ResultSet resultSet = preparedStatement.executeQuery();
+ ResultSetMetaData metaData = resultSet.getMetaData();
+ int columnCount = metaData.getColumnCount();
+
+
+ while (resultSet.next()){
+ for (int i = 1; i <= columnCount; i++) {
+ if (resultSet.isFirst()){
+ String columnTypeName = metaData.getColumnTypeName(i);
+
+ DatabaseMetaData metaDataColumns = conn.getMetaData();
+ ResultSet columns = metaDataColumns.getColumns(null, null, metaData.getTableName(i), metaData.getColumnName(i));
+ String remarks =null;
+
+ while (columns.next()){
+ remarks = columns.getString("REMARKS");
+
+ log.info("字段备注:"+remarks);
+ }
+ DataValue build = DataValue.builder()
+ .key(metaData.getColumnName(i))
+ .label(remarks)
+ .value(resultSet.getObject(i, DataType.convertType(columnTypeName)))
+ .type(DataType.findBySqlType(columnTypeName))
+ .build();
+ map.put(i,build);
+ list.add(build);
+ }else {
+ DataValue build = DataValue.builder()
+ .key(metaData.getColumnName(i))
+ .label(map.get(i).getLabel())
+ .value(resultSet.getObject(i, map.get(i).getType().getTargetType()))
+ .type(map.get(i).getType())
+ .build();
+ list.add(build);
+ }
+
+ }
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ mysqlPool.replease(conn);
+ mysqlPool.closeConn();
+ return list;
+ }
+
+ @Override
+ public List> findTableValueContributionRule(Long basicId, Long tableId) {
+ ConcurrentHashMap map = new ConcurrentHashMap<>();
+ TableInfo dataSourceTableInfo = tableInfoService.getById(basicId);
+
+ DataSources dataSources = dataSourcesService.getById(dataSourceTableInfo.getBasicId());
+ TableInfo tableInfo = tableInfoService.getById(tableId);
+ String tableName = tableInfo.getTableName();
+
+ MysqlPool mysqlPool = new MysqlPool(dataSources);
+ mysqlPool.init();
+ Connection conn = mysqlPool.getConn();
+
+ List> list = new ArrayList<>();
+
+ try {
+
+ PreparedStatement preparedStatement = conn.prepareStatement(SELECTALL+tableName);
+
+ ResultSet resultSet = preparedStatement.executeQuery();
+ ResultSetMetaData metaData = resultSet.getMetaData();
+ int columnCount = metaData.getColumnCount();
+
+
+ while (resultSet.next()){
+ ArrayList dataValues = new ArrayList<>();
+ for (int i = 1; i <= columnCount; i++) {
+
+ if (resultSet.isFirst()){
+ String columnTypeName = metaData.getColumnTypeName(i);
+
+ DatabaseMetaData metaDataColumns = conn.getMetaData();
+ ResultSet columns = metaDataColumns.getColumns(null, null, metaData.getTableName(i), metaData.getColumnName(i));
+ String remarks =null;
+
+ while (columns.next()){
+ remarks = columns.getString("REMARKS");
+
+ log.info("字段备注:"+remarks);
+ }
+ DataValue build = DataValue.builder()
+ .key(metaData.getColumnName(i))
+ .label(remarks)
+ .value(resultSet.getObject(i, DataType.convertType(columnTypeName)))
+ .type(DataType.findBySqlType(columnTypeName))
+ .build();
+ dataValues.add(build);
+ map.put(i,build);
+ }else {
+ DataValue build = DataValue.builder()
+ .key(metaData.getColumnName(i))
+ .label(map.get(i).getLabel())
+ .value(resultSet.getObject(i, map.get(i).getType().getTargetType()))
+ .type(map.get(i).getType())
+ .build();
+ dataValues.add(build);
+ }
+
+ }
+ list.add(dataValues);
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ mysqlPool.replease(conn);
+ mysqlPool.closeConn();
+ return list;
+ }
+
+ @Override
+ public Long findCount(Long basicId, String sql) {
+
+
+ DataSources dataSources = dataSourcesService.getById(basicId);
+ MysqlPool mysqlPool = new MysqlPool(dataSources);
+ mysqlPool.init();
+ Connection conn = mysqlPool.getConn();
+ Long count=0L;
+ try {
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery();
+ while (resultSet.next()){
+ count = resultSet.getLong(1);
+ }
+
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }finally {
+ try {
+ conn.close();
+ mysqlPool.closeConn();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ return count;
+ }
+
+ @Override
+ public DataValue[][] findTableValueToArray(Long basicId, String sql, Long one, Integer two) {
+
+ MySqlQuery mySqlQuery = new MySqlQuery();
+ mySqlQuery.setSql(sql);
+ mySqlQuery.setDataSourceId(basicId);
+ mySqlQuery.setOne(one);
+ mySqlQuery.setTwo(two);
+ BaseQueryHandler.set(mySqlQuery);
+ MySqlDataSource mySqlDataSource = new MySqlDataSource();
+ DataValue[][] rows = mySqlDataSource.getRows();
+
+ return rows;
+ }
+
+
+
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/ProductServiceImpl.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/ProductServiceImpl.java
new file mode 100644
index 0000000..2e127d2
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/ProductServiceImpl.java
@@ -0,0 +1,225 @@
+package com.muyu.datasources.service.impl;
+
+import com.muyu.common.domain.DataSources;
+import com.muyu.common.domain.TableInfo;
+
+import com.muyu.common.log.annotation.Log;
+import com.muyu.common.log.enums.BusinessType;
+import com.muyu.datasources.service.DataSourcesService;
+import com.muyu.datasources.service.ProductService;
+import com.muyu.datasources.service.TableInfoService;
+import com.muyu.etl.domain.DataValue;
+import com.muyu.etl.enums.DataType;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+/**
+ * @Author:zhangzhihao
+ * @name:ProductServiceImpl
+ * @Date:2024/9/2 21:12
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Log4j2
+@Service
+public class ProductServiceImpl implements ProductService {
+
+ @Autowired
+ private DataSourcesService dataSourcesService;
+
+ @Autowired
+ private TableInfoService tableInfoService;
+
+ /**
+ * 添加产品
+ * @param basicId
+ * @param tableId
+ * @param listList
+ * @return
+ */
+
+ @Log(title = "添加产品数据库", businessType = BusinessType.INSERT)
+ @Override
+ public int addProduct(Long basicId, Long tableId, DataValue[][] listList) {
+ TableInfo tableInfoDataSources = tableInfoService.getById(basicId);
+ Long basicId1 = tableInfoDataSources.getBasicId();
+ DataSources dataSources = dataSourcesService.getById(basicId1);
+ TableInfo tableInfo = tableInfoService.getById(tableId);
+ String tableName = tableInfo.getTableName();
+
+
+ HikariConfig hikariConfig = new HikariConfig();
+ hikariConfig.setPoolName("HikariCP 连接池");
+ hikariConfig.setDriverClassName(dataSources.getDriverName());
+ hikariConfig.setJdbcUrl(dataSources.getUrl(dataSources));
+ hikariConfig.setUsername(dataSources.getUserName());
+ hikariConfig.setPassword(dataSources.getUserPwd());
+ hikariConfig.setMinimumIdle(2);
+ hikariConfig.setMaximumPoolSize(10);
+ hikariConfig.setMaxLifetime(300000); // 5 minutes
+ hikariConfig.setConnectionTimeout(30000); // 30 seconds
+
+ HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);
+
+ ExecutorService executorService = Executors.newFixedThreadPool(6);
+ AtomicInteger addCount = new AtomicInteger();
+
+ // 分割数据为较小的批次
+ List batches = splitData(listList, 5000);
+
+ try (Connection conn = hikariDataSource.getConnection()) {
+ conn.setAutoCommit(false); // 开启事务
+
+ for (DataValue[][] batch : batches) {
+ executorService.submit(() -> {
+ try (Statement stmt = conn.createStatement()) {
+ String sql = buildBatchInsertSQL(tableName, batch);
+ stmt.executeUpdate(sql);
+ addCount.addAndGet(batch.length);
+ } catch (SQLException e) {
+ log.error("SQLException异常发生", e);
+ try {
+ conn.rollback(); // 回滚事务
+ } catch (SQLException ex) {
+ log.error("回滚事务失败", ex);
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ } catch (Exception e) {
+ log.error("其他异常发生", e);
+ try {
+ conn.rollback(); // 回滚事务
+ } catch (SQLException ex) {
+ log.error("回滚事务失败", ex);
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ executorService.shutdown();
+ if (!executorService.awaitTermination(1, TimeUnit.HOURS)) {
+ log.warn("Executor service did not terminate within the timeout.");
+ executorService.shutdownNow();
+ }
+ conn.commit(); // 提交事务
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ } finally {
+ close(hikariDataSource); // 关闭数据源
+ }
+
+ return addCount.get();
+ }
+
+ private String buildBatchInsertSQL(String tableName, DataValue[][] batch) {
+ StringBuilder columns = new StringBuilder("(");
+ StringBuilder values = new StringBuilder("VALUES ");
+
+ // 构建字段名
+ for (DataValue dataValue : batch[0]) {
+ String key = dataValue.getKey();
+ columns.append(key).append(", ");
+ }
+ // 删除最后一个逗号和空格
+ columns.delete(columns.length() - 2, columns.length());
+
+ // 构建值部分
+ for (DataValue[] dataValueList : batch) {
+ values.append("(");
+ for (DataValue dataValue : dataValueList) {
+ Object value = dataValue.getValue();
+ values.append(formatValue(dataValue.getType(), value)).append(", ");
+ }
+ values.delete(values.length() - 2, values.length());
+ values.append("), ");
+ }
+ // 删除最后一个逗号
+ values.delete(values.length() - 2, values.length());
+
+ // 完成 SQL 插入语句
+ String sql = "INSERT INTO " + tableName + " " + columns.toString() + ") " + values.toString();
+ return sql;
+ }
+
+ private String formatValue(DataType type, Object value) {
+ if (value == null) {
+ // 根据业务需求处理 null 值
+ return "NULL"; // 或者其他默认值
+ }
+
+ if (type == DataType.VARCHAR || type == DataType.TEXT) {
+ return "'" + value.toString().replace("'", "''") + "'";
+ } else if (type == DataType.BIGINT) {
+ return value.toString();
+ } else if (type == DataType.INT) {
+ return value.toString();
+ } else if (type == DataType.DECIMAL) {
+ return value.toString();
+ } else if (type == DataType.DATETIME) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ return "'" + sdf.format((Date) value) + "'";
+ } else if (type == DataType.DOUBLE) {
+ return value.toString();
+ } else {
+ return "'" + value.toString() + "'";
+ }
+ }
+
+ // 分割数据为较小的批次
+ private List splitData(DataValue[][] listList, int batchSize) {
+ List batches = new ArrayList<>();
+ int totalRows = listList.length;
+ int totalBatches = (int) Math.ceil((double) totalRows / batchSize);
+
+ for (int i = 0; i < totalBatches; i++) {
+ int start = i * batchSize;
+ int end = Math.min(start + batchSize, totalRows);
+ DataValue[][] batch = Arrays.copyOfRange(listList, start, end);
+ batches.add(batch);
+ }
+
+ return batches;
+ }
+
+ // 关闭数据源
+ private void close(HikariDataSource dataSource) {
+ dataSource.close();
+ }
+
+
+
+// private void closeConnection(Connection conn, MysqlPool mysqlPool) {
+// try {
+// if (conn != null && !conn.isClosed()) {
+// conn.close();
+// mysqlPool.closeConn();
+// }
+// } catch (SQLException e) {
+// e.printStackTrace();
+// }
+// }
+
+
+}
+
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/StructureServiceImpl.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/StructureServiceImpl.java
new file mode 100644
index 0000000..78374e2
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/StructureServiceImpl.java
@@ -0,0 +1,33 @@
+package com.muyu.datasources.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.muyu.common.domain.Structure;
+import com.muyu.datasources.mapper.StructureMapper;
+import com.muyu.datasources.service.StructureService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:StructureServiceImpl
+ * @Date:2024/8/25 16:49
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Service
+public class StructureServiceImpl extends ServiceImpl implements StructureService {
+
+ @Autowired
+ private StructureMapper structureMapper;
+
+ @Override
+ public List findStructureByTableId(Long id) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(Structure::getTableId,id);
+ List list = structureMapper.selectList(queryWrapper);
+ return list;
+ }
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/SysUserServiceImpl.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/SysUserServiceImpl.java
new file mode 100644
index 0000000..5ce6dfc
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/SysUserServiceImpl.java
@@ -0,0 +1,25 @@
+package com.muyu.datasources.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.muyu.common.system.domain.SysUser;
+import com.muyu.datasources.mapper.SysUserMapper;
+import com.muyu.datasources.service.SysUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Author:zhangzhihao
+ * @name:SysUserServiceImpl
+ * @Date:2024/8/31 18:48
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Service
+public class SysUserServiceImpl extends ServiceImpl implements SysUserService {
+ @Autowired
+ private SysUserMapper userMapper;
+
+ @Override
+ public SysUser findUserById(Long userId) {
+ return userMapper.findUserById(userId);
+ }
+}
diff --git a/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/TableInfoServiceImpl.java b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/TableInfoServiceImpl.java
new file mode 100644
index 0000000..94c7afa
--- /dev/null
+++ b/cloud-datasources-server/src/main/java/com/muyu/datasources/service/impl/TableInfoServiceImpl.java
@@ -0,0 +1,42 @@
+package com.muyu.datasources.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.muyu.common.domain.TableInfo;
+import com.muyu.datasources.mapper.TableInfoMapper;
+import com.muyu.datasources.service.TableInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Author:zhangzhihao
+ * @name:TableInfoServiceImpl
+ * @Date:2024/8/25 11:37
+ * 不准抄代码,添加注释,清楚每一行代码意思
+ */
+@Service
+public class TableInfoServiceImpl extends ServiceImpl implements TableInfoService {
+
+ @Autowired
+ private TableInfoMapper tableInfoMapper;
+
+
+ @Override
+ public TableInfo selectTableInfoByName(TableInfo tableInfoInsert) {
+
+ LambdaQueryWrapper tableInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
+
+
+ tableInfoLambdaQueryWrapper.eq(TableInfo::getBasicId, tableInfoInsert.getBasicId())
+ .eq(TableInfo::getTableName, tableInfoInsert.getTableName())
+ .eq(TableInfo::getParentId, tableInfoInsert.getParentId());
+ return this.tableInfoMapper.selectOne(tableInfoLambdaQueryWrapper);
+ }
+
+ @Override
+ public List findTableIdByParentId(Long basicId) {
+ return tableInfoMapper.findTableIdByParentId(basicId);
+ }
+}
diff --git a/cloud-datasources-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/cloud-datasources-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/cloud-datasources-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+
diff --git a/cloud-datasources-server/src/main/resources/banner.txt b/cloud-datasources-server/src/main/resources/banner.txt
new file mode 100644
index 0000000..0dd5eee
--- /dev/null
+++ b/cloud-datasources-server/src/main/resources/banner.txt
@@ -0,0 +1,2 @@
+Spring Boot Version: ${spring-boot.version}
+Spring Application Name: ${spring.application.name}
diff --git a/cloud-datasources-server/src/main/resources/bootstrap.yml b/cloud-datasources-server/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..c82eb85
--- /dev/null
+++ b/cloud-datasources-server/src/main/resources/bootstrap.yml
@@ -0,0 +1,56 @@
+# Tomcat
+server:
+ port: 12000
+
+# nacos线上地址
+nacos:
+ addr: 12.2.0.252:8848
+ user-name: nacos
+ password: nacos
+ namespace: muyu-cloud
+
+# Spring
+spring:
+ main:
+ allow-bean-definition-overriding: true
+ application:
+ # 应用名称
+ name: cloud-etl-datasources
+ profiles:
+ # 环境配置
+ active: dev
+ cloud:
+ nacos:
+ discovery:
+ # 服务注册地址
+ server-addr: ${nacos.addr}
+ # nacos用户名
+ username: ${nacos.user-name}
+ # nacos密码
+ password: ${nacos.password}
+ # 命名空间
+ namespace: ${nacos.namespace}
+ config:
+ # 服务注册地址
+ server-addr: ${nacos.addr}
+ # nacos用户名
+ username: ${nacos.user-name}
+ # nacos密码
+ password: ${nacos.password}
+ # 命名空间
+ namespace: ${nacos.namespace}
+ # 配置文件格式
+ file-extension: yml
+ # 共享配置
+ shared-configs:
+ # 系统共享配置
+ - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
+ # 系统环境Config共享配置
+ - application-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
+ # xxl-job 配置文件
+ - application-xxl-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
+ # rabbit 配置文件
+ - application-rabbit-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
+logging:
+ level:
+ com.muyu.system.mapper: DEBUG
diff --git a/cloud-datasources-server/src/main/resources/logback/dev.xml b/cloud-datasources-server/src/main/resources/logback/dev.xml
new file mode 100644
index 0000000..100deef
--- /dev/null
+++ b/cloud-datasources-server/src/main/resources/logback/dev.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+ ${log.pattern}
+
+
+
+
+
+ ${log.path}/info.log
+
+
+
+ ${log.path}/info.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+ ${log.pattern}
+
+
+
+ INFO
+
+ ACCEPT
+
+ DENY
+
+
+
+
+ ${log.path}/error.log
+
+
+
+ ${log.path}/error.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+ ${log.pattern}
+
+
+
+ ERROR
+
+ ACCEPT
+
+ DENY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cloud-datasources-server/src/main/resources/logback/prod.xml b/cloud-datasources-server/src/main/resources/logback/prod.xml
new file mode 100644
index 0000000..bcab75a
--- /dev/null
+++ b/cloud-datasources-server/src/main/resources/logback/prod.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+ ${log.sky.pattern}
+
+
+
+
+
+ ${log.path}/info.log
+
+
+
+ ${log.path}/info.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+
+
+ INFO
+
+ ACCEPT
+
+ DENY
+
+
+
+
+ ${log.path}/error.log
+
+
+
+ ${log.path}/error.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+
+
+ ERROR
+
+ ACCEPT
+
+ DENY
+
+
+
+
+
+
+
+ ${log.sky.pattern}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cloud-datasources-server/src/main/resources/logback/test.xml b/cloud-datasources-server/src/main/resources/logback/test.xml
new file mode 100644
index 0000000..bcab75a
--- /dev/null
+++ b/cloud-datasources-server/src/main/resources/logback/test.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+ ${log.sky.pattern}
+
+
+
+
+
+ ${log.path}/info.log
+
+
+
+ ${log.path}/info.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+
+
+ INFO
+
+ ACCEPT
+
+ DENY
+
+
+
+
+ ${log.path}/error.log
+
+
+
+ ${log.path}/error.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+
+
+ ERROR
+
+ ACCEPT
+
+ DENY
+
+
+
+
+
+
+
+ ${log.sky.pattern}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cloud-datasources-server/src/main/resources/mapper/AssetAccreditMapper.xml b/cloud-datasources-server/src/main/resources/mapper/AssetAccreditMapper.xml
new file mode 100644
index 0000000..13955a4
--- /dev/null
+++ b/cloud-datasources-server/src/main/resources/mapper/AssetAccreditMapper.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cloud-datasources-server/src/main/resources/mapper/SysUserMapper.xml b/cloud-datasources-server/src/main/resources/mapper/SysUserMapper.xml
new file mode 100644
index 0000000..2f096f3
--- /dev/null
+++ b/cloud-datasources-server/src/main/resources/mapper/SysUserMapper.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/cloud-datasources-server/src/main/resources/mapper/TableInfoMapper.xml b/cloud-datasources-server/src/main/resources/mapper/TableInfoMapper.xml
new file mode 100644
index 0000000..674f484
--- /dev/null
+++ b/cloud-datasources-server/src/main/resources/mapper/TableInfoMapper.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ec4390e
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,28 @@
+
+
+ 4.0.0
+
+ com.muyu
+ cloud-server-parent
+ 3.6.4
+
+
+ cloud-etl-datasources
+ 1.0.0
+ pom
+
+ cloud-datasources-common
+ cloud-datasources-remote
+ cloud-datasources-server
+ cloud-datasources-client
+
+
+
+ 17
+ 17
+ UTF-8
+
+
+