`

DatabaseMetaData开发实务(上)

阅读更多

1.总论

       在企业开发实务中,数据迁移是经常会遇到的事情,此时,需要搞清楚,源数据库与目的数据库之间表以及表内部各列之间的异同。而有些时候,我们拿到的项目文档,未必能准确表述各个表的准确结构,即使应用建模工具反向导出物理结构,但依靠人工比对,也是很困难的一件事情。而此时, 如果能“反编译数据库”,提取表信息以及表内部各列的信息,然后通过程序自动进行比较,并将比较结果以报表的形式输出,那么这个问题就简单很多了。此间“反编译数据库”要解决两个问题,一个是数据库中每个用户表的名称是什么,另外一个就是对于规定的表名称,其内部结构是什么样的,比如有那些列,每列的数据类型,长度等等信息。基于上述事项,编写本文。上篇阐述Table列表的获取,中篇阐述单一表field列表的获取,下篇完成数据库之间的比较并生成比较报告。

2.数据库表结构的获取

       在JDBC技术规范中,提供了Connection,Statement,ResultSet这三个开发过程中经常用到的接口。针对与每个接口,JDBC规范提供了相应的接口描述对象,也就是xxxMetaData系列描述对象。在本文中我们将会用到DatabaseMetaData和ResultSetMetaData,他们分别描述了数据库的相关信息和结果集的相关信息。

3.遍历数据库的表

3.1DatabaseMetaData对象的获取。

当数据库连接对象(Connection)被创建完毕以后,针对该Connection会存在一个数据库的描述对象,其获取方式如下。

//获取数据库连接对象

conn=DBUtils.getConnection();

//获取描述对象

DatabaseMetaData dbmd=conn.getMetaData();

这个对象包含了conn所连接的数据库的详细信息,有了这些信息我们才好施展手脚。

3.2获取表的定义

       DatabaseMetaData提供了如下方法用来获取数据库表的定义

   //检索数据库中表的类型

   ResultSet getTables(String catalog,                       String schemaPattern,

                       String tableNamePattern,

                       String[] types

)

                    throws SQLException

3.2.1参数说明:

    对于该方法的四个参数,总是有些让人迷惑,而相关的资料介绍也并不是很详细,分析相关资料以及通过实际的程序测试,大致可以得出如下结论:

catalog – Stirng形式的类别名称,如果为null,则该参数不作为检索条件,如果为空(””)则获取不带类别的表的信息

schemaPattern – String形式的模式名称,如果为null,则该参数不作为检索条件,如果为空(””)则获取不带模式的表的信息

tableNamePattern –表名称,为null将不作为检索条件

types[] – 获取那些类型的表,每种类型以字符串的形式放入该数组中,典型的表类型一般包括"TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM"。该参数可以为null,此时不作为检索条件。一般来说我们要获取的就是表和视图的信息,因此字符传数组types的值一般写成{"TABLE","VIEW"}

结合本文要解决的事项,第三个参数,没有实际的意义,填充null,第四个参数,由于程序中只需要分析表和视图,所以值为“new String[]{"TABLE","VIEW"}”。但是对于前两个参数,针对不同的数据库,其参数值大相径庭。

下面以MySQL和Oracle为例来讲解这个两个参数。

3.2.2 catalog和schema

Oracle和MySQL数据的组织结构是完全不同,直观表象上,表和视图的挂接途径不一样,在Oracle中,采取的是分用户管理机制,表和视图挂接在某个用户下,此时用户会成为Oracle的一个”模式(schema)”;而在MySQL中表和视图是直接挂接在数据库下的。这样,在Oralce中获取catalog得到的是null,获取schema得到大写的是用户名称列表。而在MySQL中得到的catalog是数据库名称列表,而schema是null。读者可以通过DatabaseMetaData提供的如下两个方法进行测试,他们返回的都是ResultSet数据类型。

//获取类别定义

rs=dbmd.getCatalogs();

//获取模式定义

rs=dbmd.getSchemas();

基于上述分析:

如果数据库为MySQL:那么第一个参数catalog,可以是数据库的名称,当该项为null时候,为Url串中指定的数据库名称,第二个参数schema,填入null;

如果数据库为Oralce: 那么第一个参数catalog,为null,第二个参数schema,填入大写的用户名称例如”SCOTT”,如果该项目为null,那么查询范围为所有的模式用户。

3.3返回值分析

       方法getTables返回值是一个结果集(ResultSet)类型,对于该结果集中的信息,到JDK1.5预留了20多个项目用来描述表的相关信息,但是,并不是每个数据都会将这20多个项目返回的. 我们能够常用到的有如下的四个项目:

TABLE_SCHEM:对于Oracle而言,是大写的用户名称,对MySQL而言为null 。

TABLE_NAME:表的名称 。

TABLE_CAT=对Oracle而言为null,对MySQL而言是数据库名称 。

TABLE_TYPE=表的类型,依据第四个参数types数组中的某一项,用以表和视图。

   

4.程序代码:

数据库连接类:DBUtils.java

 

view plaincopy to clipboardprint?
package com.qhit.db;  
 
import java.sql.*;  
 
public class DBUtils  
{  
    private static String Driver = "com.mysql.jdbc.Driver";  
    private static String Url = "jdbc:mysql://localhost/jxgl";  
    private static String username="root";  
    private static String pwd="root1234";  
    static 
    {  
        try 
        {  
            if(true)  
            {  
                Driver = "oracle.jdbc.driver.OracleDriver";  
                Url = "jdbc:oracle:thin:@localhost:1521:qhit";    
                username="scott";  
                pwd="tiger";  
            }   
            Class.forName(Driver);  
        }  
        catch (ClassNotFoundException e)  
        {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
 
    public static Connection getConnection() throws Exception  
    {  
        return DriverManager.getConnection(Url, username, pwd);  
    }  
 
    public static void close(ResultSet rs)  
    {  
        try 
        {  
            if (rs != null)  
            {  
                rs.close();  
            }  
        }  
        catch (SQLException e)  
        {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
 
    public static void close(Statement pstm)  
    {  
        try 
        {  
            if (pstm != null)  
            {  
                pstm.close();  
            }  
        }  
        catch (SQLException e)  
        {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
 
    public static void close(Connection conn)  
    {  
        try 
        {  
            if (conn != null && !conn.isClosed())  
            {  
                conn.close();  
            }  
        }  
        catch (SQLException e)  
        {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  

package com.qhit.db;

import java.sql.*;

public class DBUtils
{
 private static String Driver = "com.mysql.jdbc.Driver";
 private static String Url = "jdbc:mysql://localhost/jxgl";
 private static String username="root";
 private static String pwd="root1234";
 static
 {
  try
  {
   if(true)
   {
    Driver = "oracle.jdbc.driver.OracleDriver";
    Url = "jdbc:oracle:thin:@localhost:1521:qhit"; 
    username="scott";
    pwd="tiger";
   }
   Class.forName(Driver);
  }
  catch (ClassNotFoundException e)
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 public static Connection getConnection() throws Exception
 {
  return DriverManager.getConnection(Url, username, pwd);
 }

 public static void close(ResultSet rs)
 {
  try
  {
   if (rs != null)
   {
    rs.close();
   }
  }
  catch (SQLException e)
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 public static void close(Statement pstm)
 {
  try
  {
   if (pstm != null)
   {
    pstm.close();
   }
  }
  catch (SQLException e)
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 public static void close(Connection conn)
 {
  try
  {
   if (conn != null && !conn.isClosed())
   {
    conn.close();
   }
  }
  catch (SQLException e)
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}


 

数据库反编译类:

view plaincopy to clipboardprint?
/** 
 *  
 * FileName:      DataBaseInfo 
 * 
 * FileType:      final Class 
 * 
 * Date:          2009年07月11日 
 * 
 * Author:        一点红 
 *  
 * Email:        
CPUCPA@163.COM 
 * 
 * Description:   反编译数据库 
 *  
 */ 
package com.qhit.services;  
 
import java.sql.Connection;  
import java.sql.DatabaseMetaData;  
import java.sql.PreparedStatement;  
import java.sql.ResultSet;  
import java.sql.ResultSetMetaData;  
import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.List;  
import java.util.Map;  
 
import com.qhit.db.DBUtils;  
 
public final class DataBaseInfo  
{  
    /** 
     * 获取数据库Table列表 
     * @throws Exception 
     */ 
    public static void tableList()throws Exception  
    {  
        Connection conn=null;  
        ResultSet rs=null;  
        try 
        {  
            conn=DBUtils.getConnection();  
            DatabaseMetaData dbmd=conn.getMetaData();  
              
            /** 
             * 获取类别 
             */ 
            //rs=dbmd.getCatalogs();  
            /** 
             * 获取模式 
             */ 
            //rs=dbmd.getSchemas();  
            /** 
             * 限定获取表的类型 
             */ 
            String types[]={"TABLE","VIEW"};  
              
            /** 
             * MySQL获取表信息 
             */ 
            //rs=dbmd.getTables("jxgl", null, null, types);           
            /** 
             * Oracle获取表信息 
             */ 
            rs=dbmd.getTables(null, "SCOTT", null, types);  
              
              
            /** 
             * 以下部分为结果集解析 
             */ 
            ResultSetMetaData rsmd=rs.getMetaData();  
            int size=rsmd.getColumnCount();  
 
            List rows=new ArrayList();  
            Map item=null;  
            while(rs.next())  
            {  
                item=new HashMap();  
                for(int i=1;i<=size;i++)  
                {  
                    item.put(rsmd.getColumnName(i), rs.getString(i));  
                }  
                rows.add(item);  
            }  
            System.out.println(rows);  
        }  
        finally 
        {  
            DBUtils.close(rs);  
            DBUtils.close(conn);  
        }  
    }  
    public static void main(String[] args)  
    {  
        try 
        {  
            tableList();  
            //tableinfo();  
        }  
        catch (Exception e)  
        {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  

 

分享到:
评论
1 楼 zhylandroid 2013-03-16  
谢谢了,对我很有帮助

相关推荐

    DatabaseMetaData生成数据库DLL

    `DatabaseMetaData` 是Java数据库连接(JDBC)API的一部分,它提供了关于数据库模式、特性以及元数据的详细信息。本篇文章将深入探讨如何利用`DatabaseMetaData`生成数据库的DLL(在关系型数据库中,DLL通常指的是...

    DatabaseMetaData 接口

    DatabaseMetaData 接口DatabaseMetaData 接口作为整体提供有关数据库的综合信息。 其中某些方法采用“字符串”自变量作为目录和模式名称。DB2 Everyplace 忽略这些自变量。 此处的某些方法以 ResultSet 对象的...

    JDBC元数据操作--DatabaseMetaData接口Demo

    DatabaseMetaData和ResultSetMetaData就是两个常用的获取数据库元数据相关信息的接口,本文只讲解DatabaseMetaData接口获取元数据的方法。 文章地址:http://blog.csdn.net/chen_zw/article/details/18816599

    java 查询oracle数据库所有表DatabaseMetaData的用法(详解)

    在Java编程中,当我们需要与Oracle数据库交互时,`java.sql.DatabaseMetaData`接口提供了一种方式来获取关于数据库的各种元数据信息。这篇文章将详细介绍如何利用`DatabaseMetaData`查询Oracle数据库的所有表。 ...

    DatabaseMetaDate接口

    DatabaseMetaData 接口作为整体提供有关数据库的综合信息。

    Laravel开发-metadata

    你可以使用`Cache::store('driver')`来选择不同的缓存驱动(如file、database或Redis),然后通过`Cache::put()`方法存储metadata,`Cache::get()`获取metadata,以及`Cache::forget()`删除metadata。 在Laravel中...

    java判断数据库表是否存在

    2. **DatabaseMetaData接口** 3. **getTables方法** 4. **ResultSet处理** ### 实现原理与步骤 #### 1. JDBC简介 JDBC是Java中用于连接和操作关系型数据库的标准API。它提供了一套标准的方法来执行SQL语句,获取...

    metadata.db

    将metadata.db文件存放在群晖上,不仅可以节省本地存储空间,还能实现多设备间的数据同步。 3. 数据安全与备份:在群晖系统中,可以设置定时备份策略,确保metadata.db的安全性。一旦发生数据丢失或错误,可以从...

    calibre-web 数据库文件metadata.db 下载

    calibre-web 数据库文件metadata.db 下载

    java获取数据库主外键

    使用`Connection`对象的方法`getMetaData()`获取`DatabaseMetaData`对象,它是用于访问数据库元数据的对象。 ```java DatabaseMetaData dbmd = connection.getMetaData(); ``` 3. **获取表列表** 使用`...

    android资料

    总的来说,理解和熟练运用`requestWindowFeature()`函数以及`DatabaseMetaData`接口是Android开发和数据库管理中的基础技能。前者能帮助你定制和优化用户界面,后者则提供了深入洞察数据库特性和能力的工具,从而更...

    怎样用JDBC查看数据库的详细信息

    总结来说,使用JDBC查看数据库的详细信息主要涉及加载驱动、建立连接、获取`DatabaseMetaData`对象并调用其方法,以及正确处理结果集和关闭资源。这对于任何需要与数据库交互的Java应用都是至关重要的。通过阅读博文...

    JdbcUtil.rar_oracle_元数据

    在Oracle中,可以使用JDBC的`DatabaseMetaData`接口来获取这些信息。下面将详细介绍如何通过Java和JDBC操作Oracle元数据。 1. **连接Oracle数据库**: 首先,你需要加载Oracle的JDBC驱动,通常是`ojdbc.jar`,并...

    Java开发案例-springboot-57-metadata-extractor读取图片信息-源代码+文档.rar

    Java开发案例-springboot-57-metadata-extractor读取图片信息-源代码+文档.rar Java开发案例-springboot-57-metadata-extractor读取图片信息-源代码+文档.rar Java开发案例-springboot-57-metadata-extractor读取...

    SalesForce - Metadata API Developer Guide.pdf

    Metadata API可以在多种开发平台上运行,包括但不限于Java、.NET、Python和PHP。这些平台提供了与Metadata API交互所需的支持,使得开发者能够在熟悉的环境中进行开发。 **标准合规性** Metadata API遵循行业标准,...

    基于Java JDBC的数据库元数据查询设计源码

    项目分为核心查询模块“database-metadata-core”和数据展示模块“database-metadata-view”,其中核心模块采用纯JDBC方式,通过java.sql.DatabaseMetaData对象获取数据库元数据信息,不依赖任何外部jar包,适用于...

    自己开发java代码生成工具

    在公司做项目,特别是业务系统的时候,大量的表单和增删改查,而且后台Ui经常用一些easyui等...jdbc DatabaseMetaData(连接数据库 读取表结构) freemarker (根据订制的模版生成 文件) 美化swing界面 substance 皮肤包

    java读取metadata元信息

    在数据库操作中,JDBC(Java Database Connectivity)提供了`DatabaseMetaData`接口,允许查询数据库的元信息,如表结构、列信息、索引、视图等。通过`Connection`对象的`getMetaData()`方法可以获得这些信息。 6....

    MetaData非托管API

    ### MetaData非托管API #### 概述 本文档详细介绍了**MetaData非托管API**,这一API主要用于在.NET环境中生成和导入元数据。该API专为编译器和加载器等底层工具设计,旨在实现对元数据的快速访问,同时减少在遍历...

    JAVA100例之实例56 数据库元数据

    JDBC提供了java.sql.Connection、java.sql.DriverManager、java.sql.DatabaseMetaData等类,用于建立数据库连接和获取元数据。 1. **建立数据库连接**: 使用`DriverManager.getConnection()`方法,提供数据库URL...

Global site tag (gtag.js) - Google Analytics