日期:2014-05-16  浏览次数:20567 次

DAO开发模式
DAO开发模式介绍
学术部   张亚涛
2008-8-28


一 .有关DAO模式的介绍

业务对象只应该关注业务逻辑,不应该关心数据存取的细节。数据访问对象必须实现特定的持久化策略(如,基于JDBC或Hibernate的持久化逻辑), 这样就抽出来了DAO层,作为数据源层,而之上的Domain Model层与之通讯而已,如果将那些实现了数据访问操作的所有细节都放入高层Domain model(领域模型)的话,系统的结构一定层次上来说就变得有些混乱。低级别的数据访问逻辑与高级别的业务逻辑分离,用一个DAO接口隐藏持久化操作的 细节,这样使用的最终目的就是让业务对象无需知道底层的持久化技术知识,这是标准 j2ee 设计模式之一。一个典型的的DAO组成:DAO工厂类,DAO接口,实现DAO接口的具体类(每个 DAO 实例负责一个主要域对象或实体),VO(Value Object)。如果一个DAO 工厂只为一个数据库的实现(现在只考虑这种情况)而创建很多的DAO的时候,实现该策略时,我们考虑采用工厂方法设计模 式.

二.设计DAO要注意的问题

在采用这种工厂方法设计模式来实现时我们其实要注意很多问题,哪个对象负责开始事务,哪个负责事务结束?DAO 是否要负责事务的开始和结束? 应用程序是否需要通过多少个DAO访问数据?事务涉及一个DAO还是多个DAO?一个DAO是否调用另一个DAO的方法?了解上述问题的答案将有助于我们 选择最适合的 DAO 的事务界定策略。在 DAO 中有两种主要的界定事务的策略。一种方式是让 DAO 负责界定事务,另一种将事务界定交给调用这个 DAO 方法的对象处理。如果选择了前一种方式,那么就将事务代码嵌入到 DAO 中。如果选择后一种方式,那么事务界定代码就是在 DAO 类外面,在这里我将用<<Hibernate项目开发宝典>>中留言版的小例子来理解后一种工作方式是如何工作的,以及如何自己 实现一个类似Spring的IOC轻量级容器中Bean工厂的功能(当然是没有使用Spring应用程序框架的情况下,对于这个简单的例子来说更有助于我 们理解Spring的DI模式)。这个小实例所要实现的业务功能包括创建用户,用户登录,发表文章,浏览文章,修改文章和删除文章,所以有两个对应的实体 对象User,Message。本文不涉及到业务逻辑,以及显示层部分。

三.DAO的实现

  DAO 模式对开发J2EE应用的人员来说都应该很熟悉的,但是模式的实现各不相同,在这里我将按下面的思路来实现:
1.系统中的所有数据库访问都通过 DAO 进行以实现封装。
2.每个 DAO 实例负责一个主要域对象或实体。
      3.DAO 负责域对象的创建、读取(按主键)、更新和删除(CRUD)。
4.DAO 可允许基于除主键之外的标准进行查询,返回值通常是DAO 负责的域对象集合。
  5.像上面说的,DAO 不负责处理事务、会话或连接,而把这交给一个工具类,这样做是为了实现灵活性。
     (一)泛型 DAO 接口
  泛型 DAO 的基础是其 CRUD 操作。下面的接口定义泛型 DAO 的方法:
  提供数据库操作接口给业务层使用
       清单1
public interface IMessageDAO
{
//对应留言信息Message这个实体对象的操作
public void saveMessage( Message message );
public void updateMessage( Message message );
public List getMessages( );
public void deleteMessage( String id, String userId );
public Message getMessage( String id );
}
     清单2
  public interface IUserDAO
       {
       public void saveUser( User user );
       public User getUser( String username );
      public User getUserById( String id );
      }
    (二)泛型DAO的实现
第一个泛型 DAO 的实现
DAO 的实现类,封装数据库逻辑,按<<Hibernate项目开发宝典>>书上所说的将那些持久化操作封装到一个DAO基础类,也相 当于是一个工具类,通过继承这个基础类,DAO的实现类可以在很大程度上简化持久化操作的步骤,减少代码的重复量。这个基础类命名为 HibernateDAO,具体的方法实现如清单2
清单 3.

/**
* 使用Hibernate实现DAO的基础类
* 包括了持久化操作的一些基础方法
*/
public class HibernateDAO
{
/**
* 保存对象信息到数据库
* @param obj 需要进行持久化操作的对象
*/
public void saveObject(Object obj)
{
   HibernateUtil.getCurrentSession().save(obj);
}
/**
* 更新持久化对象
* @param obj 需要更新的对象
*/
public void updateObject(Object obj)
{
   HibernateUtil.getCurrentSession().update(obj);
}
/**
* 使用HQL语句进行查询
* @param hsql 查询语句
* @return 符合条件的对象集合
*/
public List getObjects(String hsql)
{
   List result = HibernateUtil.getCurrentSession().createQuery(hsql).list();
   return result;
}
/**
* 使用HQL语句进行对象的查询
* @param hsql 查询语句
* @return 符合条件的对象
*/
public Object getObject(String hsql)
{
   Object result = HibernateUtil.getCurrentSession().createQuery(hsql).uniqueResult();
   return result;
}
/**
* 根据ID值得到持久化的对象
* @param cls 对象的类型
* @param id ID值
* @return 指定ID的对象
*/
public Object getObject(Class cls, String id)
{
   Object result = HibernateUtil.getCurrentSession().get(cls, id);
   return result;
}
/**
* 删除对象信息
* @param obj 被删除的对象
*/
public void deleteObject(Object obj)
{
   HibernateUtil.getCurrentSession().delete(obj);
}
}
清单 4. IMessage