無為

          無為則可為,無為則至深!

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks

          公告

          與有奉獻精神和分享精神的人做朋友!

          Locations of visitors to this page
          Subscribe by Anothr

          搜索

          •  

          積分與排名

          • 積分 - 581780
          • 排名 - 83

          最新評論

          閱讀排行榜

          感謝偉大的 Java 技術、感謝天才之作《 Java Developers ALMANAC , 它們成就了 PVO 技術的誕生。也許是我個人的偏見,到目前為止,真不知道還有什么技術會像 PVO 這樣給數據庫編程帶來如此之高的效率,使用起來卻是如此的簡單!
          我曾經拜讀過 OMR JDO 之類技術方面的文章,見到一大堆復雜的技術真讓人望而卻步;也聽別人介紹過 hibernate 技術,在網上也見到過不少人在談論 hibernate 技術,他們總是津津樂道,而給我的感覺總是一盆霧水。在探索和迷茫的過程中,不禁要問, Java 本來就是一個高效、強大的象征,為什么會被 OMR JDO hibernate 之類弄得如此復雜?在簡化數據庫編程方面,難道就沒有更好的方法嗎?我與其把大量的精力花在鉆研 OMR JDO hiberlate 之類的技術上,還不如多花些精力鉆研 Java 技術本身,從中去尋求解決之道。于是一個實用的 HashMap 關系數據映射技術歷時半年,在本人開發“ 皖南熱線網站 ”之前終于誕生了,并在“皖南熱線網站”的開發過程中不斷得到完善、充實、檢驗。
          PVO Process Value Object 的縮寫,意為值對象加工, ProcessVO 是本案的核心類,故將此技術簡稱為 PVO 技術 在簡化數據庫編程方面,這是一項重要的技術創新 。無論是與常規的 JDBC 數據庫編程技術相比,還是與現有流行的各種數據映射技術相比,此方案可能會在一個項目開發中,將數據庫的編程效率提高數倍、甚至是數十倍,如果一個表的字段有數十個,就會存在這樣的可能性。數據庫字段越多, PVO 技術能帶來的編程效率就越明顯 。為什么 PVO 技術會有如此之高的編程效率?主要原因有以下幾點:
          1、Java 容器技術、 Java 實用類技術本身就是高效、成熟的技術。
          2、 不論是讀取數據,還是存入數據,均使用了 JDBC 元數據技術、反射技術來自動實現記錄與 HashMap 之間的映射、結果集與 Vector 之間的映射。
          3、 免去了復雜的 XML Properties 之類的配置。
          4、SQL 標準語句參數化生成技術,會將所映射的 HashMap 對象,自動轉化成 SQL 標準語句的一部分,以供 JDBC API 調用;不再需要你去調用 rs.getString(fieldName) pstmt.setString(i , objectValue); 之類的方法了。
          5、 如果是進行 Web 應用開發,本方案提供的 BaseMapForm 重載了 Struts ActionForm reset 方法,除了上傳文件,只用一個 Map record 屬性,來取代其它所有的屬性,以不變應萬變,再不需要你去定義一大堆屬性了。
          6、 如果一個字段類型發生了變化,甚至是添加了幾個新字段,再不須要你去修改業務邏輯部分的代碼了。
          PVO 技術方案符合 DAO 設計模式思想,有效地實現了數據庫訪問操作與業務邏輯的分離。核心類 ProcessVO 封裝了與數據庫相關的所有基本操作,如:插入、更新、刪除、查詢,并且實現了對查詢結果集進行分頁、篩選、排序、備份、獲取子集的多種算法。此案通用性強,在 EJB Application Servlet Applet 等應用中均可不受限制地方便使用。 PVO 不但可以大大提高數據庫編程的效率,同時可以大大減輕數據庫服務器數據流量的負擔。
          支持標準的 SQL 操作,如:插入、更新、刪除、查詢(包括多表查詢)。
          運用 Java 反射技術來實現 HashMap 與關系型數據之間的映射。
          運用 Java 反射技術,參數化生成 SQL 標準語句,供 JDBC API 調用。
          針對每一條記錄,使用 HashMap 對象作為數據的載體,這個 HashMap 對象的鍵名是表中的字段名,或是字段的別名,鍵值為字段值,鍵值的類型是字段所對應的 JDBC API Java 類。 針對數據庫的操作,如:插入、更新、刪除、查詢,該方法會將所傳遞的 Map 型參數轉化成 SQL 語句的組成部分,自動生成完整的標準的 SQL 語句,供 JDBC API 調用。
          支持復雜的多表查詢,針對每一個查詢結果集,用一個 Vector 對象存貯,而這個 Vector 中的每一個元素均是一個 HashMap 對象,這個對象映射了一條記錄。
          充分利用了成熟的豐富的 Java 容器技術,實現了對這個 Vector 查詢結果集進行分頁、篩選、排序、備份、獲取子集的多種算法。
          基本技術包括:
          JDBC JDBC 元數據技術;
          Map Vector 等容器技術;
          Java 反射技術;
          通用 SQL 標準語句參數化生成技術及其算法;
          HashMap 與關系數據庫記錄之間的映射技術及其算法。
          1、 包名:核心包 cn.hkm.sql web 應用包 cn.hkm.web
          2、 下載 PVO_v1.0
          3、 類文件:
          cn.hkm.sql 包括 ProcessVO DbCon Tool WhereString QueryString
          cn.hkm.web 包括: BaseMapForm PvoPageTag PvoSqlTag PvoRecordTag PvoImgsTag PvoImgTag PvoShowImgTag PvoRecordMapTag 以及標志庫描述文件 pvotag.tld
          ????
          1、 查詢,例:
          ProcessVO pvo=new ProcessVO();
          pvo.setCon(con);
          // 也可用 ProcessVO pvo=new ProcessVO(con);
          Vector v=pvo.getSomeRecord( select a.* ,b.name from… where … );
          pvo.closeCon();
          // 也可省略, ProcessVO 類重載了 finalize() ,在其中會自動關閉數據庫聯接。
          2、 插入,例:
          ProcessVO pvo=new ProcessVO(con);
          boolean b =insertObjectRecord(tableName, map);
          // 也可使用 int i=pvo.insertARecord("insert into …");
          pvo.closeCon();
          3、 更新,例:
          ProcessVO pvo=new ProcessVO(con);
          boolean b=pvo.updateARecord("table",map,new WhereString("key_id","=",id));
          pvo.closeCon();
          4、 刪除,例:
          ProcessVO pvo=new ProcessVO(con);
          int i=pvo.delRecord(“delete from …”);
          pvo.closeCon();
          ?
          五、在 Web 中的應用,與Struts 完美結合
          設數據庫表如:
          create table tel(
          tel_id bigint primary key,
          clerk_id bigint,
          type varchar(8),
          code varchar(32)
          )
          create table clerk(
          clerk_id bigint primary key,
          name varchar(32),
          birthday varchar(10),
          descreption varchar(255)
          )
            本案可以與流行的 Struts 架構完美結合,使用時請將 pvotag.tld 復制到 WEB-INF 目錄中。為了更方便地使用, cn.hkm.web.BaseMapForm 類繼承了 Struts 中的 org.apache.struts.action.ActionForm ,并且重載了 reset 方法, 增加了一個Map record屬性 ,只要您的 ActionForm 繼承 BaseMapForm ,并按以下方式重載 reset 方法:
          ??? public void reset(ActionMapping actionMapping,HttpServletRequest servletRequest) {
          ??????? super.reset(actionMapping,servletRequest);
          }
          這樣,在理論上,除了上傳文件外, 只要有這一個Map record屬性,就足夠了。
          1、 查詢,例:
          ProcessVO pvo=new ProcessVO(con);
          Vector v=pvo.getSomeRecord( select a.* ,b.name from tel as a, clerk as b where a.clerk_id=b.clerk_id );
          session.setAttribute("clerk_tel_v",v);
               // 在頁面中調用 Vector 結果集,以流行的 Struts 為例
               <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
          ??????? <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
               <%@ taglib uri="/WEB-INF/pvotag.tld" prefix="pvo" %>
               ……..
               ?<table bgcolor="white" width="100%" cellpadding="0" cellspacing="1">
          ??????????? <logic:present name="clerk_tel_v">
          ??????????????? <tr align=’center’>
          <td> 姓名 </td>
          <td> 分類 </td>
          <td> 號碼 </td>
          </tr>
          ????????????? <logic:iterate id="record" name="clerk_tel_v">
          ??????????????? <tr>
          ????????????????? <td><bean:write name="record" property="name"/></td>
          ????????????????? <td><bean:write name="record" property="type"/></td>
          ????????????????? <td><bean:write name="record" property="code"/></td>
          ??????????????? </tr>
          ????????????? </logic:iterate>
          ??????????? </logic:present>
          ????????? </table>
          ?
          如果表中有記錄,則會有類似以下的結果:
          姓名
          分類
          號碼
          張三
          手機
          13955668899
          張三
          電話
          0553-6823888
          張三
          傳真
          0553-6823888
          ?
          2、 數據錄入(添加記錄與編輯記錄),例:
          頁面中的表單,
          書寫格式為 record. 字段名 的域,會自動成為 Map record 屬性中的元素,其鍵名就是字段名,其鍵值就是域值
          ???    <p><h1 style="color:yellow"> 人員信息錄入 </h1></p>
          ?     <html:form action="/menuAction.do?method=clerk" method="post">
               <p>
          ???????????? 姓名 ???????????
          ???????    <html:hidden property="id"/>????????
          ??????????? <html:text property="record.name"/>
          ?????   </p>
               <p> 出生日期 <html:text property="record.birthday"/></p>
          <p> 簡介 <html:text property="record.descreption"/></p>
          <p><html:submit> 提交 </html:submit></p>
          </html:form>
          ?
          /**MenuAction 中的 clerk 方法 */
          public ActionForward clerk(ActionMapping actionMapping,
          ???????????????????????????????? ActionForm actionForm,
          ?????????????????????????? ??????HttpServletRequest servletRequest,
          ???????????????????????????????? HttpServletResponse servletResponse) {
          String id=servletRequest.getParameter("id");
          ??? ProcessVO pvo=new ProcessVO(con);
          ??? MapForm form = (MapForm) actionForm;
          ??? boolean b=false;??
          ??? Map map=form.getRecord();// 獲取表單中的記錄
          ??? if ((id == null)||id.equals("")){
               // 新插入一條記錄
          Long ID = pvo.insertKey("clerk", "clerk_id");???????
          ??????? b=pvo.updateARecord("clerk",map,new WhereString("clerk_id", "=", ID));
          ??????? pvo.closeCon();
          ???????if (b) {}
          ??? }else {
          // 更新一條記錄
          ??????? pvo.setCon(con);
          ??????? b = pvo.updateARecord("clerk", map, new WhereString("clerk_id", "=", id));
          ??????? pvo.closeCon();
          ??????? if (b) {}
          ??? }
          // 在頁面表單中,隱含域 <html:hidden property="id"/>
          // 也可替換成 <html:hidden property="record.clerk_id"/>
          // 但在更新數據時,請預先保存 clerk_id 值,如 String id=(Long)record.get(“clerk_id”).toString
          // 然后調用 record.remove(“clerk_id”)
          // 更新操作完畢后,調用 record.put(“clerk_id”,id) ,以便編輯記錄使用。
          // 原因是: updateARecord() 會自動將 map 中的所有元素作為 SQL 語句中的組
          // 成部分,生成類似以下的語句:
          //update clerk set clerk_id=?,name=?,birthday=?,descreption=?
          //where (clerk_id = '123')
          // update 語句中, set 主鍵名 where 主鍵名 同時出現不被數據庫支持
          return actionMapping.findForward("clerk");
          ?}
          ?
          /**clerk_edit 方法,從數據庫中提取一條指定的記錄,供表單編輯使用 */
          public ActionForward clerk_edit(ActionMapping actionMapping,
          ???????????????????????????? ActionForm actionForm,
          ???????????????????????????? HttpServletRequest servletRequest,
          ???????????????????????????? HttpServletResponse servletResponse) {
          ??? String id=servletRequest.getParameter("id");
          ??? ProcessVO pvo=new ProcessVO(con);
          ??? Map map=pvo.getARecord("clerk","clerk_id",id);???
          ??? MapForm form = (MapForm) actionForm;
          ??? form.setId(id);
          ??? form.setRecord(map);
          // 如果用常規的方式,準備數據是一件非常辛苦的工作。而用 PVO 時,是如此簡單。
          ??? return actionMapping.findForward("clerk");
          }
          ?
          請注意無論是插入一條新記錄,還是更新一條記錄以及為表單準備數據,操作都十分簡潔。更值得一提的是,如果數據庫表中的字段類型發生變化,不須修改 clerk 方法,如果表中增加了一些新的字段,也不須修改 clerk 方法,只要在表單中添加相應的屬性。 假如:表中添加了新字段,
          age int,
          sex varchar(2),
          在表單中添加以下兩行即可:
          <p> 年齡 <html:text property=" record.age "/></p>
          <p> 性別 <html:text property=" record.sex "/></p>
          注意!使用格式是: record. 字段名
          ?
          HashMap 關系數據映射技術》源代碼將在今后適當的時候公布。


          凡是有該標志的文章,都是該blog博主Caoer(草兒)原創,凡是索引、收藏
          、轉載請注明來處和原文作者。非常感謝。

          posted on 2006-05-21 17:11 草兒 閱讀(929) 評論(1)  編輯  收藏 所屬分類: java

          Feedback

          # re: HashMap關系數據映射技術(簡稱PVO技術) 2006-05-25 19:28 pc
          http://www.kpwang.com/pc/view.jsp?board_id=1&article_id=200645223821
          Java常見問題集錦(轉載)

          http://www.kpwang.com/pc/view.jsp?board_id=1&article_id=200645223641
          java中的易混問題收集

          http://www.kpwang.com/pc/view.jsp?board_id=1&article_id=20064522334
          Java學習過程的一些重點  回復  更多評論
            

          主站蜘蛛池模板: 休宁县| 沧州市| 高阳县| 寿阳县| 明溪县| 常山县| 福建省| 玛纳斯县| 泸溪县| 淳安县| 东源县| 龙井市| 习水县| 延吉市| 宜宾市| 石家庄市| 星子县| 嘉禾县| 罗甸县| 九台市| 白山市| 大田县| 准格尔旗| 登封市| 无棣县| 双鸭山市| 繁峙县| 通河县| 同心县| 马尔康县| 西充县| 上虞市| 柞水县| 望城县| 车险| 罗定市| 四子王旗| 嘉义县| 鄂尔多斯市| 伊吾县| 宣城市|