熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

用Java構造Intranet范例查詢系統

2013-11-15 09:50:06  來源: JSP教程 

  范例查詢
  我們的終極目標是一個能夠滿足所有潛在用戶的Intranet為此我們必須提高Intranet用戶訪問數據庫的靈活性一種可能的方案是采用所謂的即席查詢(Adhoc Query)
  
  即席兩個字在這裡的含義是不作特殊准備地隨意自由地即席查詢允許用戶象數據庫管理員一樣自由地訪問數據庫也許最靈活的方式是讓用戶在Web頁面的文本輸入框中直接輸入SQL命令然後由應用發送該SQL命令查詢數據庫然而雖然這種方式很靈活但要實施得好很困難存在許多問題
  
  首先這種方式不安全如果不對用戶進行大量的培訓不在應用中對用戶輸入的SQL命令進行嚴格的檢驗用戶可能有意無意地破壞系統運行另外即使進行了培訓要求用戶總是能夠構造出高效的SQL查詢也不切實際
  
  然而這些問題並不能完全阻礙我們構造出有效的Intranet即席查詢系統一般地Intranet內的用戶比網絡之外的用戶可信度高為此我們可以采用靈活性稍差但仍不失高效的方案——范例查詢(QueryByExampleQBE)范例查詢的使用簡單靈活不需要對用戶進行大量的培訓同時它也比直接使用SQL的方式更安全
  
  在范例查詢系統中我們提供給用戶的界面與數據庫結構之間有著密切的對應關系每一個查詢項目有一個相應的用戶界面控件例如假設有一個雇員信息數據庫我們用一個列表框允許用戶選擇雇員所在的部門用一個文本框允許用戶輸入薪金范圍限制查詢結果
  
  數據庫抽象
  對於一些程序員來說數據庫操作有時就象是一堆散亂的連接字符串SQL命令和結果集Java的面向對象特色可以讓數據源具有更好的可管理性接下來我們將用Java技術構造一個浏覽器界面的QBE系統這個系統以幾個核心類為基礎核心類允許JSP頁面在更高的層次上操作數據庫避免大量地編寫底層SQL代碼
  
  數據庫最基本的元素之一是表在數據庫中表是數據記錄的容器比如用來容納雇員名字和薪水信息下面的DBTable類描述的就是數據庫裡面的表DBTable類的公用方法負責處理最底層的細節比如addChildTable方法用來建立表的父子關系addConstraint方法用來過濾表的輸出
  
  【Listing DBTablejava描述數據庫的表】
  
  
  import javautil*;
  public class DBTable {
   String pkey;    // 主鍵
   String name;    // 表的名字
   Vector columns;   // 結果集包含的列
   Hashtable col_desc; // 各個列的描述
   Vector children;  // 子表
   Vector constraints; // 所有約束
   /* 創建一個新的未經初始化的表*/
   protected DBTable() {
  columns   = new Vector();
  children  = new Vector();
  constraints = new Vector();
  col_desc = new Hashtable();
   }
   /* 創建一個新的表指定名字和主鍵*/
   public DBTable(String name String pkey) {
  this();
  thisname = name;
  thispkey = pkey;
   }
   /* 返回主鍵 */
   public String getPrimaryKey() {
  return pkey;
   }
   /* 創建一個新的約束設置它的值
  * 並把它加入表的約束列表
  */
   public void addConstraint(String column
      int op String value) {
  Constraint c = new Constraint();
  lumn = column;
  cop   = op;
  cvalue = value;
  constraintsadd(c);
   }
   /* 把結果集限制為單個記錄的簡便方法 */
   public void constrainByPrimaryKey(String value) {
  addConstraint(pkey ConstraintEQ + value + );
   }
   /* 添加一個列 */
   public void addColumn(String column
           String description) {
  columnsadd(column);
  col_descput(column description);
   }
   /* 添加一個子表通過外鍵建立關系 */
   public void addChildTable(DBTable table String fkey) {
  childrenadd(table);
  addConstraint(thispkey ConstraintEQ
        tablename + + fkey);
   }
   /* 搜索當前表以及(遞歸地搜索)所有子表
  * 尋找指定的列返回該列的描述 */
   public String findColumnDescription(String column) {
  String result = (String) col_descget(column);
  if (result != null) { // 已經找到指定的列
   return result;
  } else {
   // 在所有子表中搜索該列
   Enumeration e = childrenelements();
   while (ehasMoreElements()) {
    DBTable child = (DBTable) enextElement();
    result = childfindColumnDescription(column);
    if (result != null) { // 已經找到!
     return result;
    }
   }
   return null; // 在所有表中都無法找到指定的列
  }
   }
   /* 搜索當前表以及(遞歸地搜索)所有子表
  * 檢查指定的列是否是一個主鍵 */
   public boolean isPrimaryKey(String column) {
  if (pkeyequals(column)) { // 已經找到指定的列
   return true;
  } else {
   // 搜索所有子表
   Enumeration e = childrenelements();
   while (ehasMoreElements()) {
    DBTable child = (DBTable) enextElement();
    if (childisPrimaryKey(column)) { // 已經找到!
     return true;
    }
   }
   return false;
  }
   }
  }
  
  單獨的DBTable類其實沒有什麼實際用途它只是一種抽象的描述既沒有建立底層的數據庫連接也沒有任何SQL命令為發揮DBTable類的作用我們必須定義一個DBTable類的子類在子類中利用DBTable類定義的方法訪問數據庫服務器
  
  下面就是DBTable類的子類SQLDBTablejava
  
  【Listing SQLDBTable擴展DBTable提供SQL和JDBC支持】
  
  import javasql*;
  import javautil*;
  public class SQLDBTable extends DBTable {
   /* 構造函數 */
   public SQLDBTable(String name String pkey) {
  super(name pkey);
   }
   /* 生成一個SQL命令 */
   public String generateSQL() {
  /* 獲得SQL命令中出現的所有表的一個清單 */
  Vector tables = new Vector();
  findTables(tables);
  /* 獲得所有列的一個清單 */
  Vector columns = new Vector();
  findColumns(columns);
  /* 獲得必須在WHERE子句中出現的所有約束
   * 的一個清單
   */
  Vector where = new Vector();
  findConstraints(where);
  /* 創建一個容納SQL命令的StringBuffer */
  StringBuffer sql = new StringBuffer(SELECT );
  sqlappend(delimitedList( columnselements()));
  sqlappend( FROM );
  sqlappend(delimitedList( tableselements()));
  if (wheresize() > ) {
   sqlappend( WHERE );
   sqlappend(delimitedList( AND whereelements()));
  }
  return sqltoString();
   }
   /* 利用一個JDBC連接提取結果記錄
  * 注意調用者必須關閉結果集的
  * Statement對象
  */
   public ResultSet fetchRows(Connection conn)
  throws Exception
   {
  String sql = generateSQL();
  /* 創建Statement(可能拋出SQLExeception異常)*/
  Statement stmt = conncreateStatement();
  /* 返回結果集 */
  return stmtexecuteQuery(sql);
   }
   /* 這是一個從主鍵以外的各個列獲取數據的簡便
  * 方法它在下列情形下使用當你不想讓用戶看到主鍵時
  *關於使用該方法的例子請參見HtmlSelectListMakerjava
  */
   public Enumeration getDisplayData(ResultSet rs) throws SQLException
   {
  ResultSetMetaData rmd = rsgetMetaData();
  Vector result = new Vector();
  for(int i = ; i < rmdgetColumnCount(); i++) {
   String column = rmdgetColumnName(i + );
   if (isPrimaryKey(column)) {
    continue;
   }
   resultaddElement( rsgetString(column) );
  }
  return resultelements();
   }
   /* 該方法生成帶分界符的列表僅供內部使用
  * 用來為SQL命令生成空格或逗號分隔的列表
  */
   private String delimitedList(String delim Enumeration e)

From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19196.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.