论坛首页 Java企业应用论坛

BO,DAO如何来分层清晰以及Session何处关闭的问题

浏览 16901 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-07-03  
pypcjs 写道
请看这篇文章《不要重复DAO》
http://www.ibm.com/developerworks/cn/java/j-genericdao.html

又仔细看了下这篇,有地方还是有点模糊:
===============
泛型 DAO 接口

public interface GenericDao <T, PK extends Serializable> {
T read(PK id);

。。。。
}

第一个泛型 DAO 实现

public class GenericDaoHibernateImpl <T, PK extends Serializable>
    implements GenericDao<T, PK>, FinderExecutor {
    private Class<T> type;

    public GenericDaoHibernateImpl(Class<T> type) {   《===这里type从哪里获取?
        this.type = type;   
    }

public T read(PK id) {
        return (T) getSession().get(type, id);  《===这里的type如何获取的?初始化GenericDaoHibernateImpl 要指明T的类型吗?应该不用吧?
    }

}
============================
参考了江南白衣的文章  可以写成:
public GenericHibernateDAO() {
        this.clazz = (Class<E>) ((ParameterizedType) getClass()
                                                         .getGenericSuperclass()).getActualTypeArguments()[0];
    }
我加到我的BaseDao中报错 取不到正确类型

究竟如何才能在BaseDao中轻松的实现 public T read(PK id) {
}方法呢?   
0 请登录后投票
   发表时间:2007-07-03  
cnpollux 写道
异常为什么要这样处理呢?
# catch(HibernateException e){  
#        throw e;  
#       }

这里只是想说明BaseDao是否处理得当的问题,没太注意异常,实际代码中是由上层专门异常类来捕获处理的,您说这里是应该如何处理?
0 请登录后投票
   发表时间:2007-07-03  
cnpollux 写道
异常为什么要这样处理呢?
# catch(HibernateException e){  
#        throw e;  
#       }


这是数据层的操作,为的是向上抛出异常,让业务层捕捉,然后来处理。
楼主说的应该是三层结构,论坛有过这样的帖子。

我的理解是,封装数据层(持久层),数据层只对数据进行操作,不管理业务关系。

以增加用户为例子:
类名: UserDAO.java (User表DAO)
数据层的方法: public List findByUsername(String userName) throws Expection;
             public void save(User user) throws Expection;
类名:SysBO.java (系统管理员BO)
业务层的方法: public boolean addUser(String userName,String Password) throws
ExistExpection,AddExpection;

下面简单的写下业务层的代码:
 try{
     List l = userDAO.findByUsername(userName);
     if(l==null||l.size()>0) throw new ExistExpection();
     User u = new User();
     u.setUsername("admin");
     u.setPassword("admin888");
     userDAO.save(u);
 }catch(Expection e){
     throw new AddExpection();
 } 


我也是刚刚在项目中使用,我在网吧发帖,所以这段代码没有在编辑器中调试,希望你能理解到我想说什么。
0 请登录后投票
   发表时间:2007-07-06  

我现在修改后的Dao中完全不包含事务处理操作    如下ColumnsDAO中某一个函数

ColumnsDAO:

 
java 代码
  1. public class ColumnsDAO extends BaseDAO{   
  2.      Session session;   
  3.   
  4.      public ColumnsDAO(){   
  5.          //something need to be done   
  6.      }   
  7.         
  8.      public ColumnsDAO(Session session){   
  9.          this.session=session;   
  10.      }   
  11.             
  12.      //示例函数    
  13.          public List<Columns> getColList1() throws HibernateException {   
  14.   
  15.       try {   
  16.   
  17.        String hql = "from .....";   
  18.        List<Columns> ColList=session.createQuery(hql)   
  19.         .list();   
  20.        return ColList;   
  21.       }catch(HibernateException e){   
  22.        throw e;   
  23.       }finally{   
  24.       }   
  25.      }   
  26. }  
事务操作都放在对应BO中处理,如ColumnsBO对应的函数

 ColumnsBO:

java 代码
  1. public  List<Columns> getColList1(){   
  2.          session = SessionFactory.getSession();   
  3.          Transaction tx = session.beginTransaction();   
  4.          colDao = new ColumnsDAO(session);   
  5.          try {   
  6.              List<Columns> colList = new ArrayList<Columns>();   
  7.              colList = colDao.getColList1();   
  8.              tx.commit();   
  9.              return colList;   
  10.           }catch(HibernateException e){   
  11.            throw e;   
  12.           }finally{   
  13.           }   
  14.      }  

 为了保证可以使用延迟加载,session的关闭不是在BO或Dao中而是放到过滤器中,只要请求一个新的action就关闭掉session。这样问题就来了,我在某一BO的方法中需要调用其他BO的方法或者多个Dao的方法时session就都没有关闭,不是引起No row with the given identifier exists:就是出现Null错误。这种情况改如何处理?session是否要单独处理?

0 请登录后投票
   发表时间:2007-07-20  
动态代理如何?
0 请登录后投票
   发表时间:2007-07-20  
我想楼主真的应该用用Spring。在传统的三层架构下,DAO中的操作应该是单元性的;也就说,一个DAO对应一个领域对象(在事务脚本中就是一个DAO对应一个DTO)。而业务层的领域服务(似乎大家也称为业务对象)并不是和DAO一一对应的,因此会出现一个Service方法中包含多个DAO操作。因此,事务控制不应该在DAO层而是在Service层。但是,事务管理本身是与业务无关的横切性功能,因此使用Spring的声明式事务管理是很好的选择。在没有Spring的情况下,可以自己写一个简单的事务管理工具(但这样也是要代码耦合的,但比起在Service调用Hibernate代码要好很多)。如果是web程序,可以考虑Open Session in View,这样就是每个web请求一个事务了,也不用将事务代码耦合在Service中。
0 请登录后投票
   发表时间:2007-07-20  
johnl 写道
动态代理如何?


简单的情况下可行。可以对Service做动态代理,统一管理事务的开启和关闭(诚如Spring的AOP实现)。然后通过工厂模式向上提供访问Service的接口。
0 请登录后投票
   发表时间:2007-07-25  
Session session;   
ColumnsDAO colDao;   
public List getColList1(){   
     session = SessionFactory.getSession();   
     Transaction tx = session.beginTransaction();   
     colDao = new ColumnsDAO(session);   
     try {   
         List colList = new ArrayList();   
         colList = colDao.getColList1();   
         tx.commit();   
         return colList;   
      }catch(HibernateException e){   
       throw e;   
      }finally{   
      }   
0 请登录后投票
   发表时间:2007-07-25  
Session session;   
ColumnsDAO colDao;   
public List getColList1(){    session = SessionFactory.getSession();     Transaction tx = session.beginTransaction();   
     colDao = new ColumnsDAO(session);   
     try {  List colList = new ArrayList();   
         colList = colDao.getColList1();   
         tx.commit();   
         return colList;   
      }catch(HibernateException e){   
       throw e;   
      }finally{   
      }   
0 请登录后投票
   发表时间:2007-07-25  
public  List getColList1(){    
         session = SessionFactory.getSession();    
         Transaction tx = session.beginTransaction();    
         colDao = new ColumnsDAO(session);    
         try {    
             List colList = new ArrayList();    
             colList = colDao.getColList1();    
             tx.commit();    
             return colList;    
          }catch(HibernateException e){    
           throw e;    
          }finally{    
          }    
     }
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics