无为

无为则可为,无为则至深!

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks
感谢伟大的 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 草儿 阅读(807) 评论(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学习过程的一些重点  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: