数据库元数据MetaData-飞外

本篇介绍数据库方面的元数据(MetaData)的有关知识。元数据在建立框架和架构方面是特别重要的知识,再下一篇我们仿造开源数据库工具类DbUtils就要使用数据库的元数据来创建自定义JDBC框架。

在我们前面使用JDBC来处理数据库的接口主要有三个,即Connection,PreparedStatement和ResultSet这三个,而对于这三个接口,还可以获取不同类型的元数据,通过这些元数据类获得一些数据库的信息。

元数据(MetaData),即定义数据的数据。打个比方,就好像我们要想搜索一首歌(歌本身是数据),而我们可以通过歌名,作者,专辑等信息来搜索,那么这些歌名,作者,专辑等等就是这首歌的元数据。因此数据库的元数据就是一些注明数据库信息的数据。

① 由Connection对象的getMetaData()方法获取的是DatabaseMetaData对象。

② 由PreparedStatement对象的getParameterMetaData ()方法获取的是ParameterMetaData对象。

③由ResultSet对象的getMetaData()方法获取的是ResultSetMetaData对象。

下面将对这三种类型的元数据对象进行各自简单地介绍,其中示例中的数据库工具类可以参考《JDBC操作数据库的学习(2)》中定义的JdbcUtils,或者前面几篇关于连接池的如《开源数据库连接池之DBCP》或者《开源数据库连接池之C3P0》等等中定义的JdbcUtils,这里获取连接的方式对本文没有影响,只要我们能获取Connection对象即可。

一、DatabaseMetaData

DatabaseMetaData是由Connection对象通过getMetaData方法获取而来,主要封装了是对数据库本身的一些整体综合信息,例如数据库的产品名称,数据库的版本号,数据库的URL,是否支持事务等等,能获取的信息比较多,具体可以参考DatabaseMetaData的API文档。

以下有一些关于DatabaseMetaData的常用方法:

getDatabaseProductName:获取数据库的产品名称

getDatabaseProductName:获取数据库的版本号

getUserName:获取数据库的用户名

getURL:获取数据库连接的URL

getDriverName:获取数据库的驱动名称

driverVersion:获取数据库的驱动版本号

isReadOnly:查看数据库是否只允许读操作

supportsTransactions:查看数据库是否支持事务

例1:

