update system数据库连接信息配置、查询指定数据库下表、字段、数据接口

master
yinq 1 week ago
parent 82f350afae
commit 4280c7684b

@ -1,6 +1,8 @@
package org.dromara.system.controller;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
@ -21,6 +23,8 @@ import org.dromara.system.domain.vo.SysDatabaseLinkVo;
import org.dromara.system.domain.bo.SysDatabaseLinkBo;
import org.dromara.system.service.ISysDatabaseLinkService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.vo.TableInfoVO;
import org.dromara.system.domain.vo.ColumnInfoVO;
/**
*
@ -113,4 +117,33 @@ public class SysDatabaseLinkController extends BaseController {
List<SysDatabaseLinkVo> list = sysDatabaseLinkService.queryList(bo);
return R.ok(list);
}
/**
*
*/
@SaCheckPermission("system:databaseLink:query")
@GetMapping("/tables/{linkId}")
public R<List<TableInfoVO>> getTables(@PathVariable Long linkId) {
return R.ok(sysDatabaseLinkService.queryTables(linkId));
}
/**
*
*/
@SaCheckPermission("system:databaseLink:query")
@GetMapping("/columns/{linkId}/{tableName}")
public R<List<ColumnInfoVO>> getColumns(@PathVariable Long linkId, @PathVariable String tableName) {
return R.ok(sysDatabaseLinkService.queryColumns(linkId, tableName));
}
/**
* SQLList
*/
@SaCheckPermission("system:databaseLink:query")
@PostMapping("/querySql/{linkId}")
public R<List<LinkedHashMap<String, Object>>> querySql(@PathVariable Long linkId, @RequestBody String sql) {
return R.ok(sysDatabaseLinkService.querySql(linkId, sql));
}
}

@ -2,12 +2,16 @@ package org.dromara.system.service;
import org.dromara.system.domain.SysDatabaseLink;
import org.dromara.system.domain.vo.SysDatabaseLinkVo;
import org.dromara.system.domain.vo.TableInfoVO;
import org.dromara.system.domain.vo.ColumnInfoVO;
import org.dromara.system.domain.bo.SysDatabaseLinkBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Service
@ -66,4 +70,26 @@ public interface ISysDatabaseLinkService {
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
*
* @param linkId ID
* @return
*/
List<TableInfoVO> queryTablesAndColumns(Long linkId);
/**
*
*/
List<TableInfoVO> queryTables(Long linkId);
/**
*
*/
List<ColumnInfoVO> queryColumns(Long linkId, String tableName);
/**
* SQLList
*/
List<LinkedHashMap<String, Object>> querySql(Long linkId, String sql);
}

