diff --git a/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DataWarehouseDataSourceMapper.xml b/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DataWarehouseDataSourceMapper.xml
index c2ae1ffca2c36354498da88df08ae4f4539416f1..f6f45dccae023bacf8406144c159ee099b8897ca 100644
--- a/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DataWarehouseDataSourceMapper.xml
+++ b/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DataWarehouseDataSourceMapper.xml
@@ -52,6 +52,7 @@ along with this program. If not, see .-->
+
@@ -104,6 +105,7 @@ along with this program. If not, see .-->
a.module_id as moduleId,
a.data_count as dataCount,
a.db_type as dbType,
+ a.database_id as databaseId,
b.id as fieldId,
b.name as fieldName,
b.label as fieldLabel,
@@ -203,6 +205,7 @@ along with this program. If not, see .-->
expire_unit = #{expireUnit},
is_active = #{isActive},
db_type = #{dbType},
+ database_id = #{databaseId},
xml = #{xml,typeHandler=CompressHandler}
where id = #{id}
@@ -238,6 +241,7 @@ along with this program. If not, see .-->
expire_unit,
xml,
db_type,
+ database_id,
is_active)
values (#{id},
#{name},
@@ -250,6 +254,7 @@ along with this program. If not, see .-->
#{expireUnit},
#{xml,typeHandler=CompressHandler},
#{dbType},
+ #{databaseId},
#{isActive})
diff --git a/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DatabaseMapper.java b/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DatabaseMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ec0cd2d26562f3a8a3d039dc6426ac21425f686
--- /dev/null
+++ b/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DatabaseMapper.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package neatlogic.framework.datawarehouse.dao.mapper;
+
+import neatlogic.framework.datawarehouse.dto.DatabaseVo;
+
+import java.util.List;
+
+public interface DatabaseMapper {
+
+ DatabaseVo getDataBaseById(Long id);
+
+ int checkDatabaseNameIsRepeat(DatabaseVo dataBaseVo);
+
+ int getDataBaseCount(DatabaseVo DataBaseVo);
+
+ List getDataBaseList(DatabaseVo DataBaseVo);
+
+ int insertDataBase(DatabaseVo DataBaseVo);
+
+ int deleteDataBaseById(Long id);
+}
diff --git a/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DatabaseMapper.xml b/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DatabaseMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1c7052e57038e548b42257c993db16de1b8dbb7b
--- /dev/null
+++ b/src/main/java/neatlogic/framework/datawarehouse/dao/mapper/DatabaseMapper.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ INSERT INTO `database` (`id`, `name`, `type`, `config`, `file_id_list`)
+ VALUES (#{id}, #{name}, #{type}, #{configStr, typeHandler=CompressHandler}, #{fileIdListStr})
+ ON DUPLICATE KEY UPDATE
+ `name` = #{name},
+ `type` = #{type},
+ `config` = #{configStr, typeHandler=CompressHandler},
+ `file_id_list` = #{fileIdListStr}
+
+
+
+ DELETE FROM `database` WHERE `id` = #{value}
+
+
\ No newline at end of file
diff --git a/src/main/java/neatlogic/framework/datawarehouse/dto/DataSourceVo.java b/src/main/java/neatlogic/framework/datawarehouse/dto/DataSourceVo.java
index 085b83b26a3299260deb2ff4cc304e19216e20a1..d7f9c9b3176acd78b7be1ffa7dceffbc1b2e2a50 100644
--- a/src/main/java/neatlogic/framework/datawarehouse/dto/DataSourceVo.java
+++ b/src/main/java/neatlogic/framework/datawarehouse/dto/DataSourceVo.java
@@ -76,6 +76,8 @@ public class DataSourceVo extends BasePageVo {
private List fieldList = new ArrayList<>();//需要默认值为空数组,避免空指针异常
@EntityField(name = "nfdd.datasourcevo.entityfield.name.connectionid", type = ApiParamType.LONG)
private Long connectionId;
+ @EntityField(name = "nfdd.datasourcevo.entityfield.name.databaseid", type = ApiParamType.LONG)
+ private Long databaseId;
@JSONField(serialize = false)//数据列表
private List dataList;
@EntityField(name = "nfdd.datasourcevo.entityfield.name.paramlist", type = ApiParamType.JSONARRAY)
@@ -249,6 +251,14 @@ public class DataSourceVo extends BasePageVo {
this.connectionId = connectionId;
}
+ public Long getDatabaseId() {
+ return databaseId;
+ }
+
+ public void setDatabaseId(Long databaseId) {
+ this.databaseId = databaseId;
+ }
+
public void setQueryTimeout(Integer queryTimeout) {
this.queryTimeout = queryTimeout;
}
diff --git a/src/main/java/neatlogic/framework/datawarehouse/dto/DatabaseVo.java b/src/main/java/neatlogic/framework/datawarehouse/dto/DatabaseVo.java
new file mode 100644
index 0000000000000000000000000000000000000000..71a736110e785dbab932acc7d75e016eae55a213
--- /dev/null
+++ b/src/main/java/neatlogic/framework/datawarehouse/dto/DatabaseVo.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package neatlogic.framework.datawarehouse.dto;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.annotation.JSONField;
+import neatlogic.framework.common.dto.BasePageVo;
+import neatlogic.framework.file.dto.FileVo;
+
+import java.util.List;
+
+public class DatabaseVo extends BasePageVo {
+ private Long id;
+ private String name;
+ private String type;
+ private JSONObject config;
+ private List fileIdList;
+ private List fileList;
+ @JSONField(serialize = false)
+ private String configStr;
+ @JSONField(serialize = false)
+ private String fileIdListStr;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public JSONObject getConfig() {
+ if (config == null && configStr != null) {
+ try {
+ config = JSONObject.parseObject(configStr);
+ } catch (Exception ignored) {
+
+ }
+ }
+ return this.config;
+ }
+
+ public void setConfig(JSONObject config) {
+ this.config = config;
+ }
+
+ public String getConfigStr() {
+ if (config != null) {
+ configStr = config.toJSONString();
+ }
+ return configStr;
+ }
+
+ public void setConfigStr(String configStr) {
+ this.configStr = configStr;
+ }
+
+ public List getFileIdList() {
+ if (fileIdList == null && fileIdListStr != null) {
+ try {
+ fileIdList = JSONArray.parseArray(fileIdListStr, Long.class);
+ } catch (Exception ignored) {
+
+ }
+ }
+ return fileIdList;
+ }
+
+ public void setFileIdList(List fileIdList) {
+ this.fileIdList = fileIdList;
+ }
+
+ public List getFileList() {
+ return fileList;
+ }
+
+ public void setFileList(List fileList) {
+ this.fileList = fileList;
+ }
+
+ public String getFileIdListStr() {
+ if (fileIdListStr == null && fileIdList != null) {
+ fileIdListStr = JSONArray.toJSONString(fileIdList);
+ }
+ return fileIdListStr;
+ }
+
+ public void setFileIdListStr(String fileIdListStr) {
+ this.fileIdListStr = fileIdListStr;
+ }
+}
diff --git a/src/main/java/neatlogic/framework/datawarehouse/exceptions/DatabaseConnectionFailedException.java b/src/main/java/neatlogic/framework/datawarehouse/exceptions/DatabaseConnectionFailedException.java
new file mode 100644
index 0000000000000000000000000000000000000000..eaca60a5851483a9a15c43ece7660e3975e162e8
--- /dev/null
+++ b/src/main/java/neatlogic/framework/datawarehouse/exceptions/DatabaseConnectionFailedException.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package neatlogic.framework.datawarehouse.exceptions;
+
+import neatlogic.framework.exception.core.ApiRuntimeException;
+import neatlogic.framework.util.$;
+
+public class DatabaseConnectionFailedException extends ApiRuntimeException {
+
+ public enum Type {
+ CONFIG_IS_EMPTY, FILE_ID_LIST_IS_EMPTY
+ }
+ public DatabaseConnectionFailedException(Type type, String name) {
+ super(getMessage(type, name));
+ }
+
+ private static String getMessage(Type type, String name) {
+ if (type == Type.FILE_ID_LIST_IS_EMPTY) {
+ return $.t("nfde.databaseconnectionfailedexception.fileidlistisempty", name);
+ } else {
+ return $.t("{0}nfde.databaseconnectionfailedexception.configisempty", name);
+ }
+ }
+}
diff --git a/src/main/java/neatlogic/framework/datawarehouse/exceptions/DatabaseNameRepeatException.java b/src/main/java/neatlogic/framework/datawarehouse/exceptions/DatabaseNameRepeatException.java
new file mode 100644
index 0000000000000000000000000000000000000000..d82f5afe28bc9e6c172a67fb35e53e477b905339
--- /dev/null
+++ b/src/main/java/neatlogic/framework/datawarehouse/exceptions/DatabaseNameRepeatException.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package neatlogic.framework.datawarehouse.exceptions;
+
+import neatlogic.framework.exception.core.ApiRuntimeException;
+
+public class DatabaseNameRepeatException extends ApiRuntimeException {
+ public DatabaseNameRepeatException(String name) {
+ super("nfde.databasenamerepeatexception.databasenamerepeatexception", name);
+ }
+}
diff --git a/src/main/java/neatlogic/framework/datawarehouse/exceptions/DatabaseNotFoundException.java b/src/main/java/neatlogic/framework/datawarehouse/exceptions/DatabaseNotFoundException.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5c412c4c0e936ca7a38d960a24c64d2694f5453
--- /dev/null
+++ b/src/main/java/neatlogic/framework/datawarehouse/exceptions/DatabaseNotFoundException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package neatlogic.framework.datawarehouse.exceptions;
+
+import neatlogic.framework.exception.core.ApiRuntimeException;
+
+public class DatabaseNotFoundException extends ApiRuntimeException {
+
+ public DatabaseNotFoundException(Long id) {
+ super("nfde.databasenotfoundexception.databasenotfoundexception", id);
+ }
+}
diff --git a/src/main/java/neatlogic/framework/datawarehouse/service/DatabaseService.java b/src/main/java/neatlogic/framework/datawarehouse/service/DatabaseService.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a91a6d66d2f94aa41edd01c83af0163830d8d3a
--- /dev/null
+++ b/src/main/java/neatlogic/framework/datawarehouse/service/DatabaseService.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package neatlogic.framework.datawarehouse.service;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public interface DatabaseService {
+
+ Connection getConnectionByDatabaseId(Long databaseId) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException;
+}
diff --git a/src/main/java/neatlogic/framework/datawarehouse/service/DatabaseServiceImpl.java b/src/main/java/neatlogic/framework/datawarehouse/service/DatabaseServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..d171a6c6c8e4c76aade599e76acd75af2d0fff0f
--- /dev/null
+++ b/src/main/java/neatlogic/framework/datawarehouse/service/DatabaseServiceImpl.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package neatlogic.framework.datawarehouse.service;
+
+import com.alibaba.fastjson.JSONObject;
+import neatlogic.framework.common.util.FileUtil;
+import neatlogic.framework.datawarehouse.dao.mapper.DatabaseMapper;
+import neatlogic.framework.datawarehouse.dto.DatabaseVo;
+import neatlogic.framework.datawarehouse.exceptions.DatabaseConnectionFailedException;
+import neatlogic.framework.datawarehouse.exceptions.DatabaseNotFoundException;
+import neatlogic.framework.exception.file.FileNotFoundException;
+import neatlogic.framework.file.dao.mapper.FileMapper;
+import neatlogic.framework.file.dto.FileVo;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Properties;
+
+@Service
+public class DatabaseServiceImpl implements DatabaseService {
+
+ static Logger logger = LoggerFactory.getLogger(DatabaseServiceImpl.class);
+
+ @Resource
+ private DatabaseMapper databaseMapper;
+
+ @Resource
+ private FileMapper fileMapper;
+
+
+ @Override
+ public Connection getConnectionByDatabaseId(Long databaseId) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
+ DatabaseVo dataBaseVo = databaseMapper.getDataBaseById(databaseId);
+ if (dataBaseVo == null) {
+ throw new DatabaseNotFoundException(databaseId);
+ }
+ List fileIdList = dataBaseVo.getFileIdList();
+ if (CollectionUtils.isNotEmpty(fileIdList)) {
+ URL[] urls = new URL[fileIdList.size()];
+ for (int i = 0; i < fileIdList.size(); i++) {
+ Long fileId = fileIdList.get(i);
+ FileVo fileVo = fileMapper.getFileById(fileId);
+ if (fileVo == null) {
+ throw new FileNotFoundException(fileId);
+ }
+ try (InputStream is = FileUtil.getData(fileVo.getPath())) {
+ String fileName = fileVo.getName();
+ String suffix = ".jar";
+ String prefix = fileName.substring(0, fileName.length() - suffix.length());
+ File file = new File(prefix + "-" + fileVo.getId() + suffix);
+ if (!file.exists()) {
+ Path path = Paths.get(file.toURI());
+ Files.copy(is, path);
+ }
+ urls[i] = file.toURI().toURL();
+ }catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ throw new RuntimeException(e);
+ }
+ }
+ JSONObject config = dataBaseVo.getConfig();
+ if (MapUtils.isNotEmpty(config)) {
+ String user = config.getString("user");
+ String password = config.getString("password");
+ String url = config.getString("url");
+ String driverClassName = config.getString("driverClassName");
+ Properties props = new Properties();
+ if (StringUtils.isNoneBlank(user)) {
+ props.put("user", user);
+ }
+ if (StringUtils.isNotBlank(password)) {
+ props.put("password", password);
+ }
+ URLClassLoader loader = new URLClassLoader(urls, null);
+ Class> clazz = loader.loadClass(driverClassName);
+ Driver driver = ((Driver) clazz.newInstance());
+ return driver.connect(url, props);
+ } else {
+ throw new DatabaseConnectionFailedException(DatabaseConnectionFailedException.Type.CONFIG_IS_EMPTY, dataBaseVo.getName());
+ }
+ } else {
+ throw new DatabaseConnectionFailedException(DatabaseConnectionFailedException.Type.FILE_ID_LIST_IS_EMPTY, dataBaseVo.getName());
+ }
+ }
+}
diff --git a/src/main/java/neatlogic/module/framework/datawarehouse/handler/JDBCDataSourceHandler.java b/src/main/java/neatlogic/module/framework/datawarehouse/handler/JDBCDataSourceHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..72baee90da03a815214df12a8a68a07d73d9e631
--- /dev/null
+++ b/src/main/java/neatlogic/module/framework/datawarehouse/handler/JDBCDataSourceHandler.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package neatlogic.module.framework.datawarehouse.handler;
+
+import neatlogic.framework.datawarehouse.core.DataSourceServiceHandlerBase;
+import neatlogic.framework.datawarehouse.dao.mapper.DataWarehouseDataSourceMapper;
+import neatlogic.framework.datawarehouse.dto.*;
+import neatlogic.framework.datawarehouse.exceptions.ReportDataSourceSyncException;
+import neatlogic.framework.datawarehouse.service.DatabaseService;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.dom4j.DocumentException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.net.URLClassLoader;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class JDBCDataSourceHandler extends DataSourceServiceHandlerBase {
+ static Logger logger = LoggerFactory.getLogger(JDBCDataSourceHandler.class);
+ int FETCH_SIZE = 1000;
+ @Resource
+ private DataWarehouseDataSourceMapper dataSourceMapper;
+ @Resource
+ private DatabaseService databaseService;
+
+ @Override
+ public String getHandler() {
+ return "jdbc";
+ }
+
+ @Override
+ public void mySyncData(DataSourceVo dataSourceVo, DataSourceAuditVo reportDataSourceAuditVo) {
+ Connection conn = null;
+ PreparedStatement queryStatement = null;
+ ResultSet resultSet = null;
+
+ try {
+ List selectList = getSqlFromDataSource(dataSourceVo);
+ conn = getConnection(dataSourceVo);
+ for (SelectVo select : selectList) {
+ String sqlText = select.getSql();
+ queryStatement = conn.prepareStatement(sqlText, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ queryStatement.setFetchSize(FETCH_SIZE);
+ queryStatement.setFetchDirection(ResultSet.FETCH_FORWARD);
+ if (dataSourceVo.getQueryTimeout() != null && dataSourceVo.getQueryTimeout() > 0) {
+ queryStatement.setQueryTimeout(dataSourceVo.getQueryTimeout());
+ }
+
+ if (CollectionUtils.isNotEmpty(select.getParamList())) {
+ for (int p = 0; p < select.getParamList().size(); p++) {
+ if (select.getParamList().get(p) instanceof String || select.getParamList().get(p) instanceof Number) {
+ queryStatement.setObject(p + 1, select.getParamList().get(p));
+ } else if (select.getParamList().get(p) instanceof String[]) {
+ // 数组参数有待处理
+ queryStatement.setObject(p + 1, ((String[]) select.getParamList().get(p))[0]);
+ } else if (select.getParamList().get(p) instanceof Number[]) {
+ // 数组参数有待处理
+ queryStatement.setObject(p + 1, ((Number[]) select.getParamList().get(p))[0]);
+ }
+ }
+ }
+ /*
+ 新增日志记录
+ */
+ if (logger.isInfoEnabled()) {
+ logger.info("REPORT RUN SQL::" + sqlText);
+ }
+
+ resultSet = queryStatement.executeQuery();
+
+ ResultSetMetaData metaData = resultSet.getMetaData();
+ Map fieldMap = new HashMap<>();
+ for (int i = 1; i <= metaData.getColumnCount(); i++) {
+ fieldMap.put(metaData.getColumnLabel(i).toLowerCase(), i);
+ }
+
+ while (resultSet.next()) {
+ DataSourceDataVo reportDataSourceDataVo = new DataSourceDataVo(dataSourceVo.getId());
+ reportDataSourceDataVo.setExpireMinute(dataSourceVo.getExpireMinute());
+ List aggregateFieldList = new ArrayList<>();
+ List keyFieldList = new ArrayList<>();
+ if (CollectionUtils.isNotEmpty(dataSourceVo.getParamList())) {
+ for (DataSourceParamVo paramVo : dataSourceVo.getParamList()) {
+ if (fieldMap.containsKey(paramVo.getName().toLowerCase())) {
+ Object v = resultSet.getObject(fieldMap.get(paramVo.getName().toLowerCase()));
+ Long lv = null;
+ try {
+ lv = (Long) v;
+ } catch (Exception ex) {
+ logger.error(ex.getMessage(), ex);
+ }
+ if (lv != null) {
+ if (paramVo.getCurrentValue() == null) {
+ paramVo.setCurrentValue(lv);
+ } else if (lv > paramVo.getCurrentValue()) {
+ paramVo.setCurrentValue(lv);
+ }
+ }
+ }
+ }
+ }
+ for (DataSourceFieldVo fieldVo : dataSourceVo.getFieldList()) {
+ if (fieldMap.containsKey(fieldVo.getName().toLowerCase())) {
+ Object v = resultSet.getObject(fieldMap.get(fieldVo.getName().toLowerCase()));
+ fieldVo.setValue(v != null ? v : "");//把所有的null值都转成空字符串
+ }
+ reportDataSourceDataVo.addField(fieldVo);
+ if (StringUtils.isNotBlank(fieldVo.getAggregate())) {
+ aggregateFieldList.add(fieldVo);
+ }
+ if (fieldVo.getIsKey().equals(1)) {
+ keyFieldList.add(fieldVo);
+ }
+ }
+ aggregateAndInsertData(aggregateFieldList, keyFieldList, reportDataSourceDataVo, reportDataSourceAuditVo);
+ }
+ if (CollectionUtils.isNotEmpty(dataSourceVo.getParamList())) {
+ for (DataSourceParamVo param : dataSourceVo.getParamList()) {
+ dataSourceMapper.updateDataSourceParamCurrentValue(param);
+ }
+ }
+ }
+ } catch (SQLException | DocumentException | InstantiationException | IllegalAccessException |
+ ClassNotFoundException e) {
+ logger.error(e.getMessage(), e);
+ reportDataSourceAuditVo.setError(e.getMessage());
+ throw new ReportDataSourceSyncException(dataSourceVo, e);
+ } finally {
+ try {
+ if (resultSet != null) {
+ resultSet.close();
+ }
+ if (queryStatement != null) {
+ queryStatement.close();
+ }
+ if (conn != null) {
+ ClassLoader classLoader = conn.getClass().getClassLoader();
+ conn.close();
+ if (classLoader instanceof URLClassLoader) {
+ ((URLClassLoader) classLoader).close();
+ }
+ }
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ private Connection getConnection(DataSourceVo dataSourceVo) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
+ return databaseService.getConnectionByDatabaseId(dataSourceVo.getDatabaseId());
+ }
+}
diff --git a/src/main/resources/neatlogic/resources/framework/changelog/2025-06-03/neatlogic_tenant.sql b/src/main/resources/neatlogic/resources/framework/changelog/2025-06-03/neatlogic_tenant.sql
new file mode 100644
index 0000000000000000000000000000000000000000..f3424461b53e7c09dd53d95d280ffc2d2bfedfef
--- /dev/null
+++ b/src/main/resources/neatlogic/resources/framework/changelog/2025-06-03/neatlogic_tenant.sql
@@ -0,0 +1,10 @@
+CREATE TABLE `database` (
+ `id` bigint NOT NULL COMMENT '主键ID',
+ `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '名称',
+ `type` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '类型',
+ `config` text COLLATE utf8mb4_general_ci NOT NULL COMMENT '配置信息',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+ALTER TABLE `datawarehouse_datasource`
+ ADD COLUMN `database_id` BIGINT NULL COMMENT '数据源' AFTER `db_type`;
\ No newline at end of file
diff --git a/src/main/resources/neatlogic/resources/framework/changelog/2025-06-03/version.json b/src/main/resources/neatlogic/resources/framework/changelog/2025-06-03/version.json
new file mode 100644
index 0000000000000000000000000000000000000000..6ac9cae5001cf39c2f456b519236ffb36ffa9c12
--- /dev/null
+++ b/src/main/resources/neatlogic/resources/framework/changelog/2025-06-03/version.json
@@ -0,0 +1,12 @@
+{
+ "content": [
+ {
+ "type": "功能",
+ "detail": [
+ {
+ "msg": "1.数据仓库支持配置第三方数据库获取数据"
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/main/resources/neatlogic/resources/framework/sqlscript/ddl.sql b/src/main/resources/neatlogic/resources/framework/sqlscript/ddl.sql
index 8987dc4f70e658a2e938c36893bf1746636e87b3..2881a7a9ac89c38babc56f203c7f4859f59d49a2 100644
--- a/src/main/resources/neatlogic/resources/framework/sqlscript/ddl.sql
+++ b/src/main/resources/neatlogic/resources/framework/sqlscript/ddl.sql
@@ -112,6 +112,17 @@ CREATE TABLE IF NOT EXISTS `database_view_info`
CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci COMMENT = '视图信息表';
+-- ----------------------------
+-- Table structure for database
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `database` (
+ `id` bigint NOT NULL COMMENT '主键ID',
+ `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '名称',
+ `type` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '类型',
+ `config` text COLLATE utf8mb4_general_ci NOT NULL COMMENT '配置信息',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
-- ----------------------------
-- Table structure for datawarehouse_datasource
-- ----------------------------
@@ -131,6 +142,7 @@ CREATE TABLE IF NOT EXISTS `datawarehouse_datasource`
`data_count` int NULL DEFAULT NULL COMMENT '数据量',
`expire_unit` enum ('minute','hour','day','month','year') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '过期单位',
`db_type` enum ('mysql','mongodb') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'mysql' COMMENT '数据库类型',
+ `database_id` bigint NULL DEFAULT NULL COMMENT '数据库ID',
`last_fire_time` timestamp(3) NULL DEFAULT NULL COMMENT '最后一次激活时间',
`last_finish_time` timestamp(3) NULL DEFAULT NULL COMMENT '最后一次完成时间',
`next_fire_time` timestamp(3) NULL DEFAULT NULL COMMENT '下一次激活时间',