`
lujar
  • 浏览: 495704 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

J2EE中几种面向对象的数据库映射访问策略:

阅读更多

几种面向对象的数据库访问策略:

1 JDBC
是最原始的方法,写sql语句,维护性差


下面面向对象的方法:

例如update: 要先取出对象,更新对象,然后再保存

OrderInfo order = orderService.getOrder(orderId);
order.setStatus(new Integer(2));
orderService.updateOrder(order);

2 Hibernate

使用Hql

3 iBatis
将查询和更新放在maps文件中

  <dynamic-mapped-statement name="searchProductList" result-map="result">
    select productid, name, descn, category from product
    <dynamic prepend="where">
      <iterate property="keywordList" open="(" close=")" conjunction="OR">
        lower(name) like #keywordList[]# OR lower(category) like #keywordList[]# OR lower(descn) like #keywordList[]#
      </iterate>
    </dynamic>

4 EasyDBO:

有三种实现方法,我们只看其中采用annotation的
@Table(tableName="Customer")
public class Customer implements Serializable {
来确定表名

采用反射的方法,不需要配置文件:
 public List getRootCustomers() {  
  return this.dao.query(Customer.class,"(parent_id is null or parent_id='')");
 }

  List list=dao.query(CustomerPrice.class, "customer_id="+cu.getId()+" and product_id="+p.getId()+" order by vdate desc");

该方法已经和ADODB很像了,但和adodb不同的是,仍然没有实现完全自动的Plain SQL转换到PO.

5 PHP's ADODB的j2ee移植

以jdbc查询sql为基础,通过反射,范型等方法自动装载。
adodb的方法和上面的easydbo很像,不过在obj到sql的生成上更加成熟一些,驱动也更加多

对于查询

    /////////////////////////////////////////////////////////////////////////////
    //Function: 完成ResultSet对象向ArrayList对象为集合的对象的转化
    //Para:sql,指定的查询Sql
   //Para:className,Sql相对应得JavaBean/FormBean类的名字
   //Return:以类className为一条记录的结果集,完成ResultSet对象向ArrayList对象为集//合的className对象的转化
  //////////////////////////////////////////////////////////////////////////////
  public ArrayList Select(String sql,String className){
    ArrayList paraList=new ArrayList();
    try{
      if (conn == null){
        Connection();
      }
      PreparedStatement stmt = conn.prepareStatement(sql);
      ResultSet rs = stmt.executeQuery();
      String recordValue="";
      Object c1=null;
      paraList=new ArrayList();
      ResultSetMetaData rsmd = rs.getMetaData();
      int columnCount = rsmd.getColumnCount();
      while (rs.next()){
          c1=Class.forName(className).newInstance();
          for (int i=1; i<=columnCount; i++) {
            if(rs.getString(rsmd.getColumnName(i))!=null){
              recordValue=rs.getString(rsmd.getColumnName(i));
            }else{
              recordValue="";
            }
            Method m=c1.getClass().getMethod(getSetMethodName(rsmd.getColumnName(i)),new Class[]{recordValue.getClass()});
            m.invoke (c1, new Object[]{recordValue});
          }
          paraList.add(c1);
      }
    }catch(SQLException ex){
     
    }catch(ClassNotFoundException e){
    }catch(NoSuchMethodException e) {
    }catch(InvocationTargetException e){
    }catch (IllegalAccessException e){
    }catch(InstantiationException e){
    } finaly{
        closeConnection();
    return paraList;
    }
      }


   //Function:取得用户列表
  //Para:
  //Return:返回用户列表
  /////////////////////////////////////////////////////////////////////////////
  public ArrayList getUsers(){
      ArrayList ret=null;
      DatabaseManage db=new DatabaseManage();
      String sql=" select usr_id,usr_name "
          +" from users " ;  //该方法的好处是SQL可以随便写,需要的字段也可以随便写,甚至免去了持久层的LazyLoad
      ret=db.Select(sql,"com.domain.User");
      return ret;
  }

对于单张表,用PO/Formbean来存放
如果有关联多张表,需要一个VO/Map来存放

对于保存和更新
    检查对象里面的每一个属性,如果不是null,就组成SQL语句,
    更新的时候,先查出这个对象,如果属性不是null,并且属性值变了,才将该属性组成SQL语句
   
这种方法和Hibernate/Ibatis相比可能牺牲一些性能,但是免去了大量的配置文件,如果对字段有特殊的要求,可以
通过annotation来定义。

Annotation可是个好东西,根据jdk手册:Annotations can be read from source files, class files, or reflectively at run time.
所以可以充分利用反射读取annotation来减少代码。
下面是一些例子
@com.acme.util.Name(first=Alfred, middle=E., last=Neuman)
@Table(tableName="Customer")
@ManyToOne(column = "parent_id", fieldType=java.util.HashSet.class,type = Customer.class,lazy=false)
读取的方法是在反射里面使用下面的方法
<T extends Annotation> T xxx = getAnnotation(Class<T> annotationClass) 

当然,实现必须声明annotationClass,下面是手册的一个简单例子
/**
 * Describes the Request-For-Enhancement(RFE) that led
 * to the presence of the annotated API element.
   定义一个标签记号
 */
public @interface RequestForEnhancement {
    int    id();
    String synopsis();
    String engineer() default "[unassigned]";
    String date();    default "[unimplemented]";
}

这个标签,和它的属性都在上面声明了,下面是某个函数中需要用到这个标签的示例
@RequestForEnhancement(
    id       = 2868724,
    synopsis = "Enable time-travel",
    engineer = "Mr. Peabody",
    date     = "4/1/3007"
)
public static void travelThroughTime(Date destination) { ... }

因此我们如果想要调用这个标签
for (Method m : Class.forName('假设是travelThroughTime所在的类名').getMethods()) {
         if (m.isAnnotationPresent(RequestForEnhancement.class)) {
             RequestForEnhancement rfe = m.getAnnotation(RequestForEnhancement.class);
             下面就可以取得rfe的属性了
         }
      }

Commons Attributes也是一个替代jdk标准annotation的方案


PHP中的ADODB之所以强大,高效是在于PHP数组的强大和弱变量定义的方便。

当然这里的每一个对象就相当于对应数据库的一张表,这样也很好。
因为在业务相当复杂的时候,关联要尽量少用,把业务精心设计在数据库表上面而非java对象的集合的关联上。
在大型应用中,一般1:1的关联都多使用View来处理关联,1:n和n:n的关联,建议还是在DAO里面手动保存,装载和更新


===================
此外还有一些方法,可以方便我们快速的将RS变成可操作的对象,简单举几个例子如下

1 commons dbutils

Custom RowProcessor

java.lang.Object[] toArray(java.sql.ResultSet rs)
          Convert a ResultSet row into an Object[].
 java.lang.Object toBean(java.sql.ResultSet rs, java.lang.Class type)
          Convert a ResultSet row into a JavaBean.
 java.util.List toBeanList(java.sql.ResultSet rs, java.lang.Class type)
          Convert a ResultSet into a List of JavaBeans.
 java.util.Map toMap(java.sql.ResultSet rs)
          Convert a ResultSet row into a Map.


Custom BeanProcessor


 java.lang.Object toBean(java.sql.ResultSet rs, java.lang.Class type)
          Convert a ResultSet row into a JavaBean.
 java.util.List toBeanList(java.sql.ResultSet rs, java.lang.Class type)
          Convert a ResultSet into a List of JavaBeans.


2 commons beanutils
ResultSetDynaClass (Wraps ResultSet in DynaBeans)

  Connection conn = ...;
  Statement stmt = conn.createStatement();
  ResultSet rs = stmt.executeQuery
    ("select account_id, name from customers");
  Iterator rows = (new ResultSetDynaClass(rs)).iterator();
  while (rows.hasNext()) {
    DynaBean row = (DynaBean) rows.next();
    System.out.println("Account number is " +
                       row.get("account_id") +
                       " and name is " + row.get("name"));
  }
  rs.close();
  stmt.close();

============

总得来说,使用反射机制可以极大得方便对数据的各种操作,使操作变得更加透明,无需配置文件 

分享到:
评论

相关推荐

    J2EE中几种面向对象的数据库映射访问策略:.rar

    J2EE中几种面向对象的数据库映射访问策略:.rar

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    Java的产生与流行是当今Internet发展的客观要求,Java是一门各方面性能都很好的编程语言,它的基本特点是简单、面向对象、分布式、解释的、健壮的、安全的、结构中立的、可移植的、性能很优异的、多线程的、动态的,...

    Powerdesigner数据库分析设计与应用

    能在一个环境中支持所有几种建模技术的设计工具之一:数据库建模(概念数据模型 CDM,物理数据模型PDM),业务处理模型BPM,以及面向对象模型OOM,以及自 由模型FEM。  数据建模方面:利用基于可靠方法、真正的两...

    超级有影响力霸气的Java面试题大全文档

    面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性:  多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化...

    支持多数据库的ORM框架ef-orm.zip

    事实上JPA的几种数据查询方式存在青黄不接的问题。选择查询语言xxQL,项目面临后续维护困难,跨数据库移植性差;选择Criteria API,代码臃肿,操作繁琐,很多人望而却步。EF的设计思想是使人早日摆脱拼装SQL/HQL/...

    java面试题

    面向对象的特征? 答:1:封装:通过定义类并且给类的属性和方法加上访问控制 2:继承:子类继承父类,子类可以拥有父类中已定义的方法,并且子类可以修改父类中的方法使其更适合特殊需求。 3:多台:不同对象对...

    java 面试题 总结

    SessionBean在J2EE应用程序中被用来完成一些服务器端的业务操作,例如访问数据库、调用其他EJB组件。EntityBean被用来代表应用系统中用到的数据。 对于客户机,SessionBean是一种非持久性对象,它实现某些在服务器上...

    asp.net知识库

    在.NET访问MySql数据库时的几点经验! 自动代码生成器 关于能自定义格式的、支持多语言的、支持多数据库的代码生成器的想法 发布Oracle存储过程包c#代码生成工具(CodeRobot) New Folder XCodeFactory3.0完全攻略--...

    JAVA面试题最全集

    76.EJB有哪几种?区别是什么? 77.JavaBean与EJB有什么区别? 78.软件开发生命周期有哪几个阶段? 79.软件开发有哪些因素? 80.软件开发中如何进行版本控制? 81.UML中,类视图如何表示类中的继承与聚合? 82.客户端...

    计算机网络专业毕业实习报告3000字.docx

    Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。 计算机网络...

    ibatis 开发指南(pdf)

    开发规范中要求, 所有牵涉到业务逻辑部分的数据库操作,必须在数据库层由 存储过程实现(就笔者工作所面向的金融行业而言,工商银行、中国银行、交 通银行,都在开发规范中严格指定) 3. 系统数据处理量...

    【计算机软件毕业设计】二手车交易平台的分析、设计与实现文献综述1.doc

    文献综述 摘 要 Web开发技术和Web开发框架整合实践研究是这个时代的一个热点,本文在参阅国内 外Web开发技术和Web开发框架及... Raible学者认为,Hibernate是一个面对Java环境的对象/关系数据库映射工具, 它对JDBC进

    本科毕业设计开题报告(计算机协会信息管理系统的设计与实现V5)

    本系统使用的开发语言是Java语言,Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台、科学超级计算机...

    JAVA上百实例源码以及开源项目

    在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天...

    JAVA上百实例源码以及开源项目源代码

    在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天...

    java开源包1

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包11

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包2

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包3

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

Global site tag (gtag.js) - Google Analytics