简单地获取一些常用的数据库综合信息。

 1 public void testDatabaseMetaData() throws SQLException { 2 Connection conn = JdbcUtils.getConnection(); 3 DatabaseMetaData dbMetaData = conn.getMetaData(); 4 //获取数据库产品名称 5 String productName = dbMetaData.getDatabaseProductName(); 6 //获取数据库版本号 7 String productVersion = dbMetaData.getDatabaseProductVersion(); 8 //获取数据库用户名 9 String userName = dbMetaData.getUserName();10 //获取数据库连接URL11 String userUrl = dbMetaData.getURL();12 //获取数据库驱动13 String driverName = dbMetaData.getDriverName();14 //获取数据库驱动版本号15 String driverVersion = dbMetaData.getDriverVersion();16 //查看数据库是否允许读操作17 boolean isReadOnly = dbMetaData.isReadOnly();18 //查看数据库是否支持事务操作19 boolean supportsTransactions = dbMetaData.supportsTransactions();20 }
View Code

控制台上结果显示如下:

二、ParameterMetaData

ParameterMetaData是由PreparedStatement对象通过getParameterMetaData方法获取而来,主要是针对PreparedStatement对象和其预编译的SQL命令语句提供一些信息,比如像 insert into account(id,name,money) values(?,?,?) 这样的预编译SQL语句,ParameterMetaData能提供占位符参数的个数,获取指定位置占位符的SQL类型等等,功能也比较多,这里不列举完,详细请看有关ParameterMetaData的API文档。

以下有一些关于ParameterMetaData的常用方法:

getParameterCount:获取预编译SQL语句中占位符参数的个数

在我看来,ParameterMetaData对象能用的只有获取参数个数的getParameterCount()方法。

注意:ParameterMetaData许多方法MySQL并不友好支持,比如像获取指定参数的SQL类型的getParameterType方法,如果数据库驱动连接URL只是简单的 jdbc:mysql://localhost:3306/jdbcdemo 那么MyEclipse会抛出SQLException异常,必须要将URL修改为 jdbc:mysql://localhost:3306/jdbcdemo?generateSimpleParameterMetadata=true 才行。但是像getParameterType等等与其他的方法也没多好用,因为如下面的例子,这些方法好像只会将所有的参数认为是字符串(VARCHAR)类型。

例2:

简单地获取预编译SQL中参数的元数据信息,但发现只有获取参数个数好用:

在数据库中创建一个user表,创建的SQL脚本如下:

 create table user( id int primary key, name varchar(40), age int );

接下来对上面这个user表进行ParameterMetaData对象的演示:

 1 public void testParameterMetaData() throws SQLException { 2 Connection conn = null; 3 PreparedStatement st = null; 4 ResultSet rs = null; 5 try{ 6 conn = JdbcUtils.getConnection(); 7 String sql = "insert into user(id,name,age) values(?,?,?)"; 8 st = conn.prepareStatement(sql); 9 st.setInt(1, 1);10 st.setString(2, "Ding");11 st.setInt(3, 25);13 ParameterMetaData paramMetaData = st.getParameterMetaData();14 //获取参数个数15 int paramCount = paramMetaData.getParameterCount();16 //以字符串形式获取指定参数的SQL类型,这里有问题17 String paramTypeName = paramMetaData.getParameterTypeName(1);18 //返回指定参数的SQL类型,以java.sql.Types类的字段表示,这里有问题19 int paramType = paramMetaData.getParameterType(1);20 //返回指定参数类型的Java完全限定名称,这里有问题21 String paramClassName = paramMetaData.getParameterClassName(1);22 //返回指定参数的模,,这里有问题23 int paramMode = paramMetaData.getParameterMode(1);24 //返回指定参数的列大小,这里有问题25 int precision = paramMetaData.getPrecision(1);26 //返回指定参数的小数点右边的位数,这里有问题27 int scale = paramMetaData.getScale(1);28 }
View Code

注:完全限定名称,指的是该类型的Java完整名称,包括包名和类型。

在控制台中显示的结果如下:

因为我们的SQL语句为"insert into user(id,name,age) values(?,?,?)",而我们所有利用ParameterMetaData查询的信息除了参数个数以外,都是查询第一个参数的信息,也就是 id 列,而这个 id 列我们创建时是int整型的,但是利用ParameterMetaData的查询结果都是显示为字符串类型,因此我对ParameterMetaData的功能产生了怀疑。

因此在以后使用参数元数据ParameterMetaData尽量只要使用其getParamterCount()方法获取参数个数,对于该对象其他方法请慎用。

三、ResultSetMetaData

ResultSetMetaData是由ResultSet对象通过getMetaData方法获取而来,主要是针对由数据库执行的SQL脚本命令获取的结果集对象ResultSet中提供的一些信息,比如结果集中的列数、指定列的名称、指定列的SQL类型等等,可以说这个是对于框架来说非常重要的一个对象。关于该结果集元数据对象的其他具体功能和方法请查阅有关ResultSetMetaData的API文档。

以下有一些关于ResultSetMetaData的常用方法:

getColumnCount:获取结果集中列项目的个数

getColumnType:获取指定列的SQL类型对应于Java中Types类的字段

getColumnTypeName:获取指定列的SQL类型

getClassName:获取指定列SQL类型对应于Java中的类型(包名加类名)

例3:

简单地获取结果集对象中的元数据。

我们创建一个表,这个表和例2相同,同时我们还将在这个表中添加2条数据项:

 create table user( id int primary key, name varchar(40), age int insert into user(id,name,age) values(1,'Ding',25); insert into user(id,name,age) values(2,'LRR',24);

接下来我们要在程序中获取ResultSetMetaData并使用其方法:

 1 public void testResultSetMetaData() throws SQLException { 2 Connection conn = null; 3 PreparedStatement st = null; 4 ResultSet rs = null; 5 try{ 6 conn = JdbcUtils.getConnection(); 7 String sql = "select * from user"; 8 st = conn.prepareStatement(sql);10 rs = st.executeQuery();11 ResultSetMetaData resultMetaData = rs.getMetaData();12 //获取结果集的列数13 int columnCount = resultMetaData.getColumnCount();14 //获取指定列的名称15 String columnName = resultMetaData.getColumnName(1);16 //获取指定列的SQL类型对应于java.sql.Types类的字段17 int columnType = resultMetaData.getColumnType(1);18 //获取指定列的SQL类型19 String columnTypeName = resultMetaData.getColumnTypeName(1);20 //获取指定列SQL类型对应于Java的类型21 String className= resultMetaData.getColumnClassName(1);22 //获取指定列所在的表的名称23 String tableName = resultMetaData.getTableName(1);24 }
View Code

在控制台中显示的结果如下:

可以看到通过结果集元数据对象ResultSetMetaData的方法,取得的列数确实是3个(id,name,age),第一列确实是id项,而这个id项确实也是整型。

通过本篇我们学习了在数据库中有关数据库,预编译SQL参数和结果集的三种不同的元数据对象,元数据就是定义数据的数据,通过元数据,我们在下一篇中就可以通过这些定义信息来构建一个自定义的JDBC框架了。

参考博客:

http://luyao123127.iteye.com/blog/678765

http://huweiyi.iteye.com/blog/2123295

http://jiauwu.iteye.com/blog/1307617

http://www.cnblogs.com/xdp-gacl/p/4006830.html