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

来源:互联网 发布:大神码字软件 编辑:程序博客网 时间:2024/04/29 11:53

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

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


下面面向对象的方法:

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

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

2 Hibernate

使用Hql

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

 
    select productid, name, descn, category from product
   
     
        lower(name) like #keywordList[]# OR lower(category) like #keywordList[]# OR lower(descn) like #keywordList[]#
     

   

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 xxx = getAnnotation(Class 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();

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

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




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 数学大题不会做怎么办 小学六年级数学考30分怎么办 六年级数学考了30分怎么办 数学考了30分怎么办 没有给直接领导报到怎么办 小学二年级成绩不好怎么办 初中孩子上课注意力不集中怎么办 学生打架家长争吵老师怎么办 我和我老婆感情危机怎么办 数学作业做得慢怎么办 待转弯区变红灯怎么办 大班健康发生火灾怎么办教案 数字化审图图纸提交不了怎么办 监狱建筑师没电了怎么办 ios短信提示不弹出怎么办 ie游览器图标删了怎么办 电脑上ie卸载了怎么办 打开cad浏览器闪退怎么办 dnf进游戏闪退怎么办 苹果8出现闪退怎么办 手机浏览器老是自动打开软件怎么办 打开手机浏览器为什么是英文怎么办 ie浏览器删除掉了怎么办 手机360浏览器卸载不掉怎么办 大学素质拓展学分不够怎么办 专升本学分不够怎么办 电脑连接无线网络网关禁用怎么办 背部毛孔粗大有黑头怎么办 毛孔变粗大长痘怎么办 皮肤粗糙暗黄毛孔大怎么办 毛孔粗大还有痘印怎么办 高一的不爱上数学怎么办 监狱系统需要体测怀孕怎么办 货运从业资格证年审过期了怎么办 科三线路记不住怎么办? 汽车大灯里面起雾水怎么办 二级重伤对方法庭拒绝赔偿怎么办? 在麦当劳工作收到假钞怎么办 东西湖小学分配太远怎么办 农行k令过期了怎么办 穿军训的鞋捂坏了怎么办