@ -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 ( ) )
. orderBy De sc( SysDatabaseLink : : getCreateTime ) ;
. orderBy A sc( 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 ;
}
}