麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

用Java構造Intranet范例查詢系統

2019-11-18 13:16:45
字體:
來源:轉載
供稿:網友

  一、范例查詢
  我們的終極目標是一個能夠滿足所有潛在用戶的Intranet。為此,我們必須提高Intranet用戶訪問數據庫的靈活性,一種可能的方案是采用所謂的即席查詢(Ad-hoc Query)。
  
  “即席”兩個字在這里的含義是“不作非凡預備地,隨意、自由地”。即席查詢答應用戶象數據庫治理員一樣,自由地訪問數據庫。也許,最靈活的方式是讓用戶在Web頁面的文本輸入框中直接輸入SQL命令,然后由應用發送該SQL命令查詢數據庫。然而,雖然這種方式很靈活,但要實施得好很困難,存在許多問題。
  
  首先,這種方式不安全。假如不對用戶進行大量的培訓,不在應用中對用戶輸入的SQL命令進行嚴格的檢驗,用戶可能有意無意地破壞系統運行。另外,即使進行了培訓,要求用戶總是能夠構造出高效的SQL查詢也不切實際。
  
  然而,這些問題并不能完全阻礙我們構造出有效的Intranet即席查詢系統。一般地,Intranet內的用戶比網絡之外的用戶可信度高。為此,我們可以采用靈活性稍差但仍不失高效的方案——范例查詢(Query-By-Example,QBE)。范例查詢的使用簡單、靈活,不需要對用戶進行大量的培訓,同時它也比直接使用SQL的方式更安全。
  
  在范例查詢系統中,我們提供給用戶的界面與數據庫結構之間有著密切的對應關系。每一個查詢項目有一個相應的用戶界面控件。例如,假設有一個雇員信息數據庫,我們用一個列表框答應用戶選擇雇員所在的部門,用一個文本框答應用戶輸入薪金范圍限制查詢結果。
  
  二、數據庫抽象
  對于一些程序員來說,數據庫操作有時就象是一堆散亂的連接字符串、SQL命令和結果集。java的面向對象特色可以讓數據源具有更好的可治理性。接下來我們將用Java技術構造一個瀏覽器界面的QBE系統。這個系統以幾個核心類為基礎,核心類答應jsp頁面在更高的層次上操作數據庫,避免大量地編寫底層SQL代碼。
  
  數據庫最基本的元素之一是表。在數據庫中,表是數據記錄的容器,比如用來容納雇員名字和薪水信息。下面的DBTable類描述的就是數據庫里面的表。DBTable類的公用方法負責處理最底層的細節。比如,addChildTable方法用來建立表的父-子關系,addConstraint方法用來過濾表的輸出。
  
  【Listing 1:DBTable.java,描述數據庫的表】
  
  
  import java.util.*;
  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();
  this.name = name;
  this.pkey = pkey;
   }
   /* 返回主鍵 */
   public String getPrimaryKey() {
  return pkey;
   }
   /* 創建一個新的約束,設置它的值,
  * 并把它加入表的約束列表
  */
   public void addConstraint(String column,
      int op, String value) {
  Constraint c = new Constraint();
  c.column = column;
  c.op   = op;
  c.value = value;
  constraints.add(c);
   }
   /* 把結果集限制為單個記錄的簡便方法 */
   public void constrainByPrimaryKey(String value) {
  addConstraint(pkey, Constraint.EQ, "'" + value + "'");
   }
   /* 添加一個列 */
   public void addColumn(String column,
           String description) {
  columns.add(column);
  col_desc.put(column, description);
   }
   /* 添加一個子表,通過外鍵建立關系 */
   public void addChildTable(DBTable table, String fkey) {
  children.add(table);
  addConstraint(this.pkey, Constraint.EQ,
        table.name + "." + fkey);
   }
   /* 搜索當前表以及(遞歸地搜索)所有子表,
  * 尋找指定的列,返回該列的描述 */
   public String findColumnDescription(String column) {
  String result = (String) col_desc.get(column);
  if (result != null) { // 已經找到指定的列
   return result;
  } else {
   // 在所有子表中搜索該列
   Enumeration e = children.elements();
   while (e.hasMoreElements()) {
    DBTable child = (DBTable) e.nextElement();
    result = child.findColumnDescription(column);
    if (result != null) { // 已經找到!
     return result;
    }
   }
   return null; // 在所有表中都無法找到指定的列
  }
   }
   /* 搜索當前表以及(遞歸地搜索)所有子表,
  * 檢查指定的列是否是一個主鍵 */
   public boolean isPrimaryKey(String column) {
  if (pkey.equals(column)) { // 已經找到指定的列
   return true;
  } else {
   // 搜索所有子表
   Enumeration e = children.elements();
   while (e.hasMoreElements()) {
    DBTable child = (DBTable) e.nextElement();
    if (child.isPrimaryKey(column)) { // 已經找到!
     return true;
    }
   }
   return false;
  }
   }
  }
  
  單獨的DBTable類其實沒有什么實際用途,它只是一種抽象的描述,既沒有建立底層的數據庫連接,也沒有任何SQL命令。為發揮DBTable類的作用,我們必須定義一個DBTable類的子類,在子類中利用DBTable類定義的方法訪問數據庫服務器。
  
  下面就是DBTable類的子類SQLDBTable.java:
  
  【Listing 2:SQLDBTable,擴展DBTable提供SQL和JDBC支持】
  
  import java.sql.*;
  import java.util.*;
  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 ");
  sql.append(delimitedList(", ", columns.elements()));
  sql.append(" FROM ");
  sql.append(delimitedList(", ", tables.elements()));
  if (where.size() > 0) {
   sql.append(" WHERE ");
   sql.append(delimitedList(" AND ", where.elements()));
  }
  return sql.toString();
   }
   /* 利用一個JDBC連接提取結果記錄,
  * 注重:調用者必須關閉結果集的
  * Statement對象
  */
   public ResultSet fetchRows(Connection conn)
  throws Exception
   {
  String sql = generateSQL();
  /* 創建Statement(可能拋出SQLExeception異常)*/
  Statement stmt = conn.createStatement();
  /* 返回結果集 */
  return stmt.executeQuery(sql);
   }
   /* 這是一個從主鍵以外的各個列獲取數據的簡便
  * 方法。它在下列情形下使用:當你不想讓用戶看到主鍵時。
  *關于使用該方法的例子,請參見HtmlSelectListMaker.java。
  */
   public Enumeration getDisplayData(ResultSet rs) throws SQLException
   {
  ResultSetMetaData rmd = rs.getMetaData();
  Vector result = new Vector();
  for(int i = 0; i < rmd.getColumnCount(); i++) {
   String column = rmd.getColumnName(i + 1);
   if (isPrimaryKey(column)) {
    continue;
   }
   result.addElement( rs.getString(column) );
  }
  return result.elements();
   }
   /* 該方法生成帶分界符的列表,僅供內部使用。
  * 用來為SQL命令生成空格或逗號分隔的列表。
  */
   private String delimitedList(String delim, Enumeration e)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 香蕉视频1024 | 午夜精品视频免费观看 | 一二区成人影院电影网 | 91成人在线网站 | 国毛片| 少妇的肉体2无删减版 | 免费久久久久 | 亚洲一区二区中文字幕在线观看 | 91短视频版高清在线观看www | 玩偶姐姐 在线观看 | 国产一区二区精彩视频 | 澳门一级淫片免费视频 | 亚洲午夜一区二区三区 | 色阁阁69婷婷 | 一级国产航空美女毛片内谢 | 中文字幕精品在线视频 | 女人裸体让男人桶全过程 | 国产外围在线 | 1314av| 激情亚洲一区二区 | 一级免费大片 | 999久久久 | 欧美国产一区二区三区 | 欧美在线小视频 | 国产手机国产手机在线 | 成人一级毛片 | 男人的天堂毛片 | 蜜桃av鲁一鲁一鲁一鲁 | 国产精品成人免费一区久久羞羞 | asian裸体佳人pics | 久草在线新时代视觉 | 欧美女孩videos | 欧美成人一二三区 | 国产无遮挡一区二区三区毛片日本 | 欧美人的天堂一区二区三区 | 欧美在线黄色 | 欧美成年私人网站 | 国产精品久久久久一区二区 | 国产妞干网 | 午夜九九九 | 国产二区三区四区 |