熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

一個簡單實用的數據庫操作框架

2013-11-23 19:02:40  來源: Java核心技術 

  前言
  這個小小的數據庫操作封裝框架是參考IBM開發網上的兩篇文章並在其基礎上擴充了一些功能而得到的所以首先要感謝兩篇文章的作者
  學習JDBC以來一直想實現一個簡單的封裝來方便編程但是由於水平有限一直沒有較好的辦法看了IBM開發網上的兩篇文章以後感覺作者的設計思想很好一定能擴充成一個實用的JDBC封裝所以我在文章提供的源碼基礎上加了一些功能這些功能包括支持多種數據類型處理了空值利用反射方便的在Row對象和值對象之間進行轉換還有加了一個我自認為通用的DAO類來方便用戶的操作
  我把源碼提供出來有兩個目的一個是希望能幫助比我還初學的初學者熟悉JDBC另外就是請各位高手不吝賜教改進程序中的錯誤如果能將你們的對JDBC的封裝方法提供出來那就更好了(不要說你們只用EJB或者HibernateJDO什麼的?)
  IBM開發網的那兩篇文章分別是《一個簡單的 JDBC 包裝器》《對一個簡單的 JDBC 包裝器的擴展及應用》我的郵箱是xcn有事請與我聯系
  設計思想
  把DBMS抽象成類Database這個類負責管理數據庫連接以及提供表對象
  把數據庫中的一張或多張表抽象成類Table這個類中提供對表的添加修改刪除的JDBC封裝
  將數據庫表中的一條記錄抽象成類Row這個類用HashMap保存關系數據庫中表格中一行數據的字段名和值並提供一些相關操作另外這個類還提供了兩個靜態方法用於在Row對象和ValueObject之間進行方便的轉換
  把對個Row的集合抽象成RowSet這個類中用一個vector把多個Row對象保存起來並提供一些相關操作
  代碼分析
  由於已經給出源碼所以我只對代碼中關鍵的和需要注意的地方加以說明大家可以執行源碼一邊演示一邊體會
  Database類源碼如下
  package comgdrjutildatabase;
  import javasql*;
  import javaxsql*;
  import comgdrjutilservicelocator*;
  public class Database {
   /**
    * 這個數據庫連接成員只有在與數據庫直接建立連接的情況下是有效的
    */
   private Connection conn = null;
   /**
    * 當這個參數有效時表明程序是直接與數據庫建立的連接而不是從連接池裡取得連接
    */
   private String url user password;
   /**
    * 當這個參數有效時表明程序是從連接池裡取得連接
    */
   private String datasource;
   /**
    * 用數據庫地址用戶名密碼初始化數據庫對象這個構造器用於程序是直接
    * 與數據庫建立連接的情況
    * @param url
    * @param user
    * @param password
    */
   public Database(String url String user String password) {
    thisurl = url;
    thisuser = user;
    thispassword = password;
   }
  
   /**
    * 用JNDI數據源名初始化數據庫對象這個構造器用於從連接池取數據庫連接的情況
    * @param datasource
    */
   public Database(String datasource) {
    thisdatasource = datasource;
   }
  
   /**
    * 得到數據庫連接對於是否從連接池裡取連接做了自動處理即根據用戶調用了哪個構造器
    * 來判斷是否直接與數據庫建立連接還是從連接池裡取連接
    * 對於用戶來說不用考慮程序是從那裡取得連接他只管正確的初始化數據庫對象
    * @return
    * @throws SQLException
    */
   public Connection getConnection() throws Exception {
    if (datasource == null) { //直接與數據庫建立連接
     if (conn == null) {
      conn = DriverManagergetConnection(url user password);
     }
    }
    else { //從應用服務器的連接池裡取得連接
     ServiceLocator sl = ServiceLocatorgetInstance();
     DataSource ds = slgetDataSource(datasource);
     return dsgetConnection();//每調用一次都返回一個連接池中的數據庫連接
    }
    return conn;
   }
  
   /**
    * 釋放連接如果是直接與數據庫連接的情況則什麼也不做
    * 如果是從連接池中取得的連接那麼釋放傳來的連接
    * @param conn
    */
   public void disConnect(Connection connection) {
    if (datasource != null) { //只處理從連接池取連接的情況
     try {
      if (connection != null) {
       connectionclose();
      }
     }
     catch (Exception ex) {}
    }
   }
  
   /**
    * 得到與參數名對應的表對象注意這裡不作任何數據庫操作
    * @param name
    * @return
    */
   public Table getTable(String name) {
    return new Table(this name);
   }
  }
  
  這個類是對DBMS的抽象所以使用時應用程序中只要有一個Database對象就夠了如果你是以與數據庫之間建立連接的方式使用那麼你用Database(String url String user String password)構造器進行初始化如果是從應用服務器的連接池中取得連接的方式使用那麼用Database(String datasource)構造器初始化這樣以後你使用這個對象進行getConnection和disConnection時就不用去考慮始終保持一個連接(C/S方式)還是將連接返回連接池了因為在disConnection中已經做了處理集體使用方法將Table類在getConnection中的從連接池中取連接的代碼你只要參考以下《JEE核心模式》中的服務定位器模式就知道是怎麼回事了你在用Database(String url String user String password)初始化時其中的代碼不起作用
  ?  Table類源碼如下
  package comgdrjutildatabase;
  import javasql*;
  import javautil*;
  import comgdrjutil*;
  public class Table {
   /**
    * 通過這個數據庫對象得到數據庫連接
    */
   private Database database;
   /**
    * 數據庫中一個或多個(只限查詢)表的名
    */
   private String name;
   /**
    * 初始化表對象此時不作任何數據庫相關操作
    * 一般通過database的getTable調用
    * @param database
    * @param name
    */
   public Table(Database database String name) {
    thisdatabase = database;
    thisname = name;
   }
   /**
    * 查詢某一行
    * @return
    */
   public Row getRow(String fields String criteria Object[] args) throws
     DBAccessException {
    RowSet rows = executeQuery(fields criteria args);
    if (rows == null) {
     return null;
    }
    return rowsget();
   }
   /**
    * 得到一個多行記錄
    * @param criteria 查詢條件
    * @param args 查詢條件的參數列表
    * @return
    */
   public RowSet getRows(String fields String criteria Object[] args) throws
     DBAccessException {
    return executeQuery(fields criteria args);
   }
   /**
    * 執行SQL查詢
    * @param fields 要查詢的字段如果傳入null則表示查詢表中所有字段
    * @param criteria用戶輸入的查詢Where條件
    * @param args 用到的參數數組
    * @return 返回符合結果行集
    */
   private RowSet executeQuery(String fields String criteria Object[] args) throws
     DBAccessException {
    Connection conn = null;
    RowSet rows = new RowSet();
    String sql = null;
    if (fields == null) {
     fields = *;
    }
    try {
     conn = databasegetConnection(); //取得數據庫連接在方法內部對不同的連接情況進行了處理
     sql = select + fields + from + name +
       ( (criteria == null) ? :
        ( where + criteria));
     PreparedStatement pstmt = connprepareStatement(sql);
     if (args != null) { //如果有查詢參數則設置參數
      for (int i = ; i < args.length; i++) {
       pstmt.setObject(i + 1, args[i]);
      }
     }
     ResultSet rs = pstmt.executeQuery();
     ResultSetMetaData rsmd = rs.getMetaData();
     int cols = rsmd.getColumnCount();
     /**@todo 判斷是否為零*/
     if (cols == 0) {
      return null;
     }
     while (rs.next()) {
      Row row = new Row();
      for (int i = 1; i <= cols; i++) {
       String name = rsmd.getColumnName(i);
       Object value = rs.getObject(i); //作通用類型處理,這
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26189.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.