DatabaseMetaData的简单使用

DatabaseMetaData的简单使用在看大佬写的一个导出数据库建标脚本的接口的时候,发现频频用到DataBaseMetaData这个类,之前也没有用过这个类下的API,记录一下心得用法。DatabaseMetaData是java.sql包中的接口,利用它可以获取我们连接到的数据库的结构、存储等很多信息;先上个API文档:这英文看的是心力憔悴,直接来看这个接口…

大家好,又见面了,我是你们的朋友全栈君。

在看大佬写的一个导出数据库建标脚本的接口的时候,发现频频用到DataBaseMetaData这个类,之前也没有 用过这个类下的API,记录一下心得用法。

DatabaseMetaData是java.sql包中的接口,利用它可以获取我们连接到的数据库的结构、存储等很多信息;先上个API文档:
在这里插入图片描述
这英文看的是心力憔悴,直接上代码来看这个接口下面的用法:

查看数据库元数据

  @org.junit.Test
    public void getMetaData() { 
   
        
        DataSource dataSource = new DataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/mytest");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        //dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        Connection conn = null;
        ResultSet rs = null;

        try { 
   
            conn = dataSource.getConnection();
            DatabaseMetaData dbmd = conn.getMetaData();
            System.out.println("数据库已知的用户: " + dbmd.getUserName());
            System.out.println("数据库的系统函数的逗号分隔列表: " + dbmd.getSystemFunctions());
            System.out.println("数据库的时间和日期函数的逗号分隔列表: " + dbmd.getTimeDateFunctions());
            System.out.println("数据库的字符串函数的逗号分隔列表: " + dbmd.getStringFunctions());
            System.out.println("数据库供应商用于 'schema' 的首选术语: " + dbmd.getSchemaTerm());
            System.out.println("数据库URL: " + dbmd.getURL());
            System.out.println("是否允许只读:" + dbmd.isReadOnly());
            System.out.println("数据库的产品名称:" + dbmd.getDatabaseProductName());
            System.out.println("数据库的版本:" + dbmd.getDatabaseProductVersion());
            System.out.println("驱动程序的名称:" + dbmd.getDriverName());
            System.out.println("驱动程序的版本:" + dbmd.getDriverVersion());
            System.out.println("数据库中使用的表类型");
            rs = dbmd.getTableTypes();
            while (rs.next()) { 
   
                System.out.println(rs.getString("TABLE_TYPE"));
            }

        } catch (SQLException e) { 
   
            e.printStackTrace();
        } finally { 
   
            JdbcUtils.closeConnection(conn);
            JdbcUtils.closeResultSet(rs);
        }

    }

输出结果:

数据库已知的用户: root@localhost
数据库的系统函数的逗号分隔列表: DATABASE,USER,SYSTEM_USER,SESSION_USER,PASSWORD,ENCRYPT,LAST_INSERT_ID,VERSION
数据库的时间和日期函数的逗号分隔列表: DAYOFWEEK,WEEKDAY,DAYOFMONTH,DAYOFYEAR,MONTH,DAYNAME,MONTHNAME,QUARTER,WEEK,YEAR,HOUR,MINUTE,SECOND,PERIOD_ADD,PERIOD_DIFF,TO_DAYS,FROM_DAYS,DATE_FORMAT,TIME_FORMAT,CURDATE,CURRENT_DATE,CURTIME,CURRENT_TIME,NOW,SYSDATE,CURRENT_TIMESTAMP,UNIX_TIMESTAMP,FROM_UNIXTIME,SEC_TO_TIME,TIME_TO_SEC
数据库的字符串函数的逗号分隔列表: ASCII,BIN,BIT_LENGTH,CHAR,CHARACTER_LENGTH,CHAR_LENGTH,CONCAT,CONCAT_WS,CONV,ELT,EXPORT_SET,FIELD,FIND_IN_SET,HEX,INSERT,INSTR,LCASE,LEFT,LENGTH,LOAD_FILE,LOCATE,LOCATE,LOWER,LPAD,LTRIM,MAKE_SET,MATCH,MID,OCT,OCTET_LENGTH,ORD,POSITION,QUOTE,REPEAT,REPLACE,REVERSE,RIGHT,RPAD,RTRIM,SOUNDEX,SPACE,STRCMP,SUBSTRING,SUBSTRING,SUBSTRING,SUBSTRING,SUBSTRING_INDEX,TRIM,UCASE,UPPER
数据库供应商用于 'schema' 的首选术语: 
数据库URL: jdbc:mysql://localhost:3306/mytest
是否允许只读:false
数据库的产品名称:MySQL
数据库的版本:5.7.28
驱动程序的名称:MySQL-AB JDBC Driver
驱动程序的版本:mysql-connector-java-5.1.21 ( Revision: ${ 
   bzr.revision-id} )
