# database-metadata **Repository Path**: jjfinal/database-metadata ## Basic Information - **Project Name**: database-metadata - **Description**: 本项目用于数据的元数据查询,简单的说,就是对数据库的字段和表结构进行查询,当前项目分为2个模块 - database-metadata-core 核心查询模块 - database-metadata-view 数据展示模块 核心模块不依赖任何jar文件,采用原始的jdbc方式进行的查询,项目代码主要的核心思想就是通过 java.sql下的 DatabaseMetaData对象来获取对应的元数据。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 4 - **Created**: 2026-02-10 - **Last Updated**: 2026-02-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 数据库元数据查询 ## 概述 ### 简介 公司的系统中很多经常要和数据库打交道,比如获取数据库表结构、数据库字段信息,做的多了,就希望将这一块给整合起来做成一个jar包的形式,这样就有了这个项目。 本项目用于数据的元数据查询,简单的说,就是对数据库的字段和表结构进行查询,当前项目分为2个模块 - `database-metadata-core` 核心查询模块 - `database-metadata-view` 数据展示模块 核心模块不依赖任何jar文件,采用原始的jdbc方式进行的查询,减少依赖冲突,方便随时的引用。项目主要的核心思想就是通过 java.sql 下的 `DatabaseMetaData` 对象来获取对应的元数据。view 模块依赖 core 模块,所以,如果引用了`database-metadata-view`模块就没必要再次引入`database-metadata-core` 模块了。 项目中参考了 **screw** 项目,地址:https://gitee.com/leshalv/screw 还有 **DBMetadata** 项目,地址:https://gitee.com/free/DBMetadata 当初看 screw 的时候,感觉依赖太多,对数据源的支持也不太好,不太适合直接嵌入到系统中,而看到 DBMetadata 的时候,这个项目感觉是非常适合我的需求,但这代码写的太复杂了,而且也不太适合嵌入到自己的项目中,就将项目改造了下。 ### 效果预览 #### html ![image-20220725004304771](README.assets/image-20220725004304771.png) ![image-20220725004313747](README.assets/image-20220725004313747.png) #### md文档 ![image-20220725004351556](README.assets/image-20220725004351556.png) ![image-20220725004402835](README.assets/image-20220725004402835.png) #### doc文档生成 ![image-20220725004453024](README.assets/image-20220725004453024.png)![image-20220725004501341](README.assets/image-20220725004501341.png) ### 特性 - 核心模块不依赖其他模块,最少依赖 - 查询表和字段的同时,还可以支持映射为对应的java结构,方便后期java 的扩展,与java能更好的融合。 - 支持扩展,可以非常方便的对多种数据库进行元数据查询支持 - 支持多种数据库(目前) - Oracle - MySQL - MariaDB - SQLite - Hsqldb - postgreSQL - DB2 - sqlserver(2005+) - 必须使用jtds驱动 - 支持在获取数据库库表和字段信息的时候进行接口扩展,方便在事前、事中、事后的处理 - 支持查询表的时候进行过滤 ## 打包 发布到中央仓库需要服务器和域名,所以这一块的打包需要自己来做,也建议自己来做。 这样方便二次开发,对于不支持的数据库完全可以自定义相关的代码逻辑,发布到自己的环境也更加安全。 ### 上传 配置好公司或者个人的的maven配置文件 `setting.xml` ,即可完成上传代码 ![image-20220506152226112](README.assets/image-20220506152226112.png) 查询 ![image-20220506152238030](README.assets/image-20220506152238030.png) 如果公司没有maven私服也很简单,直接打包jar引入即可,但这种情况下,建议你使用阿里的云效私有仓库,也可以非常方便的使用maven,步骤没有什么区别。 ## 模块 ### database-metadata-core #### 设计思路 项目最终的结果都保存在 TableModel 中,字段信息也包含其中。 整个项目使用上只需要关注 MetadataQueryHandle 即可,其中的核心方法为 `coreHandle` ,在查询之前,代码会先在元数据中进行一次查询 `getColumns(simpleDataSource, metadataConfig)`,然后在补充详细的信息。 设计思路就是利用 `DatabaseMetaData` 进行最基础的元数据查询,这个 java.sql 自带的接口帮我们实现了大部分的功能,对于通过该接口获取数据不完整的,再通过实现ColumnModelService 接口进行扩展补充。 #### 扩展 所有的扩展都需要继承 ColumnModelService 接口,用于扩展查询字段信息,大部分情况下,我们应该优先考虑使用默认的查询方式先进行测试,元数据获取的方式可以适用于大部分情况,新增数据库的支持并不一定需要编写新的实现。 编写完实现之后,在 `selectImpl(SimpleDataSource simpleDataSource)` 方法中选择实现方式。 #### 快速开始 所有的测试用例都写在 `BaseTest` 测试类中。可以参考该测试类。 需要先配置公司的maven仓库,下载对应依赖。 ``` com.sprouting database-metadata-core 0.0.1-SNAPSHOT ``` 1、 获取数据库基础信息 ```java /** * 获取数据库基础信息 * @throws SQLException */ public void getDatabaseInfoBase() throws SQLException { OracleDataSource ods = new OracleDataSource(); ods.setDriverType ("thin"); ods.setNetworkProtocol("tcp"); ods.setServerName ("127.0.0.1"); // Oracle SID ods.setDatabaseName("orcl"); ods.setPortNumber(1521); ods.setUser("root"); ods.setPassword("root"); ods.setConnectionCachingEnabled(false); SimpleDataSource simpleDataSource = new SimpleDataSource(DatabaseEnum.ORACLE, ods); // 非必要,按需配置 MetadataConfig metadataConfig = new MetadataConfig(); metadataConfig.setSchemaPattern("root"); MetadataQueryHandle metadataQueryHandle = new MetadataQueryHandle(); List tableModels = metadataQueryHandle.coreHandle(simpleDataSource, metadataConfig); for (TableModel table : tableModels){ System.out.println("查询出的表:" + table.getTableName() + "字段:" + table.getColumnModelList().size()); } } ``` 在使用的时候建议最好直接传入已构建的 dataSource。 2、普通的mysql测试 ```java /** * mysql 测试用例 * @throws SQLException */ public void mysqlTest() throws SQLException { SimpleDataSource simpleDataSource = new SimpleDataSource(DatabaseEnum.MYSQL5, "jdbc:mysql://127.0.0.1:3306/user-info", "root", "root" ); // 非必要,按需配置 MetadataConfig metadataConfig = new MetadataConfig(); MetadataQueryHandle metadataQueryHandle = new MetadataQueryHandle(); List tableModels = metadataQueryHandle.coreHandle(simpleDataSource, metadataConfig); for (TableModel table : tableModels){ System.out.println("查询出的表:" + table.getTableName() + "字段:" + table.getColumnModelList().size()); } } ``` #### 后期扩展临时记录 由于没有相应数据库,暂时无法验证,故而先将部分数据源查询的语句进行记录,方便后期扩展 ##### cacheDB 查询全部表和列信息 ```sql select TABLE_NAME as 表名, COLUMN_NAME 字段名, DESCRIPTION 注释, CHARACTER_MAXIMUM_LENGTH from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'Schema信息' ``` 主键信息 ```sql select TABLE_CATALOG ,TABLE_NAME ,TABLE_SCHEMA ,COLUMN_NAME ,ORDINAL_POSITION from INFORMATION_SCHEMA.COLUMNS where PRIMARY_KEY='YES' and TABLE_SCHEMA='Schema信息' ``` ##### 达梦 查询表 ```sql select ut.table_name TABLE_NAME, utc.comments COMMENTS from user_tables ut left join USER_TAB_COMMENTS utc on ut.table_name=utc.table_name ``` 查询字段 ```sql select ut.table_name TABLE_NAME , uc.column_name COLUMN_NAME , case uc.data_type when 'CLOB' then uc.data_type when 'BLOB' then uc.data_type else concat(concat(concat(uc.data_type, '('), uc.data_length), ')') end case AS COLUMN_TYPE , uc.data_length COLUMN_LENGTH , uc.DATA_PRECISION DATA_PRECISION,uc.DATA_SCALE DECIMAL_DIGITS, case uc.NULLABLE when 'Y' then '1' else '0' end case NULLABLE, uc.DATA_DEFAULT COLUMN_DEF, ucc.comments REMARKS from user_tables ut left join USER_TAB_COMMENTS utc on ut.table_name=utc.table_name left join user_tab_columns uc on ut.table_name=uc.table_name left join user_col_comments ucc on uc.table_name = ucc.table_name and uc.column_name=ucc.column_name where 1=1 ``` 查询主键 ```sql SELECT C.OWNER AS TABLE_SCHEM, C.TABLE_NAME, C.COLUMN_NAME , C.POSITION AS KEY_SEQ , C.CONSTRAINT_NAME AS PK_NAME FROM ALL_CONS_COLUMNS C, ALL_CONSTRAINTS K WHERE K.CONSTRAINT_TYPE = 'P' AND K.OWNER = '%s' AND K.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND K.TABLE_NAME = C.TABLE_NAME AND K.OWNER = C.OWNER ``` ### database-metadata-view #### 设计思路 元数据展示这一块,核心思想就是通过 freemarker 模板生成相应的文件。项目的核心方法就是 DocumentGenerationProcess 类的 coreHandle 方法,所有的文档生成实现都要实现 DocumentGenerationInterface 接口,这里面有一个默认的文档生成实现,现在的几种文档生成都使用的它的默认方法,根据情况覆盖默认实现 #### 特性 - 依赖少,项目只依赖 database-metadata-core 模块和 freemarker 模板,这也意味着,==如果你需要使用 database-metadata-view ,那么就没必要再引入 database-metadata-core 的依赖。== - 支持多种格式生成 - Markdown - html 展示最为良好 - word 数据表多的时候生成会比较大 #### 快速开始 需要先配置公司的maven仓库,下载对应依赖。 ``` com.sprouting database-metadata-view 0.0.1-SNAPSHOT ``` 开始之前,建议看下对应的测试类中的例子。 ```java /** * mysql 测试用例 - html生成 * @throws SQLException */ public void mysqlTest() throws Exception { SimpleDataSource simpleDataSource = new SimpleDataSource(DatabaseEnum.MYSQL5, "jdbc:mysql://127.0.0.1:3306/user-info?useInformationSchema=true", "root", "root" ); // 非必要,按需配置 MetadataConfig metadataConfig = new MetadataConfig(); metadataConfig.setTableNamePattern("%user-info%"); MetadataQueryHandle metadataQueryHandle = new MetadataQueryHandle(); List tableModels = metadataQueryHandle.coreHandle(simpleDataSource, metadataConfig); for (TableModel table : tableModels){ System.out.println("查询出的表:" + table.getTableName() + "字段:" + table.getColumnModelList().size()); } ViewConfig viewConfig = new ViewConfig(); // viewConfig.setDocumentTypeEnum(DocumentTypeEnum.WORD); // viewConfig.setDocumentTypeEnum(DocumentTypeEnum.HTML); viewConfig.setDocumentTypeEnum(DocumentTypeEnum.MD); DocumentGenerationProcess documentGenerationProcess = new DocumentGenerationProcess(); File file = documentGenerationProcess.coreHandle(viewConfig, tableModels); System.out.println(file.getPath()); } ``` 同样的,dataSource 可以自定义也可以传入进去,获得表结构后,在传入调用 DocumentGenerationProcess 的coreHandle 方法,我们还可以在 ViewConfig 中配置一些生成的参数,让生成更符合你的需要 ## 常见问题 ### 数据库乱码 这一般和数据库的编码有关系,如果是MySQL的话,尝试在连接在添加 `?characterEncoding=UTF-8` ### MySQL生成后没有注释 在数据连接url中添加了两个参数`characterEncoding=utf8`和`useInformationSchema=true`