`
insky
  • 浏览: 38207 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

阅读更多

我的BaseDAO如下:

java 代码
  1. public class BaseDAO<t></t>   
  2. {   
  3.        
  4.     Session session;   
  5.            
  6.        
  7.     /**  
  8.      * @author   insKy  
  9.      * @time     2007-6-17  下午03:06:17  
  10.      * @version  1.0  
  11.      * @param t  
  12.      */  
  13.        
  14.   
  15.         public void create (T t) {   
  16.          try {   
  17.              session = SessionFactory.getSession();   
  18.              Transaction tx = session.beginTransaction();   
  19.                          session.save( t );   
  20.   
  21.              session.flush();   
  22.              tx.commit();   
  23.                     }catch(HibernateException e){   
  24.                 throw e;   
  25.             }finally{   
  26.           }   
  27.     }   
  28.     //update delete操作类似 此处代码略     
  29.     public void update (T t)   
  30.     public void delete(T t)   
  31. }  

 

其余Dao继承这个BaseDAO:

java 代码
  1. public class ColumnsDAO extends BaseDAO{   
  2.        
  3. //某些操作。。。  此处不显式调用父类的creat函数   
  4. }  
ColumnsAction中调用ColumnsDAO的create函数完成增加操作
  
然而Dao中出现事务操作是不合适的,所以这里想分出BO层处理session以及事务的处理,修改完后的BaseBO应该大体如下:
java 代码
  1. public void create (T t) {   
  2.          try {   
  3.              session.save( t );   
  4.               }catch(HibernateException e){   
  5.                 throw e;   
  6.             }finally{   
  7.           }   
  8.     }  

我的问题是

1,对应的BO应该如何处理?BaseDAO中的session应该如何获取?BO中如何传递过来?(没用Spring之用到Struts+Hibernate)session的获取是SessionFactory通过ThreadLocal获取的
//看了别人的程序,感觉如果用Spring来管理,不会遇到这些问题,这里没用Spring改如何来最好的管理session的传递?

2,是否也应该写一个BaseBO来对应处理BaseDAO中的各个操作以避免每个BO中处理crud操作?
请各位指教

分享到:
评论
23 楼 zzm_fly2004 2008-03-30  
不知道可以不可以用类似与sping的opensessioninview的方式,在过滤器中打开session,把这个session用ThreadLocal保存起来,在本次请求方法内都任何地方都可以使用!具体实现可能大家都会了,这里就只说一下思路,呵呵,不知道可以否!!!!
22 楼 kakaluyi 2008-03-28  
用动态代理 在你的getlist的方法用动态代理包装下,加入事务
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.hibernate.*

import com.strutslet.demo.service.SystemException;

public final class TransactionWrapper {

/**
* 装饰原始的业务代表对象,返回一个与业务代表对象有相同接口的代理对象
*/
public static Object decorate(Object delegate) {
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), new XAWrapperHandler(
delegate));
}

//动态代理技术
static final class XAWrapperHandler implements InvocationHandler {
private final Object delegate;

XAWrapperHandler(Object delegate) {
this.delegate = delegate;
}

//简单起见,包装业务代表对象所有的业务方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
session = SessionFactory.getSession();
try {
//开始一个事务
Transaction tx = session.beginTransaction();  
//调用原始业务对象的业务方法
result = method.invoke(delegate, args);
session.flush();   
tx.commit();
} catch (Throwable t) {
//回滚
ta.rollback();
throw new SystemException(t);
}

return result;
}
}
}
bo层事务就不用写了直接写个工厂,return
TransactionWrapper.decorate(new ColumnsDao())
这样就生成把事务封装进去的Dao了,如果不用事务也行,工厂类直接返回不事务处理的dao,我觉的可行
21 楼 cindy_taozhiang 2008-03-28  

晕掉.  楼上的在做什么

看的让我茫然了.  难道非Spring不行了?

20 楼 yl3118436 2007-07-25  
<html><head><title>2222222</title></head><body>123123</body></html>
19 楼 yl3118436 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{    
          }    
     }
18 楼 yl3118436 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{   
      }   
17 楼 yl3118436 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{   
      }   
16 楼 kafka0102 2007-07-20  
johnl 写道
动态代理如何?


简单的情况下可行。可以对Service做动态代理,统一管理事务的开启和关闭(诚如Spring的AOP实现)。然后通过工厂模式向上提供访问Service的接口。
15 楼 kafka0102 2007-07-20  
我想楼主真的应该用用Spring。在传统的三层架构下,DAO中的操作应该是单元性的;也就说,一个DAO对应一个领域对象(在事务脚本中就是一个DAO对应一个DTO)。而业务层的领域服务(似乎大家也称为业务对象)并不是和DAO一一对应的,因此会出现一个Service方法中包含多个DAO操作。因此,事务控制不应该在DAO层而是在Service层。但是,事务管理本身是与业务无关的横切性功能,因此使用Spring的声明式事务管理是很好的选择。在没有Spring的情况下,可以自己写一个简单的事务管理工具(但这样也是要代码耦合的,但比起在Service调用Hibernate代码要好很多)。如果是web程序,可以考虑Open Session in View,这样就是每个web请求一个事务了,也不用将事务代码耦合在Service中。
14 楼 johnl 2007-07-20  
动态代理如何?
13 楼 insky 2007-07-06  
<div class='code_title'>
<p>我现在<font>修改后的Dao中完全不包含事务处理操作    如下ColumnsDAO中某一个函数</font></p>
<p>ColumnsDAO:</p>
</div>
<div class='code_title'> </div>
<div class='code_title'>java 代码</div>
<div class='dp-highlighter'>
<div class='bar'/>
<ol class='dp-j'>
    <li class='alt'><span><span class='keyword'>public</span><span> </span><span class='keyword'>class</span><span> ColumnsDAO </span><span class='keyword'>extends</span><span> BaseDAO{   </span></span></li>
    <li class=''><span>     Session session;   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>     </span><span class='keyword'>public</span><span> ColumnsDAO(){   </span></li>
    <li class='alt'><span>         </span><span class='comment'>//something need to be done </span><span>  </span></li>
    <li class=''><span>     }   </span></li>
    <li class='alt'><span>        </span></li>
    <li class=''><span>     </span><span class='keyword'>public</span><span> ColumnsDAO(Session session){   </span></li>
    <li class='alt'><span>         </span><span class='keyword'>this</span><span>.session=session;   </span></li>
    <li class=''><span>     }   </span></li>
    <li class='alt'><span>            </span></li>
    <li class=''><span>     </span><span class='comment'>//示例函数  </span><span>  </span></li>
    <li class='alt'><span>         </span><span class='keyword'>public</span><span> List&lt;Columns&gt; getColList1() </span><span class='keyword'>throws</span><span> HibernateException {   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>      </span><span class='keyword'>try</span><span> {   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>       String hql = </span><span class='string'>"from ....."</span><span>;   </span></li>
    <li class=''><span>       List&lt;Columns&gt; ColList=session.createQuery(hql)   </span></li>
    <li class='alt'><span>        .list();   </span></li>
    <li class=''><span>       </span><span class='keyword'>return</span><span> ColList;   </span></li>
    <li class='alt'><span>      }</span><span class='keyword'>catch</span><span>(HibernateException e){   </span></li>
    <li class=''><span>       </span><span class='keyword'>throw</span><span> e;   </span></li>
    <li class='alt'><span>      }</span><span class='keyword'>finally</span><span>{   </span></li>
    <li class=''><span>      }   </span></li>
    <li class='alt'><span>     }   </span></li>
    <li class=''><span>}  </span></li>
</ol>
</div>
<font>事务操作都放在对应BO中处理,如ColumnsBO对应的函数</font>
<p> ColumnsBO:</p>
<div class='code_title'>java 代码</div>
<div class='dp-highlighter'>
<div class='bar'/>
<ol class='dp-j'>
    <li class='alt'><span><span class='keyword'>public</span><span>  List&lt;Columns&gt; getColList1(){   </span></span></li>
    <li class=''><span>         session = SessionFactory.getSession();   </span></li>
    <li class='alt'><span>         Transaction tx = session.beginTransaction();   </span></li>
    <li class=''><span>         colDao = </span><span class='keyword'>new</span><span> ColumnsDAO(session);   </span></li>
    <li class='alt'><span>         </span><span class='keyword'>try</span><span> {   </span></li>
    <li class=''><span>             List&lt;Columns&gt; colList = </span><span class='keyword'>new</span><span> ArrayList&lt;Columns&gt;();   </span></li>
    <li class='alt'><span>             colList = colDao.getColList1();   </span></li>
    <li class=''><span>             tx.commit();   </span></li>
    <li class='alt'><span>             </span><span class='keyword'>return</span><span> colList;   </span></li>
    <li class=''><span>          }</span><span class='keyword'>catch</span><span>(HibernateException e){   </span></li>
    <li class='alt'><span>           </span><span class='keyword'>throw</span><span> e;   </span></li>
    <li class=''><span>          }</span><span class='keyword'>finally</span><span>{   </span></li>
    <li class='alt'><span>          }   </span></li>
    <li class=''><span>     }  </span></li>
</ol>
</div>
<p> <font>为了保证可以使用延迟加载,session的关闭不是在BO或Dao中而是放到过滤器中,只要请求一个新的action就关闭掉session。这样问题就来了,我在某一BO的方法中需要调用其他BO的方法或者多个Dao的方法时session就都没有关闭,不是引起No row with the given identifier exists:就是出现Null错误。这种情况改如何处理?session是否要单独处理?</font></p>
12 楼 yhb_4323 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();
 } 


我也是刚刚在项目中使用,我在网吧发帖,所以这段代码没有在编辑器中调试,希望你能理解到我想说什么。
11 楼 insky 2007-07-03  
cnpollux 写道
异常为什么要这样处理呢?
# catch(HibernateException e){  
#        throw e;  
#       }

这里只是想说明BaseDao是否处理得当的问题,没太注意异常,实际代码中是由上层专门异常类来捕获处理的,您说这里是应该如何处理?
10 楼 insky 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) {
}方法呢?   
9 楼 cnpollux 2007-07-02  
异常为什么要这样处理呢?
# catch(HibernateException e){  
#        throw e;  
#       }
8 楼 pypcjs 2007-06-26  
请看这篇文章《不要重复DAO》
http://www.ibm.com/developerworks/cn/java/j-genericdao.html
7 楼 insky 2007-06-25  
晕...发现所有范型有关的尖括号都被过滤掉了
6 楼 insky 2007-06-25  
<div class='code_title'>java 代码</div>
<p>其实我的主要疑问是当Dao中的session,事务操作都放到BO中后,BaseDao的crud操作改如何处理?是否也写个BaseBO做对应的操作?</p>
<p>其余的dao方法很容易处理,比如我ColumnsDao中有个取出所有一级栏目的操作<font>getColList1()方法,改写后ColumnsDao对应的方法如下:</font></p>
<div class='code_title'>java 代码</div>
<div class='dp-highlighter'>
<div class='bar'/>
<ol class='dp-j'>
    <li class='alt'><span><span class='keyword'>public</span><span> List&lt;Columns&gt; getColList1() </span><span class='keyword'>throws</span><span> HibernateException {   </span></span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>      </span><span class='keyword'>try</span><span> {   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>       String hql = </span><span class='string'>"from Columns where parentColumn is null and colStatus=1 order by colOrder"</span><span>;   </span></li>
    <li class=''><span>       List&lt;Columns&gt; Collist=session.createQuery(hql)   </span></li>
    <li class='alt'><span>        .list();   </span></li>
    <li class=''><span>       </span><span class='keyword'>return</span><span> Collist;   </span></li>
    <li class='alt'><span>      }</span><span class='keyword'>catch</span><span>(HibernateException e){   </span></li>
    <li class=''><span>       </span><span class='keyword'>throw</span><span> e;   </span></li>
    <li class='alt'><span>      }</span><span class='keyword'>finally</span><span>{   </span></li>
    <li class=''><span>      }   </span></li>
    <li class='alt'><span>     }  </span></li>
</ol>
</div>
<p> </p>
<p>对应ColumnsBO如下:</p>
<div class='code_title'>java 代码</div>
<div class='dp-highlighter'>
<div class='bar'/>
<ol class='dp-j'>
    <li class='alt'><span><span>Session session;   </span></span></li>
    <li class=''><span> ColumnsDAO colDao;   </span></li>
    <li class='alt'><span> </span><span class='keyword'>public</span><span> List&lt;Columns&gt; getColList1(){   </span></li>
    <li class=''><span>     session = SessionFactory.getSession();   </span></li>
    <li class='alt'><span>     Transaction tx = session.beginTransaction();   </span></li>
    <li class=''><span>     colDao = </span><span class='keyword'>new</span><span> ColumnsDAO(session);   </span></li>
    <li class='alt'><span>     </span><span class='keyword'>try</span><span> {   </span></li>
    <li class=''><span>         List&lt;Columns&gt; colList = </span><span class='keyword'>new</span><span> ArrayList&lt;Columns&gt;();   </span></li>
    <li class='alt'><span>         colList = colDao.getColList1();   </span></li>
    <li class=''><span>         tx.commit();   </span></li>
    <li class='alt'><span>         </span><span class='keyword'>return</span><span> colList;   </span></li>
    <li class=''><span>      }</span><span class='keyword'>catch</span><span>(HibernateException e){   </span></li>
    <li class='alt'><span>       </span><span class='keyword'>throw</span><span> e;   </span></li>
    <li class=''><span>      }</span><span class='keyword'>finally</span><span>{   </span></li>
    <li class='alt'><span>      }   </span></li>
    <li class=''><span> }  </span></li>
</ol>
</div>
<p>这样似乎很顺畅,但是遇到BaseDao里的crud方法,因为ColumnsDao根本就没出现过crud方法,ColumnsBO该如何处理?也写个BaseBO对应处理BaseDao的方法?感觉怪怪的...</p>
<p>BTW:不知道我是否能把我的意思表达清楚,语言表达能力有限,给各位舔堵了:(</p>
5 楼 insky 2007-06-25  
yongyuan.jiang 写道
BaseDao后还需要各自entity的dao,写代码不写死了,要是有20个类,还得去copy 20个xxxDAO?

何不直接使用一个BaseDao,提供save,delete,update,query,findById方法。

使用:
User user = (User)baseDao.findById('123');

不知道您是否没仔细看,或者是我的代码没表达清楚我的意思,我的BaseDao中已经提供了crud方法,写BaseDao就是为了其余entity的dao中避免copy重复的crud方法
比如ColumnAction中直接调用ColumnDao的creat方法(继承父类BaseDao)就可以,而不用再在ColumnDao处理crud方法
4 楼 yongyuan.jiang 2007-06-25  
BaseDao后还需要各自entity的dao,写代码不写死了,要是有20个类,还得去copy 20个xxxDAO?

何不直接使用一个BaseDao,提供save,delete,update,query,findById方法。

使用:
User user = (User)baseDao.findById('123');

相关推荐

    Bo-Blog daodao

    4. **模板引擎**:为了方便用户自定义博客外观,Bo-Blog daodao 可能内置了模板引擎,如Smarty,允许用户通过修改模板文件来调整页面布局和样式,无需深入理解PHP代码。 5. **用户认证与权限管理**:一个完整的博客...

    java术语(PO/POJO/VO/BO/DAO/DTO)

    BO会调用DAO来与数据库进行交互,处理复杂的业务流程。BO是业务逻辑和数据访问的桥梁,它的设计和实现直接影响到系统的可维护性和可扩展性。 5. DAO(Data Access Object,数据访问对象) DAO是一种设计模式,它...

    java BO类和Dao类代码生成器

    Java中的Business Object(BO)类和Data Access Object(DAO)类是软件开发中常见的设计模式,主要用于处理业务逻辑和数据库交互。BO类通常封装了业务逻辑,而DAO类则负责与数据库进行通信,实现了数据的增删查改...

    java-DAO分层解析.pdf

    Java DAO分层是一种常见的软件设计模式,用于组织和分离应用程序中的数据访问逻辑。在这个模式中,我们通常将系统划分为四个主要层次:显示层、控制层、业务层和数据层。下面将详细解释这些层次以及DAO设计模式在...

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    Java利用Freemarker模板自动生成dto、dao、rowmapper、bo、service代码

    本主题涉及的核心技术是使用Freemarker模板引擎来生成DTO(Data Transfer Object)、DAO(Data Access Object)、RowMapper、BO(Business Object)和服务层代码。这些组件在Spring框架中扮演着重要角色。 1. **...

    生成bo,dao,mapping java工具类

    "生成bo,dao,mapping Java工具类" 是一种自动化代码生成的解决方案,它可以帮助开发者快速构建数据访问层的基础架构,包括Business Object (BO),Data Access Object (DAO)以及MyBatis的Mapper映射文件。...

    Java的(PO,VO,TO,BO,DAO,POJO)解释

    "Java的(PO,VO,TO,BO,DAO,POJO)解释" Java作为一门流行的编程语言,在软件开发中扮演着重要角色,其中一些关键概念和技术为开发者提供了方便快捷的开发体验。本篇文章将对Java中的PO、VO、TO、BO、DAO、POJO等概念...

    VO / DTO / BO / ORM DAO entity DO PO/ POJO(分层领域模型规约)整理

    本文将详细介绍VO (View Object)、DTO (Data Transfer Object)、BO (Business Object)、ORM (Object Relational Mapping)、DAO (Data Access Object)、Entity (实体)、DO (Data Object)、PO (Persistent Object)、...

    java(PO,VO,BO,DAO,POJO)Explained Collection

    BO会调用DAO来操作数据,并结合PO和VO来完成业务处理。BO包含了业务处理的复杂性,如事务管理、业务规则验证等。 4. POJO(简单无规则Java对象): POJO是最基础的Java Bean,它没有任何特定的框架或规范约束,只有...

    Java的几种对象(PO-VO-DAO-BO-POJO)解释

    ### Java的几种对象详解:PO-VO-DAO-BO-POJO #### 一、PO:Persistant Object(持久对象) 持久对象(Persistent Object,简称PO),主要用于与数据库中的表进行映射。一个简单的PO对象可以代表数据库表中的一条...

    应用分层及规约

    应用分层及规约的知识点涉及软件架构中的分层概念和各层之间的依赖关系,异常处理规约,以及分层领域模型规约。以下是对这些概念的详细阐述: ### 应用分层 在软件开发中,应用分层是一种常见的设计模式,它将应用...

    BO安装、配置&报表制作培训

    "BO安装、配置&报表制作培训" BO安装、配置&报表制作培训是Business Objects(BO)的一系列培训课程,旨在帮助用户掌握BO的安装、配置和报表制作技能。本培训课程涵盖了BO的安装、配置、报表设计和开发等方面的知识...

    关于VO、PO的理解——java的(PO,VO,TO,BO,DAO,POJO)解释

    "关于VO、PO的理解——java的(PO,VO,TO,BO,DAO,POJO)解释" 在 Java 中,PO、VO、TO、BO、DAO、POJO 是六个重要的概念,它们之间存在着紧密的关系,本文将对它们进行详细的解释。 首先,PO(Persistent Object)是...

    vo bo po dto dao区别

    本人以前搞不懂这些o的区别,特意查找资料总结了一下,希望也可以帮到其他人

    java DAO学习

    Java DAO(Data Access Object)模式是一种常见的设计模式,主要用于封装对数据库的操作,使得业务逻辑与数据访问代码分离...学习DAO模式有助于初学者理解如何在Java中构建分层架构,提高软件设计的灵活性和可扩展性。

Global site tag (gtag.js) - Google Analytics