数据库中使用的表类型
TABLE
VIEW
LOCAL TEMPORARY

查看数据库表的元数据

通过getTables可以返回一个ResultSet里面包含着这个数据表的元数据,但是我们一开始也不知道这个rs里面有哪些属性呀,我们先遍历一下看下rs里面有哪些属性,把获取数据库的一块代码挑取出来方便后续使用:

  DataSource getSource() { 
   
        DataSource dataSource = new DataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/mytest");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        //dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

上测试代码:

 @org.junit.Test
    public void getTableMetaData() { 
   

        DataSource dataSource = null;
        Connection conn = null;
        ResultSet rs = null;

        try { 
   
            dataSource = getSource();
            conn = dataSource.getConnection();
            DatabaseMetaData dbmd = conn.getMetaData();
            //catalog 类别名称;它必须与存储在数据库中的类别名称匹配;该参数为 "" 表示获取没有类别的那些描述;为 null 则表示该类别名称不应该用于缩小搜索范围
            //schemaPattern 数据库名,对于oracle来说就用户名
            //tableNamePattern 表名称模式;它必须与存储在数据库中的表名称匹配,支持模糊查询,%和_连个占位符,和在数据库中占位符意义一样
            //types 表的类型(TABLE | VIEW)
            rs = conn.getMetaData().getTables(null, null, "%", new String[] { 
    "TABLE" });
            //结果集的元数据
            ResultSetMetaData rsmd = rs.getMetaData();
            for (int i = 1 ; i <= rsmd.getColumnCount(); i++ ){ 
   
                String column = rsmd.getColumnName(i);
                System.out.println(column);
            }

        } catch (SQLException e) { 
   
            e.printStackTrace();
        } finally { 
   
            JdbcUtils.closeConnection(conn);
            JdbcUtils.closeResultSet(rs);
        }

    }

输出结果(MYSQL):

TABLE_CAT
TABLE_SCHEM
TABLE_NAME
TABLE_TYPE
REMARKS

稍微解释一下这几个是什么意思:

  • TABLE_CAT String => 表类别
  • TABLE_SCHEM String => 表模式
  • TABLE_NAME String => 表名称
  • TABLE_TYPE String => 表类型
  • REMARKS String => 表备注

然后来看看我们的表中这些元数据的属性是什么吧:

  @org.junit.Test
    public void getTableMetaData() { 
   

        DataSource dataSource = null;
        Connection conn = null;
        ResultSet rs = null;

        try { 
   
            dataSource = getSource();
            conn = dataSource.getConnection();
            DatabaseMetaData dbmd = conn.getMetaData();
            //catalog 类别名称;它必须与存储在数据库中的类别名称匹配;该参数为 "" 表示获取没有类别的那些描述;为 null 则表示该类别名称不应该用于缩小搜索范围
            //schemaPattern 数据库名,对于oracle来说就用户名
            //tableNamePattern 表名称模式;它必须与存储在数据库中的表名称匹配,支持模糊查询,%和_连个占位符,和在数据库中占位符意义一样
            //types 表的类型(TABLE | VIEW)
            rs = conn.getMetaData().getTables(null, null, "%", new String[]{ 
   "TABLE"});
            ResultSetMetaData rsmd = rs.getMetaData();
// for (int i = 1 ; i <= rsmd.getColumnCount(); i++ ){ 
   
// String column = rsmd.getColumnName(i);
// System.out.println(column);
// }
            while(rs.next()) { 
   
                System.out.println(rs.getString("TABLE_CAT"));
                System.out.println(rs.getString("TABLE_SCHEM"));
                System.out.println(rs.getString("TABLE_NAME"));
                System.out.println(rs.getString("TABLE_TYPE"));
                System.out.println(rs.getString("REMARKS"));

            }

        } catch (SQLException e) { 
   
            e.printStackTrace();
        } finally { 
   
            JdbcUtils.closeConnection(conn);
            JdbcUtils.closeResultSet(rs);
        }

    }

输出结果:

mytest
null
data_standard
TABLE

mytest
null
eao_dem_demo
TABLE

mytest
null
user_information
TABLE

mytest
null
userpo
TABLE

写这个Demo的时候遇到一个小问题,关于if(rs.next())与while(rs.next()),if(rs.next())触发一次rs移动,返回true,执行方法体;while(rs.next())触发rs移动,如果返回true,则一只循环循环体内的内容;总结:if(rs.next())是取出结果集第一个,while(rs.next())是遍历结果集。

查看数据库列的元数据

跟上面一样,先看看列都有哪些元数据属性:

@org.junit.Test
    public void getColumnMetaData() { 
   

        DataSource dataSource = null;
        Connection conn = null;
        ResultSet rs = null;

        try { 
   
            dataSource = getSource();
            conn = dataSource.getConnection();
            DatabaseMetaData dbmd = conn.getMetaData();

            // 得到全部列名
            // String catalog 类别名称;它必须与存储在数据库中的类别名称匹配;该参数为 "" 表示获取没有类别的那些描述;为 null 则表示该类别名称不应该用于缩小搜索范围
            // String schemaPattern 模式名称的模式;它必须与存储在数据库中的模式名称匹配;该参数为 "" 表示获取没有模式的那些描述;为 null 则表示该模式名称不应该用于缩小搜索范围
            // String tableNamePattern 表名称模式;它必须与存储在数据库中的表名称匹配
            // String columnNamePattern 列名称模式;它必须与存储在数据库中的列名称匹配
            // 每一行都是一个列描述
            rs = conn.getMetaData().getColumns(null, null, "%","%");
            ResultSetMetaData rsmd = rs.getMetaData();
            for (int i = 1 ; i <= rsmd.getColumnCount(); i++ ){ 
   
                String column = rsmd.getColumnName(i);
                System.out.println(column);
            }
        } catch (SQLException e) { 
   
            e.printStackTrace();
        } finally { 
   
            JdbcUtils.closeConnection(conn);
            JdbcUtils.closeResultSet(rs);
        }

    }

输出结果:

TABLE_CAT          
TABLE_SCHEM
TABLE_NAME
COLUMN_NAME
DATA_TYPE
TYPE_NAME
COLUMN_SIZE
BUFFER_LENGTH
DECIMAL_DIGITS
NUM_PREC_RADIX
NULLABLE
REMARKS
COLUMN_DEF
SQL_DATA_TYPE
SQL_DATETIME_SUB
CHAR_OCTET_LENGTH
ORDINAL_POSITION
IS_NULLABLE
SCOPE_CATALOG
SCOPE_SCHEMA
SCOPE_TABLE
SOURCE_DATA_TYPE
IS_AUTOINCREMENT

解释一下这些属性是什么意思:

  • TABLE_CAT:表类别(可能为空)
  • TABLE_SCHEM:表模式(可能为空)
  • TABLE_NAME:表名
  • COLUMN_NAME:列名
  • DATA_TYPE:对应的java.sql.Types的SQL类型(列类型ID)
  • TYPE_NAME:java.sql.Types类型名称(列类型名称)
  • COLUMN_SIZE:列大小
  • BUFFER_LENGTH:缓冲长度(有待验证)
  • DECIMAL_DIGITS:小数位数
  • NUM_PREC_RADIX:/基数(通常是10或2,有待验证)
  • NULLABLE:是否允许为null
  • REMARKS:列描述
  • COLUMN_DEF:默认值
  • SQL_DATA_TYPE:SQL数据类型(有待验证)
  • SQL_DATETIME_SUB:SQL时间间隔(有待验证)
  • CHAR_OCTET_LENGTH:对于 char 类型,该长度是列中的最大字节数
  • ORDINAL_POSITION:表中列的索引(从1开始)
  • IS_NULLABLE:是否允许为null,0为不允许为空,1为允许为空,2为不确定

然后再看看这些属性的输出结果,先看看我们的表结构:
在这里插入图片描述
这里是看每一列的元数据,这里一共有id,name,password,username四个:

  @org.junit.Test
    public void getColumnMetaData() { 
   

        DataSource dataSource = null;
        Connection conn = null;
        ResultSet rs = null;

        try { 
   
            dataSource = getSource();
            conn = dataSource.getConnection();
            DatabaseMetaData dbmd = conn.getMetaData();

            /** * 得到全部列名 * @param String catalog 类别名称;它必须与存储在数据库中的类别名称匹配;该参数为 "" 表示获取没有类别的那些描述;为 null 则表示该类别名称不应该用于缩小搜索范围 * @param String schemaPattern 模式名称的模式;它必须与存储在数据库中的模式名称匹配;该参数为 "" 表示获取没有模式的那些描述;为 null 则表示该模式名称不应该用于缩小搜索范围 * @param String tableNamePattern 表名称模式;它必须与存储在数据库中的表名称匹配 * @param String columnNamePattern 列名称模式;它必须与存储在数据库中的列名称匹配 * @return 每一行都是一个列描述 * @throws SQLException 如果发生数据库访问错误 */
            rs = conn.getMetaData().getColumns(null, null, "user_information","%");
            ResultSetMetaData rsmd = rs.getMetaData();
            while(rs.next()){ 
   
					System.out.println("TABLE_CAT is :" + rs.getString("TABLE_CAT"));
					System.out.println("TABLE_SCHEM is :" +rs.getString("TABLE_SCHEM"));
					System.out.println("TABLE_NAME is :" +rs.getString("TABLE_NAME"));
					System.out.println("COLUMN_NAME is :" +rs.getString("COLUMN_NAME"));
					System.out.println("DATA_TYPE is :" +rs.getInt("DATA_TYPE"));
					System.out.println("TYPE_NAME is :" +rs.getString("TYPE_NAME"));
					System.out.println("COLUMN_SIZE is :" +rs.getInt("COLUMN_SIZE"));
					System.out.println("BUFFER_LENGTH is :" +rs.getInt("BUFFER_LENGTH"));
					System.out.println("DECIMAL_DIGITS is :" +rs.getInt("DECIMAL_DIGITS"));
					System.out.println("NUM_PREC_RADIX is :" +rs.getInt("NUM_PREC_RADIX"));
					System.out.println("NULLABLE is :" +rs.getInt("NULLABLE"));
					System.out.println("REMARKS is :" +rs.getString("REMARKS"));
					System.out.println("COLUMN_DEF is :" +rs.getString("COLUMN_DEF"));
					System.out.println("SQL_DATA_TYPE is :" +rs.getInt("SQL_DATA_TYPE"));
					System.out.println("SQL_DATETIME_SUB is :" +rs.getInt("SQL_DATETIME_SUB"));
					System.out.println("CHAR_OCTET_LENGTH is :" +rs.getInt("CHAR_OCTET_LENGTH"));
					System.out.println("ORDINAL_POSITION is :" +rs.getInt("ORDINAL_POSITION"));
					System.out.println("IS_NULLABLE is :" +rs.getString("IS_NULLABLE"));
                    System.out.println("\n");
            }

        } catch (SQLException e) { 
   
            e.printStackTrace();
        } finally { 
   
            JdbcUtils.closeConnection(conn);
            JdbcUtils.closeResultSet(rs);
        }

    }

输出结果(一共四列):

TABLE_CAT is :mytest
TABLE_SCHEM is :null
TABLE_NAME is :user_information
COLUMN_NAME is :id
DATA_TYPE is :4
TYPE_NAME is :INT
COLUMN_SIZE is :10
BUFFER_LENGTH is :65535
DECIMAL_DIGITS is :0
NUM_PREC_RADIX is :10
NULLABLE is :0
REMARKS is :
COLUMN_DEF is :null
SQL_DATA_TYPE is :0
SQL_DATETIME_SUB is :0
CHAR_OCTET_LENGTH is :0
ORDINAL_POSITION is :1
IS_NULLABLE is :NO


TABLE_CAT is :mytest
TABLE_SCHEM is :null
TABLE_NAME is :user_information
COLUMN_NAME is :name
DATA_TYPE is :12
TYPE_NAME is :VARCHAR
COLUMN_SIZE is :20
BUFFER_LENGTH is :65535
DECIMAL_DIGITS is :0
NUM_PREC_RADIX is :10
NULLABLE is :1
REMARKS is :
COLUMN_DEF is :null
SQL_DATA_TYPE is :0
SQL_DATETIME_SUB is :0
CHAR_OCTET_LENGTH is :20
ORDINAL_POSITION is :2
IS_NULLABLE is :YES


TABLE_CAT is :mytest
TABLE_SCHEM is :null
TABLE_NAME is :user_information
COLUMN_NAME is :password
DATA_TYPE is :12
TYPE_NAME is :VARCHAR
COLUMN_SIZE is :20
BUFFER_LENGTH is :65535
DECIMAL_DIGITS is :0
NUM_PREC_RADIX is :10
NULLABLE is :1
REMARKS is :
COLUMN_DEF is :null
SQL_DATA_TYPE is :0
SQL_DATETIME_SUB is :0
CHAR_OCTET_LENGTH is :20
ORDINAL_POSITION is :3
IS_NULLABLE is :YES


TABLE_CAT is :mytest
TABLE_SCHEM is :null
TABLE_NAME is :user_information
COLUMN_NAME is :username
DATA_TYPE is :12
TYPE_NAME is :VARCHAR
COLUMN_SIZE is :255
BUFFER_LENGTH is :65535
DECIMAL_DIGITS is :0
NUM_PREC_RADIX is :10
NULLABLE is :1
REMARKS is :
COLUMN_DEF is :null
SQL_DATA_TYPE is :0
SQL_DATETIME_SUB is :0
CHAR_OCTET_LENGTH is :255
ORDINAL_POSITION is :4
IS_NULLABLE is :YES
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/150959.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ssdp java_SSDP协议 – 实施[通俗易懂]

    ssdp java_SSDP协议 – 实施[通俗易懂]我正在尝试实现SSDP协议,但我不确定它是如何工作的.SSDP通过udp发送数据,这很清楚.如果控制器连接到网络,它可以搜索具有MSEARCH消息的设备,该消息可以发送到多播地址239.255.255.250:1900.每个设备都必须收听此地址并做出响应.但我不知道他们是如何回应的.我在wireshark中看到他们用单播响应,但我不知道如何确定接收响应的端口.编辑–…

    2022年10月11日
    3
  • websocket token认证(websocket协议格式)

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mazaiting/article/details/78129542 JavaOkHttp使用本文使用eclipse编辑器,gradle依赖j…

    2022年4月17日
    75
  • 如何辨认正版mt4_真假鉴别软件

    如何辨认正版mt4_真假鉴别软件在全球零售外汇行业,外汇经纪商使用最多的还是俄罗斯迈达克公司的MT4交易平台,一些不合规的外汇经纪商也对MT4十分热衷,这使市场上几千块一个的盗版MT4日益猖獗,致使一部分交易者因此遭受一些不必要的利益侵害。那么MT4。fOrex6。cc的特点是什么?如何判别一个MT4软件是否是盗版?今天就带你们辨别真假MT4.MT4的优势1.强大的工作表现MT4强大的工作表现,这一点是毋庸置疑的。MT4自2005年7月1日推出以来,就不断的获得市场的认可。下单灵活、界面友好、交易直观等这些都是MT4平台成为外汇市场

    2022年4月19日
    71
  • 巧用ISAPI_Rewrite规则写IIS防盗链

    巧用ISAPI_Rewrite规则写IIS防盗链巧用ISAPI_Rewrite规则写IIS防盗链关键是httpd.ini的设置首先,必须要保证httpd.ini有可写权限,设置isapi_rewrite安装文件夹IIS_来宾,IIS_进程读写权限。httpd.ini默认设置如下:RewriteCondHost:(.+)RewriteCondReferer:(?!http:///1.*).*我们在它后面加上一句Rewr

    2022年7月23日
    14
  • FilterDispatcher已被标注为过时解决办法 >>> FilterDispatcher <<< is deprecated!

    FilterDispatcher已被标注为过时解决办法 >>> FilterDispatcher <<< is deprecated!一些struts2的教程都是比较早的,当我们基于较新版本的struts2来实现代码的时候,往往会出现一些问题.比如这个警告:FilterDispatcherisdeprecated!在web.xml中的配置如下:struts2org.apache.struts2.dispatcher.FilterDispatcher但

    2022年8月16日
    4
  • 哪个游戏盒子里有JAVA_关于点和盒子游戏的Java minimax

    哪个游戏盒子里有JAVA_关于点和盒子游戏的Java minimax我想建议您完全重新考虑代码.查看代码的问题(以及为什么这里没有很多响应)是很难遵循并且很难调试.例如,什么是gs.getRemainingLines,它究竟做了什么?(为什么剩下的线而不是所有合法的线?)但是,通过一些简化,可以更容易地弄清楚发生了什么并修复它.在抽象层面,minimax只是这个过程:floatminimax_max(GameStateg){if(gisterminal…

    2022年7月7日
    25

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号