Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->系统管理 ->正文

建立独立于数据类型的JDBC应用

来源:Linux-cn.com 作者:Webmaster 时间:2007-05-05 点击: [收藏] [投稿]

  概述

  数据库程序设计通常需要从大量的外部数据源中获取数据进行处理。这这篇文章中,作者提出了在数据库中使用DatabaseMetaData——JDBC源数据接口——和执行预编译的SQL实现将纯文本数据转换成实际的数据类型的技术。它提供了一种在运行时动态发现数据库的具体数据类型和翻译外部文本数据的方法。

  正文

  假设您需要写一个将文本文件中的数据转换成数据库的表并进行存储的数据库应用程序,例如这个表包含的是航班信息,包括票号、购买日期、出发日期、离港/到港位置以及票价等在数据库中,每一段信息都有一一个指定的数据类型与之相对应。例如数值型、文本型、日期型或者货币型等等。

  程序必须从文本文件中读出几段这样的票务信息,将这些信息转换成合适的数据类型并创建一个相应的表以存储这些转换过的数据。为了实现这种转换,程序需要知道每段数据在数据库中对应的数据类型。简单的方法是在程序中通过硬编码进行类型的转换——将数据类型作为编程时就预先知道的静态信息。

  通过采用这种简单的方式,您必须要在另外一个程序中用类似的代码来实现同一个数据库中另外一个表(如具有客户信息的custumer表)的数据生成工作,尽管您可以重复使用以前的许多程序代码,但您必须重新设计所有的数据库数据类型转换的代码。

  如果您需要生成的表非常多时,您就会非常厌倦并且也很浪费精力了。但这也仅仅是只有一个数据库的情况。如果将数据迁移到其它的数据库系统,您必须重写所有的代码以实现不同数据库数据类型的对应。在不同的数据库间实现数据类型的对应和转换在数据库编程中一直是一个非常讨厌的事。

  创建可重用的代码

  怎样避免这些重复的工作呢?您写代码时可以将数据库名、表名和列名看成参数。问题是是不是有办法对数据类型也可以进行类似的处理,这样您就可以写一个类或者一个类集完成任何数据库间任何数据类型的对应和表的生成?答案是在运行之前不要确定数据类型,在运行时根据java.sql 包中的DatabaseMetaData接口来实现它,通过在这个接口中写入代码,您可以避免对数据类型进行硬编码,这样就可以写通用的可重用代码了。

  DatabaseMetaData接口为数据库提供了元数据(metadata)信息。Metadata是描述数据的数据。例如,航班数据库表包含票务信息,它是数据。在这种情况下,元数据会包含诸如表中有多少列、每个列的数据类型、是不是一个列可以为空等等信息。这就是关于数据的数据本篇关注的焦点是每个列的数据类型。

  在后面的讨论中,我会向您介绍一种以层次方式进行组织的三个java类构成的可重用库。每层都对下层进行了封装,最下层离数据库最近。相应地,最上层离离应用程序最近了。虽然这些库是为灌入数据库的表而设计的,但只要您在代码上进行小规模的改动,您就可以建立自己的数据类型独立的数据库查询和更新。

  沿用下面的情况

  假设你需要在一个organization数据库中灌入一个称为emp的表,这里是一个在第一行包含表,然后第二行是一系列的列名,随后的是每行都是相应的列对应的数据的样板数据文件:


 emp
 hiredate sal ename empno 
  1996-09-01 1250.00 jackson 7123 
  1980-01-01 2500.50 walsh 7124 
  1985-01-01 12345.67 gates 7125 

  所有的输入是纯ASCII文本,但这些数据会转换成如下的数据库特定数据类型:


  字段 数据库类型 
  -------- ------------- 
  hiredate date 
  sal decimal 
  ename ASCII text 
  empno number 

  emp表的数据结构如下图的顶行所示:

  从输入列到数据库表列的映射

  不是表中所有的列都需要立刻灌入,在这个例子中,仅仅灌入标记为true的列,需要灌入的列有empno、ename、 hiredate和sal。

  在数据文件中的列的顺序也不需要一定与数据库中列的顺序一致。一个索引数组维护了文件中的列到数据库中的列的对应。在这个例子中,活动列(标记为true的)的顺序数组就是索引数组。如果I是输入文件中一个列的位置(hiredate:0、sal:1等等),那么activeColumnOrder[i]是这些列在表中的相应位置。(activeColumn[0]是5,意思是说hiredate是emp表中的第五列)。

  建立库类层次

  我们的库中包含三个层次:

  一个TableColumns类,它距离数据库最近,它负责发现和管理数据库表列的信息。

  一个TableMediator类,它用来准备使用TableColumns所管理的数据库表信息对表进行灌入。

  一个TableBuilder类,它离数据库最远,当然离应用程序最近。它负责从输入的数据文件中读取数据然后使用TableMediator类将数据灌入指定的表。

  下图说明这种层次关系:

  应用分层

  这些类都收集在称为tablebuild的包中。

  这些Java源程序可以在这里(http://www.javaworld.com/javatips/javatip82/tablebuild.zip)

  第一层:TableColumns类

  TableColumns类负责通过查询给定数据库的元数据实例发现数据库表的给定列信息。它将列信息存储在两个并列的数组中:一个称为columnNames的字符串数组,一个称为columnTypeCodes的短整型数组。

  一个给定表的所有列的类型可以通过DatabaseMetaData的getColumns方法获得:



 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:使用CachedRowSet实现数据库的断接   下一篇:JDBC 概述(1)

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章

    public abstract ResultSet getColumns(String catalog,
                                  String schemaPattern,
                                  String tableNamePattern,
                                  String columnNamePattern)
        throws SQLException