@ -7,7 +7,6 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.system.domain.bo.SysDatabaseLinkBo;
@ -15,10 +14,11 @@ import org.dromara.system.domain.vo.SysDatabaseLinkVo;
import org.dromara.system.domain.SysDatabaseLink;
import org.dromara.system.mapper.SysDatabaseLinkMapper;
import org.dromara.system.service.ISysDatabaseLinkService;
import org.dromara.system.domain.vo.TableInfoVO;
import org.dromara.system.domain.vo.ColumnInfoVO;
import java.sql.*;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* Service
@ -84,7 +84,7 @@ public class SysDatabaseLinkServiceImpl implements ISysDatabaseLinkService {
.eq(StringUtils.isNotBlank(bo.getJdbcUrl()), SysDatabaseLink::getJdbcUrl, bo.getJdbcUrl())
.eq(StringUtils.isNotBlank(bo.getDriverClass()), SysDatabaseLink::getDriverClass, bo.getDriverClass())
.eq(StringUtils.isNotBlank(bo.getStatus()), SysDatabaseLink::getStatus, bo.getStatus())
.orderByDesc(SysDatabaseLink::getCreateTime);
.orderByAsc(SysDatabaseLink::getCreateTime);
return lqw;
}
@ -139,4 +139,201 @@ public class SysDatabaseLinkServiceImpl implements ISysDatabaseLinkService {
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public List<TableInfoVO> queryTablesAndColumns(Long linkId) {
SysDatabaseLink link = baseMapper.selectById(linkId);
if (link == null) {
throw new RuntimeException("数据库连接信息不存在");
}
String url = link.getJdbcUrl();
String username = link.getUsername();
String password = link.getPassword();
String driverClass = link.getDriverClass();
List<TableInfoVO> tableList = new ArrayList<>();
try {
Class.forName(driverClass);
try (Connection conn = DriverManager.getConnection(url, username, password)) {
DatabaseMetaData metaData = conn.getMetaData();
// 1. 查询所有表名和注释
List<TableInfoVO> tables = new ArrayList<>();
List<String> tableNames = new ArrayList<>();
try (ResultSet rs = metaData.getTables(conn.getCatalog(), null, "%", new String[]{"TABLE"})) {
while (rs.next()) {
TableInfoVO table = new TableInfoVO();
String tableName = rs.getString("TABLE_NAME");
table.setTableName(tableName);
table.setTableComment(rs.getString("REMARKS"));
tables.add(table);
tableNames.add(tableName);
}
}
// 2. 一次性查所有字段
Map<String, List<ColumnInfoVO>> tableColumnMap = new HashMap<>();
for (String tableName : tableNames) {
tableColumnMap.put(tableName, new ArrayList<>());
}
try (ResultSet cols = metaData.getColumns(conn.getCatalog(), null, "%", "%")) {
while (cols.next()) {
String tableName = cols.getString("TABLE_NAME");
if (!tableColumnMap.containsKey(tableName)) continue;
ColumnInfoVO col = new ColumnInfoVO();
col.setColumnName(cols.getString("COLUMN_NAME"));
col.setDataType(cols.getString("TYPE_NAME"));
col.setColumnComment(cols.getString("REMARKS"));
tableColumnMap.get(tableName).add(col);
}
}
// 3. 组装
for (TableInfoVO table : tables) {
table.setColumns(tableColumnMap.getOrDefault(table.getTableName(), new ArrayList<>()));
}
tableList = tables;
}
} catch (Exception e) {
throw new RuntimeException("获取表结构失败: " + e.getMessage(), e);
}
return tableList;
}
@Override
public List<TableInfoVO> queryTables(Long linkId) {
SysDatabaseLink link = baseMapper.selectById(linkId);
if (link == null) {
throw new RuntimeException("数据库连接信息不存在");
}
String url = link.getJdbcUrl();
String username = link.getUsername();
String password = link.getPassword();
String driverClass = link.getDriverClass();
String dbType = link.getDbType() != null ? link.getDbType().toLowerCase() : driverClass.toLowerCase();
List<TableInfoVO> tableList = new ArrayList<>();
try {
Class.forName(driverClass);
try (Connection conn = DriverManager.getConnection(url, username, password)) {
String sql = null;
if (dbType.contains("mysql")) {
sql = "SELECT TABLE_NAME, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()";
} else if (dbType.contains("sqlserver")) {
sql = "SELECT t.name AS TABLE_NAME, ep.value AS TABLE_COMMENT FROM sys.tables t LEFT JOIN sys.extended_properties ep ON ep.major_id = t.object_id AND ep.minor_id = 0 AND ep.name = 'MS_Description' ORDER BY t.name";
} else if (dbType.contains("oracle")) {
sql = "SELECT t.table_name AS TABLE_NAME, c.comments AS TABLE_COMMENT FROM user_tables t LEFT JOIN user_tab_comments c ON t.table_name = c.table_name";
} else if (dbType.contains("postgresql")) {
sql = "SELECT c.relname AS TABLE_NAME, obj_description(c.oid) AS TABLE_COMMENT FROM pg_class c WHERE c.relkind = 'r' AND c.relname NOT LIKE 'pg_%' AND c.relname NOT LIKE 'sql_%'";
} else {
// fallback: JDBC元数据
DatabaseMetaData metaData = conn.getMetaData();
try (ResultSet rs = metaData.getTables(conn.getCatalog(), null, "%", new String[]{"TABLE"})) {
while (rs.next()) {
TableInfoVO table = new TableInfoVO();
table.setTableName(rs.getString("TABLE_NAME"));
table.setTableComment(rs.getString("REMARKS"));
tableList.add(table);
}
}
return tableList;
}
try (PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
TableInfoVO table = new TableInfoVO();
table.setTableName(rs.getString("TABLE_NAME"));
table.setTableComment(rs.getString("TABLE_COMMENT"));
tableList.add(table);
}
}
}
} catch (Exception e) {
throw new RuntimeException("获取表信息失败: " + e.getMessage(), e);
}
return tableList;
}
@Override
public List<ColumnInfoVO> queryColumns(Long linkId, String tableName) {
SysDatabaseLink link = baseMapper.selectById(linkId);
if (link == null) {
throw new RuntimeException("数据库连接信息不存在");
}
String url = link.getJdbcUrl();
String username = link.getUsername();
String password = link.getPassword();
String driverClass = link.getDriverClass();
String dbType = link.getDbType() != null ? link.getDbType().toLowerCase() : driverClass.toLowerCase();
List<ColumnInfoVO> columns = new ArrayList<>();
try {
Class.forName(driverClass);
try (Connection conn = DriverManager.getConnection(url, username, password)) {
String sql = null;
if (dbType.contains("mysql")) {
sql = "SELECT COLUMN_NAME, COLUMN_TYPE AS DATA_TYPE, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?";
} else if (dbType.contains("sqlserver")) {
sql = "SELECT c.name AS COLUMN_NAME, t.name AS DATA_TYPE, ep.value AS COLUMN_COMMENT FROM sys.columns c LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id LEFT JOIN sys.extended_properties ep ON ep.major_id = c.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description' WHERE c.object_id = OBJECT_ID(?)";
} else if (dbType.contains("oracle")) {
sql = "SELECT col.column_name AS COLUMN_NAME, col.data_type AS DATA_TYPE, comm.comments AS COLUMN_COMMENT FROM user_tab_columns col LEFT JOIN user_col_comments comm ON col.table_name = comm.table_name AND col.column_name = comm.column_name WHERE col.table_name = ?";
} else if (dbType.contains("postgresql")) {
sql = "SELECT a.attname AS COLUMN_NAME, format_type(a.atttypid, a.atttypmod) AS DATA_TYPE, col_description(a.attrelid, a.attnum) AS COLUMN_COMMENT FROM pg_attribute a WHERE a.attrelid = ?::regclass AND a.attnum > 0 AND NOT a.attisdropped";
} else {
// fallback: JDBC元数据
DatabaseMetaData metaData = conn.getMetaData();
try (ResultSet rs = metaData.getColumns(conn.getCatalog(), null, tableName, "%")) {
while (rs.next()) {
ColumnInfoVO col = new ColumnInfoVO();
col.setColumnName(rs.getString("COLUMN_NAME"));
col.setDataType(rs.getString("TYPE_NAME"));
col.setColumnComment(rs.getString("REMARKS"));
columns.add(col);
}
}
return columns;
}
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, tableName);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
ColumnInfoVO col = new ColumnInfoVO();
col.setColumnName(rs.getString("COLUMN_NAME"));
col.setDataType(rs.getString("DATA_TYPE"));
col.setColumnComment(rs.getString("COLUMN_COMMENT"));
columns.add(col);
}
}
}
}
} catch (Exception e) {
throw new RuntimeException("获取字段信息失败: " + e.getMessage(), e);
}
return columns;
}
@Override
public List<LinkedHashMap<String, Object>> querySql(Long linkId, String sql) {
SysDatabaseLink link = baseMapper.selectById(linkId);
if (link == null) {
throw new RuntimeException("数据库连接信息不存在");
}
String url = link.getJdbcUrl();
String username = link.getUsername();
String password = link.getPassword();
String driverClass = link.getDriverClass();
List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
try {
Class.forName(driverClass);
try (Connection conn = DriverManager.getConnection(url, username, password);
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
while (rs.next()) {
LinkedHashMap<String, Object> row = new LinkedHashMap<>();
for (int i = 1; i <= columnCount; i++) {
row.put(metaData.getColumnLabel(i), rs.getObject(i));
}
resultList.add(row);
}
}
} catch (Exception e) {
throw new RuntimeException("SQL执行失败: " + e.getMessage(), e);
}
return resultList;
}
}

Loading…
Cancel
Save