GetDbInfoKingBaseEsService.java
package cn.nordrassil.db2doc.impl;
import cn.nordrassil.db2doc.GetDbInfoService;
import cn.nordrassil.db2doc.dto.DbConnParamDTO;
import cn.nordrassil.db2doc.dto.DbInfoDTO;
import java.sql.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static cn.nordrassil.db2doc.util.CommonUtil.info;
public class GetDbInfoKingBaseEsService implements GetDbInfoService {
@Override
public List get(DbConnParamDTO dto) {
List ds = new ArrayList<>();
// 查询所有数据库
List dbs = new ArrayList<>();
Map dbNameDescriptionMap = new LinkedHashMap<>();
try (Connection connection = DriverManager.getConnection(getConnUrl(dto.getHost(), dto.getPort(), dto.getRandomDatabase()),
dto.getUsername(), dto.getPassword())) {
try (Statement statement = connection.createStatement();
ResultSet databaseResultSet = statement.executeQuery("SELECT d.datname, des.description " +
"FROM pg_database d " +
"LEFT JOIN pg_description des ON d.oid = des.objoid AND des.objsubid = 0")) {
while (databaseResultSet.next()) {
String databaseName = databaseResultSet.getString("datname");
dbs.add(databaseName);
String databaseDescription = databaseResultSet.getString("description");
dbNameDescriptionMap.put(databaseName, databaseDescription);
}
} catch (SQLException e) {
e.printStackTrace();
return ds;
}
} catch (SQLException e) {
e.printStackTrace();
return ds;
}
if (dbs.isEmpty()) {
info("未查询到数据库列表");
return ds;
}
info("查询数据库列表完成, size:{}, 数据库列表:{}", dbs.size(), dbs);
for (int i = 1; i <= dbs.size(); i++) {
String db = dbs.get(i - 1);
if (dto.getDbPrefixFilter() != null && dto.getDbPrefixFilter().length() > 0) {
if (!db.startsWith(dto.getDbPrefixFilter())) {
continue;
}
}
DbInfoDTO d = new DbInfoDTO();
d.setDbName(db);
d.setDbDescribe(dbNameDescriptionMap.get(db));
List tableInfos = new ArrayList<>();
d.setTableInfos(tableInfos);
info("查询第[{}/{}]数据库[{}]表信息", i, dbs.size(), db);
// 查询表信息
try (Connection currentDbConnection = DriverManager.getConnection(getConnUrl(dto.getHost(), dto.getPort(), db),
dto.getUsername(), dto.getPassword())) {
// 获取当前数据库的表列表
DatabaseMetaData metaData = currentDbConnection.getMetaData();
List tables = getTables(currentDbConnection);
try (ResultSet tableResultSet = metaData.getTables(null, null, null, new String[]{"TABLE"})) {
while (tableResultSet.next()) {
String tableName = tableResultSet.getString("TABLE_NAME");
if (!tables.contains(tableName)) {
continue;
}
String tableDescription = getTableDescription(currentDbConnection, tableName);
DbInfoDTO.TableInfo tableInfo = new DbInfoDTO.TableInfo();
tableInfo.setTableDescribe(tableDescription);
tableInfo.setTableName(tableName);
tableInfos.add(tableInfo);
List primaryKeyColumns = new ArrayList<>();
try (ResultSet primaryKeys = metaData.getPrimaryKeys(null, null, tableName)) {
while (primaryKeys.next()) {
primaryKeyColumns.add(primaryKeys.getString("COLUMN_NAME"));
}
} catch (Exception e) {
e.printStackTrace();
continue;
}
List tableFields = new ArrayList<>();
tableInfo.setTableFields(tableFields);
// 获取当前表的字段信息
try (ResultSet columnResultSet = metaData.getColumns(null, null, tableName, null)) {
while (columnResultSet.next()) {
String columnName = columnResultSet.getString("COLUMN_NAME");
String columnType = columnResultSet.getString("TYPE_NAME");
int columnSize = columnResultSet.getInt("COLUMN_SIZE");
int nullable = columnResultSet.getInt("NULLABLE");
String isNullable = nullable == DatabaseMetaData.columnNullable ? "是" : "否";
String columnDefault = columnResultSet.getString("COLUMN_DEF");
String columnComment = getColumnComment(currentDbConnection, tableName, columnName);
String isPrimaryKey = primaryKeyColumns.contains(columnName) ? "是" : "否";
/*System.out.println(" 字段名: " + columnName +
", 字段类型: " + columnType +
", 长度: " + columnSize +
", 是否非空: " + isNullable +
", 默认值: " + columnDefault +
", 是否主键: " + isPrimaryKey +
", 注释: " + columnComment);*/
tableFields.add(new DbInfoDTO.TableField(
columnName,
columnType,
columnSize,
isNullable,
isPrimaryKey,
columnDefault,
columnComment
));
}
} catch (Exception e) {
e.printStackTrace();
}
// 测试
if (dto.getTestRun()) {
if (tableInfos.size() > 2) {
break;
}
}
}
}
} catch (Exception e) {
continue;
}
ds.add(d);
// 测试
if (dto.getTestRun()) {
break;
}
}
info("获取数据库信息完成, size:{}", ds.size());
return ds;
}
private static String getConnUrl(String host, Integer port, String db) {
return "jdbc:kingbase8://" + host + ":" + port + "/" + db + "?compatibleMode=pg&allowMultiQueries=true&characterEncoding=UTF-8&ssl=false";
}
private static String getTableDescription(Connection connection, String tableName) throws SQLException {
String sql = "SELECT des.description " +
"FROM pg_class c " +
"LEFT JOIN pg_description des ON c.oid = des.objoid AND des.objsubid = 0 " +
"JOIN pg_namespace n ON n.oid = c.relnamespace " +
"WHERE c.relname =? AND c.relkind = 'r'";
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
preparedStatement.setString(1, tableName);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
return resultSet.getString("description");
}
}
}
return null;
}
private static List getTables(Connection connection) throws SQLException {
String sql = "SELECT \n" +
" pgc.relname AS table_name,\n" +
" pgd.description AS table_description\n" +
"FROM \n" +
" pg_class pgc\n" +
"LEFT JOIN \n" +
" pg_description pgd ON (pgc.oid = pgd.objoid AND pgd.objsubid = 0)\n" +
"JOIN \n" +
" pg_namespace pgn ON pgn.oid = pgc.relnamespace\n" +
"WHERE \n" +
" pgc.relkind = 'r' -- 'r'代表普通表\n" +
"AND \n" +
" pgn.nspname = 'public';";
List results = new ArrayList<>();
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
try (ResultSet resultSet = preparedStatement.executeQuery()) {
while (resultSet.next()) {
results.add(resultSet.getString("table_name"));
}
}
}
return results;
}
private static String getColumnComment(Connection connection, String tableName, String columnName) throws SQLException {
String sql = "SELECT col_description(c.oid, a.attnum) AS comment " +
"FROM pg_class c " +
"JOIN pg_attribute a ON a.attrelid = c.oid " +
"JOIN pg_namespace n ON n.oid = c.relnamespace " +
"WHERE c.relname =? AND a.attname =? AND a.attnum > 0";
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
preparedStatement.setString(1, tableName);
preparedStatement.setString(2, columnName);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
return resultSet.getString("comment");
}
}
}
return "";
}
}
maven依赖
com.kingbase8
kingbase8
8.6.0
创建表SQL
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
student_name VARCHAR(100) NOT NULL,
gender CHAR(1) NOT NULL,
birth_date DATE NOT NULL,
class_id INT,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
modify_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE students IS '存储学生的基本信息';
COMMENT ON COLUMN students.student_id IS '学生的唯一标识,自增主键';
COMMENT ON COLUMN students.student_name IS '学生的姓名';
COMMENT ON COLUMN students.gender IS '学生的性别,M 表示男性,F 表示女性';
COMMENT ON COLUMN students.birth_date IS '学生的出生日期';
COMMENT ON COLUMN students.class_id IS '学生所在班级的标识,关联 classes 表的 class_id';
COMMENT ON COLUMN students.create_time IS '记录创建的时间';
COMMENT ON COLUMN students.modify_time IS '记录修改的时间';
-- 创建班级表
CREATE TABLE classes (
class_id SERIAL PRIMARY KEY,
class_name VARCHAR(100) NOT NULL,
teacher_id INT,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
modify_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE classes IS '存储班级的相关信息';
COMMENT ON COLUMN classes.class_id IS '班级的唯一标识,自增主键';
COMMENT ON COLUMN classes.class_name IS '班级的名称';
COMMENT ON COLUMN classes.teacher_id IS '班级的授课教师标识,关联 teachers 表的 teacher_id';
COMMENT ON COLUMN classes.create_time IS '记录创建的时间';
COMMENT ON COLUMN classes.modify_time IS '记录修改的时间';
-- 创建教师表
CREATE TABLE teachers (
teacher_id SERIAL PRIMARY KEY,
teacher_name VARCHAR(100) NOT NULL,
subject VARCHAR(50) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
modify_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE teachers IS '存储教师的基本信息';
COMMENT ON COLUMN teachers.teacher_id IS '教师的唯一标识,自增主键';
COMMENT ON COLUMN teachers.teacher_name IS '教师的姓名';
COMMENT ON COLUMN teachers.subject IS '教师所教授的学科';
COMMENT ON COLUMN teachers.create_time IS '记录创建的时间';
COMMENT ON COLUMN teachers.modify_time IS '记录修改的时间';
-- 创建课程表
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
course_name VARCHAR(100) NOT NULL,
teacher_id INT,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
modify_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE courses IS '存储课程的相关信息';
COMMENT ON COLUMN courses.course_id IS '课程的唯一标识,自增主键';
COMMENT ON COLUMN courses.course_name IS '课程的名称';
COMMENT ON COLUMN courses.teacher_id IS '教授该课程的教师标识,关联 teachers 表的 teacher_id';
COMMENT ON COLUMN courses.create_time IS '记录创建的时间';
COMMENT ON COLUMN courses.modify_time IS '记录修改的时间';
-- 创建成绩表
CREATE TABLE scores (
score_id SERIAL PRIMARY KEY,
student_id INT NOT NULL,
course_id INT NOT NULL,
score NUMERIC(5, 2) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
modify_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE scores IS '存储学生的课程成绩信息';
COMMENT ON COLUMN scores.score_id IS '成绩记录的唯一标识,自增主键';
COMMENT ON COLUMN scores.student_id IS '学生的标识,关联 students 表的 student_id';
COMMENT ON COLUMN scores.course_id IS '课程的标识,关联 courses 表的 course_id';
COMMENT ON COLUMN scores.score IS '学生该课程的成绩';
COMMENT ON COLUMN scores.create_time IS '记录创建的时间';
COMMENT ON COLUMN scores.modify_time IS '记录修改的时间';