日常工作中我们可能会遇到一些配置化的功能,比如我们需要根据元数据项动态生成一些模板,比如表格,excel等,这些都需要我获取到数据库表中字段长度、类型、格式等信息。下面就以一个小白的身份和大家分享下自己的实现过程。

背景

​ 项目为spring boot 微服务项目,数据库信息在yml文件中配置,实现方式采用JDBC中的DatabaseMetaData的方式。

介绍

​ 在我们一开始学习JAVA的时候,第一次连接数据库的时候都是JDBC的方式进行连接,具体代码我就不写了,现在也同样采用Connection的方式,代码如下:

@RestController
public class DataMetaController {

    @Autowired
    private DataSourceProperties dataSourceProperties;

    @GetMapping("test")
    public  void  getColumns() throws SQLException, ClassNotFoundException {
        
        Connection conn = DriverManager.getConnection(dataSourceProperties.getUrl(),dataSourceProperties.getUsername(),dataSourceProperties.getPassword());
        
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet rs = metaData.getColumns(conn.getCatalog(), dataSourceProperties.getUsername(), "表名","%");
        
        while(rs.next()) {
            System.out.println("COLUMN_NAME :"+rs.getString("COLUMN_NAME"));
        }
    }
}

在使用的时候建议都用大写,屏蔽mysql和Oracle直接的差异

对于以上代码,我解释一下我在写下代码之前不太了解的几个点:

1.关于DriverManager为何不用执行Class.forName了,百度学习了下 https://www.cnblogs.com/w-wfy/p/6180865.html,总结就是在jdbc4中,调用getConnection的时候DriverManager会自动去加载合适的驱动。

2.一般网上的参考样例告诉我们调用getConnection时直接在程序中写驱动连接的信息,但有些时候我们的配置文件都是加密的,那我要是明文写在了程序里,就失去了价值,所以我用到了DataSourceProperties这个类读取我们的配置信息,

在这里插入图片描述

3.当我们使用 Connection 中getMetaData获取元数据信息时,在调用getColumns方法时,为什么有人写的是%,我跟踪了下代码发现如下代码,
在这里插入图片描述

也就是说,我们没有具体指定具体查询某一个字段时,默认全量查询,有兴趣的可以看下具体实现的逻辑,(oracle.jdbc.driver包下的getColumns方法,本人就大概从头到尾瞟了下),核心sql语句如下:

SELECT a.*
FROM
    all_tab_columns a
WHERE
    OWNER = '用户名' and TABLE_NAME = '表名'

最后详细说下getColumns方法

方法参数:

参数说明
catalog(数据库名称)直接使用Connection的实例对象中的getCatalog()方法返回值填充就好
schemaPattern(模式)Oracle中登陆名必须是大写,不然的话是无法获取到相应的数据,也可以使用DataSourceProperties中getUsername()直接填充
tableNamePattern(表名)要查找的表名
columnNamePattern(列名)填写要查找的列名,填写具体名称,获取填写 null 或 % ,默认全查

返回值(只看了几个常用的,其他可以参考网上资料):

名称类型说明
TABLE_NAMEString表名
COLUMN_NAMEString列名
DATA_TYPEint类型码值,对应 java.sql.Types 的 SQL 类型
TYPE_NAMEString类型名称,例如Oracle:VARCHAR2,NUMBER等
COLUMN_SIZEString列的大小
DECIMAL_DIGITSint小数部分位数,不适用的类型会返回null
NULLABLEint是否允许使用null
REMARKSString建表时的注释信息,Oracle中comment的信息
COLUMN_DEFString默认值
IS_AUTOINCREMENTString是否自增
ORDINAL_POSITIONint表中的列的索引(从 1 开始)

备注:

​ 此次自己只在Oracle11 进行了测试,MySQL是在之前项目中使用过,目前未发现什么问题,如有些的错误的地方还请大佬们指出

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