国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

用Java構(gòu)造Intranet范例查詢系統(tǒng)

2019-11-18 13:16:45
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

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

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 格尔木市| 社旗县| 凤城市| 新民市| 赤水市| 汉源县| 德兴市| 阿拉尔市| 广昌县| 嘉禾县| 濮阳县| 曲阳县| 临沧市| 缙云县| 古交市| 文昌市| 怀来县| 德清县| 中方县| 中超| 双牌县| 桂阳县| 东方市| 广水市| 马尔康县| 法库县| 郎溪县| 长武县| 房产| 泽普县| 宜章县| 阿荣旗| 武陟县| 芜湖县| 康马县| 利辛县| 梨树县| 中牟县| 五华县| 胶南市| 大石桥市|