Java查询数据库表信息导出Word-获取数据库实现[1]:KingbaseES

GetDbInfoKingBaseEsService.java

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<DbInfoDTO> get(DbConnParamDTO dto) {
        List<DbInfoDTO> ds = new ArrayList<>();
        // 查询所有数据库
        List<String> dbs = new ArrayList<>();
        Map<String, String> 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<DbInfoDTO.TableInfo> 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<String> 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<String> 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<DbInfoDTO.TableField> 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<String> 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<String> 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依赖

java 复制代码
        <dependency>
            <groupId>com.kingbase8</groupId>
            <artifactId>kingbase8</artifactId>
            <version>8.6.0</version>
        </dependency>

创建表SQL

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 '记录修改的时间';
相关推荐
爱编程的小新☆2 分钟前
【MySQL】数据类型和表的操作
java·数据库·mysql
喝养乐多长不高8 分钟前
详细PostMan的安装和基本使用方法
java·服务器·前端·网络协议·测试工具·https·postman
Kiri霧27 分钟前
JavaEE-多线程实战01
java·开发语言·java-ee
爱的叹息34 分钟前
《企业级 Java EE 架构设计精深实践》内容详解
java·java-ee
缘来的精彩36 分钟前
Android ARouter的详细使用指南
android·java·arouter
Seven9744 分钟前
为什么不能用浮点型表示金额?
java
冼紫菜1 小时前
[特殊字符]实战:使用 Canal + MQ + ES + Redis + XXL-Job 打造高性能地理抢单系统
java·redis·分布式·后端·elasticsearch·rabbitmq·全文检索
pjx9871 小时前
给应用加速:Spring Boot集成缓存 (Caffeine & Redis) 实战
java·spring boot·redis·spring·缓存
Kiri霧1 小时前
JavaEE-多线程实战02
java·开发语言·java-ee
工业互联网专业1 小时前
基于springboot+vue的摄影师分享交流社区的设计与实现
java·vue.js·spring boot·毕业设计·源码·课程设计·摄影师分享交流社区