`
tczengjin
  • 浏览: 12772 次
  • 来自: ...
社区版块
存档分类
最新评论

有了hibernate是否还需要Dao?

阅读更多
最近学习使用Struts2+Hibernate,也是分层,web层里放Struts2的action
service层里放业务逻辑对象,持久层里放的是dao+po,对po操作基本放到了dao里,可以我不解的是使用Hibernate的方法我返回本身就是po,为什么大家写程序的时候还写dao呢?我的dao里对po的操作几乎把它细分到了一个方法仅仅一次crud,我通过调用不同的dao里多次方法来实现业务中需要对不同的po进行多次的crud操作的情况,每调用一次dao的一个方法开个session然后对po进行一次crud操作又关session,那么session的缓存不是基本没什么作用了吗?还有一个问题就是通常po对应了一dao又对应了一service,我的dao的方法分的比较细(一个方法仅仅对po进行一次crud),我感觉我的service里仅仅只是重复调用了一遍dao的方法,然后在action中调用service层里不同的service对象实现稍微复杂的业务,我想过是不是service是用来把不同的dao的方法结合起来实现业务中需要对不同的po进行多次的crud操作的情况?这样在action中只要调用service中的方法那action里的代码就清爽了。但是我的action我也分的比较的细,一个action只针对用户的一步操作(多步操作可以用action chain串起来),一个页面可以有不同的action为用户不同的请求服务,action也是根据用户的一步操作命的名,我觉得根本不要把对action的多次操作的这样的业务放到service中,我想去掉service层直接在action中调用dao,原因是我的action是根据用户的一步业务操作命名,作为业务逻辑也好理解,几步操作可以用action chain,原因二是少了service层不用把数据又传到service层再调用一遍,原因三按照 黑体部分(见上面) 的考虑service到是有事情干了,可action干什么呢,难道是为了调service而存在的吗??关于web+service+dao+po这样的分层大家能能简单的说明下那三层究竟各负责什么,另外我知道要根据项目的具体情况合理分层,但我始终不明白service层的具体作用。
归纳下我的疑问:
1使用Hibernate的方法我返回本身就是po,为什么大家写程序的时候还写dao呢?我的dao里对po的操作几乎把它细分到了一个方法仅仅一次crud,每个方法一开session一关session,session的缓存不是几乎形同虚设了吗?
2我的web层的action我也分的比较的细,一个action只针对用户的一步操作(多步操作可以用action chain串起来),是否还需要service层?为什么?
3web(细,struts2支持按namespace对action划分)+service(使用Hibernate实现业务逻辑,稍复杂业务逻辑可以对不同po crud多次可以利用到session缓存)+po 一般情况的项目是不是这样分层更好一些呢?
分享到:
评论
29 楼 xmlspy 2008-01-05  
有这么个业务:
页面传来一个user_id,通过这个userId查找这个用户父亲的user_id(字段为f_id),然后获得父亲的所有图书.
我项目中的做法:
dao中方法,
//1.通过userId获得fId 
public String getFIdFromUserId(String userId);
//2.通过FId获得书籍
public List getBooksFromFId(String fId);

service中的方法
//1.通过userId获得fId 
public String getFIdFromUserId(String userId);
//2.通过FId获得书籍
public List getBooksFromFId(String fId);
//3.获得指定userId父亲的书籍
public List getBooks(String userId){
    调用方法1;
    调用方法2;
}


疑问: 大家写这种需求的代码的时候,是否也这样写?
当中的"获得指定userId父亲的书籍"方法,是否需要单独在dao中封装一个方法,使之减少对数据库的访问,访问一次就可以.
另外,dao和service层,很是令人郁闷,每次有新需求的时候,都要在dao中加个方法,然后再在service中加个调用dao中的方法,感觉是多此一举.
我曾经问过朋友能不能把dao或者service层去掉一个,朋友说和什么事务有关系,不能去掉

大家有什么看法?
28 楼 姑苏龙哥 2008-01-04  
<p>依次回答你的疑问:<br/>1.  DAO应该是细颗粒度的对持久数据的CRUD, Hibernate的API是最细颗粒度数据访问, 例如现在有这样一个需求<br/>:根据表现层传过来的一个订单号,查出这个订单下面的所有商品.你可能第一步会先得到某个订单;第二步根据配<br/>置好的一对多关联关系得到相关的商品集合.可以看到第一步属于数据访问逻辑,第二步依然是,并且两者在逻辑<br/>语义上属于一个数据访问逻辑(根据OrderId得到Order下的OrderItem List).我想你大概不想将这两步拆开来揉合<br/>到业务逻辑中去吧!所以DAO模式的主要作用就是封装对数据的访问和持久化,将数据访问和持久化逻辑从业务逻辑<br/>中解藕出来,从而实现了代码复用,也便于维护.<br/>    看到有人仍在用One Session Per Operation这种反模式,似乎又看到了当年的自己.你说的没有错,每次Session<br/>关闭后,Session级别的缓存确实失效了,如果你对于Session级别的缓存比较在意,不妨试试OPenSessionInView.但是<br/>这种模式也有一些问题,对于Hibernate Session和Transaction的管理众说纷纭,不知道目前有没有一个最优解决方案.</p><p> </p><p>2.  关于你对Action的描述和对Service层的疑问,我想说Action在本质上应该属于MVC中的C,在复杂的企业运算里,它<br/>最多可以算作一个控制器,控制业务的流程,而不应该将业务逻辑放入其中.为什么?对于将业务逻辑一概放入Action里,<br/>我将之称为"<span style='color: #ff0000;'>业务逻辑前移</span>",就是说业务逻辑层变"瘦"了,甚至没有了.这样,你的业务逻辑就跟具体的表现层框架<br/>强耦合在一起,无法达到业务逻辑的重用.如果下个项目(相同或相似的业务领域或行业)你们不用Struts,改用Webwork<br/>或者Tapstry作为展现层框架,你不得不重写业务逻辑.<br/>    关于你对位什么要有Service层的疑问.在受到Martin Fowler批评的Anemic Model中Service层主要的作用不外乎<br/>划分事务的边界,对Web层提供一个统一的Facade以供调用.在Rich Model 中除了上述的两个作用外,Service还和<br/>DomainObject协同封装业务逻辑.</p><p> </p><p>3.  在你的第3点中提到的分层方法,我称之为"<span style='color: #ff0000;'>业务逻辑后移</span>",当年我也写过.关于你的描述准确点讲应该是这样:<br/>Controller(Struts的Action)+ 贫血的DomainObject(哑数据容器)+DAO(封装了业务逻辑并在其前后包上Hibernate的<br/>Transaction).这样就将业务逻辑后移,移到了数据访问对象DAO中,这样业务逻辑就和具体的持久层框架强耦合在一起,<br/>无法重用,同时这种设计也违反了SRP(Single Responsibility Principle).<br/>    PS:如果我没记错的话,Apache的一个开源项目Roller好像就是用的这种架构.</p>
27 楼 ydw9527 2008-01-03  
我也是初学hibernate,顺便买了一本<深入浅出Hibernate>,书里就说了
1.一级缓存的出现可以抵消使用hibernate所带来额外的性能开销.    p222
2.在Hibernate的项目中使用DAO唯一的站得住脚理由就是抽象hibernate.    p343

但是如果使用了DAO+service,每次的service里的操作完成后就会调用session.close().这样就无法利用一级缓存了.这样是不是会非常影响性能呢?
26 楼 lonlyleo 2007-12-26  
考虑那么多做什么?

多分几层的,等你几个月后再回来维护系统就会觉得“挺好的”。

少分几层的,当老板只给你一天时间的时候也很爽嘛。

不想用过程(或者像我这样不会写过程)的,就会认为在Java代码里写业务逻辑是天经地义的,我很不喜欢把业务处理写到数据库的过程里面去,因为我不会写,也因为我喜欢数据库无关,哈哈。
25 楼 zhangfengsimon 2007-12-26  
moonranger 写道
我觉得设计DAO的重要原因是为了将持久化的实现与持久化接口分开。万一哪天你不用Hibernate了,DAO的接口还可以重用。而如果你直接使用Hibernate的话,你的业务逻辑层代码就和Hibernate耦合了。
这只是我肤浅的理解而已,呵呵~
24 楼 抛出异常的爱 2007-12-26  
flash 写道
这么多表相关的操作,为什么不用过程处理?为了方便数据库移植?
后加的需求.
23 楼 flash 2007-12-25  
这么多表相关的操作,为什么不用过程处理?为了方便数据库移植?
22 楼 抛出异常的爱 2007-12-25  
有的抽有的不抽
想找的时候....
你就慢慢跟吧.
PS:
引用

日志表,
权限表,
业务级联表,
操作记录表,

这几个操作可能是所有的crud都要有的.
21 楼 zbird 2007-12-25  
JAVAEYE抽风,发了两次。
删除。
20 楼 zbird 2007-12-25  
抛出异常的爱 写道
zbird 写道
就个人而言,我不喜欢DAO。
DAO不是万能药,解耦并不是加个DAO就能解决的问题。
对于大多的简单操作,Hibernate封得已经够完善了,大多时候加个DAO费力不讨好。
如果操作复杂,Service层过于混乱,这时候再抽取出个DAO也没什么不可以。
说到使用DAO解耦,大家最喜欢举的例子就是换实现。以前是说换数据库,现在Hiberate对数据库封得差不多了。于是说法改成将hibernate换成其他的实现,如jdbc等。
但真实项目中有谁有事没事的去换这些东西。
耦是有了才需要解的,如果凭空想出很多不实在的需求,无非是给自己自找麻烦。
我一直在说....
不是为了移植
而是为了管理方便

当然你可以把业务逻辑
与数据库逻辑写在一起
当只有一二个表时
并没什么不好解理
当一个操作关系到:
日志表,
权限表,
业务级联表,
操作记录表,

用人类的智力要从这么多的代码中找到逻辑.....还是差点意思

根据实际情况开看嘛,如果系统复杂那用DAO也没什么不可以。
但我确实见到过不少应用就是一个简单的管理界面,就一个CRUD也非得分这么多层,而且还分得乐此不彼的。
我就不知道这些基础的CRUD能有多少复杂的逻辑。
偶尔真出现那么一两个操作复杂的,这时候你再抽一次又有什么麻烦。
19 楼 抛出异常的爱 2007-12-25  
zbird 写道
就个人而言,我不喜欢DAO。
DAO不是万能药,解耦并不是加个DAO就能解决的问题。
对于大多的简单操作,Hibernate封得已经够完善了,大多时候加个DAO费力不讨好。
如果操作复杂,Service层过于混乱,这时候再抽取出个DAO也没什么不可以。
说到使用DAO解耦,大家最喜欢举的例子就是换实现。以前是说换数据库,现在Hiberate对数据库封得差不多了。于是说法改成将hibernate换成其他的实现,如jdbc等。
但真实项目中有谁有事没事的去换这些东西。
耦是有了才需要解的,如果凭空想出很多不实在的需求,无非是给自己自找麻烦。
我一直在说....
不是为了移植
而是为了管理方便

当然你可以把业务逻辑
与数据库逻辑写在一起
当只有一二个表时
并没什么不好解理
当一个操作关系到:
日志表,
权限表,
业务级联表,
操作记录表,

用人类的智力要从这么多的代码中找到逻辑.....还是差点意思
18 楼 zbird 2007-12-25  
就个人而言,我不喜欢DAO。
DAO不是万能药,解耦并不是加个DAO就能解决的问题。
对于大多的简单操作,Hibernate封得已经够完善了,大多时候加个DAO费力不讨好。
如果操作复杂,Service层过于混乱,这时候再抽取出个DAO也没什么不可以。
说到使用DAO解耦,大家最喜欢举的例子就是换实现。以前是说换数据库,现在Hiberate对数据库封得差不多了。于是说法改成将hibernate换成其他的实现,如jdbc等。
但真实项目中有谁有事没事的去换这些东西。
耦是有了才需要解的,如果凭空想出很多不实在的需求,无非是给自己自找麻烦。
17 楼 ice123456 2007-12-24  
我也是一个初学者。
我做个一个小项目分层:
1,servlet 专放servlet
2, entity 实体包
3 dao 数据库操作
4 util 帮助
我也是一样用的hibernate,但是我脱离了hibernate,是一样的`我只需要去修改dao里面的类。servlet里面基本上是一些输出xml的地方(用的AJAX)
16 楼 抛出异常的爱 2007-12-24  
pitt_xu 写道
除非持久层决定永远用hibernate了
不然去除了dao 对于以后可能发生的修改会引起很大的开销 比如出现了更好的持久层框架需要更换
dao只是一套接口 用来消除service层和持久层的耦合 应该是这么回事~^_^
过于扁平耦合在一起的系统的路走不长
我曾把hibernate的DAO从ejb中剥出来
用spring来代替.
15 楼 pitt_xu 2007-12-24  
除非持久层决定永远用hibernate了
不然去除了dao 对于以后可能发生的修改会引起很大的开销 比如出现了更好的持久层框架需要更换
dao只是一套接口 用来消除service层和持久层的耦合 应该是这么回事~^_^
过于扁平耦合在一起的系统的路走不长
14 楼 zhcl321 2007-12-23  
二楼说的很对,我认为:分层的目的就是为了解耦合,为了尽可能的使各个层次之间的耦合度降低,这样当我们的数据层或者业务层或者表示层发生了一些变化, 可以在最大限度的情况下减少其他层面的代码的变动,在我们使用hibernate的时候,hibernate负责为我们进行数据库的连接操作,而我们写DAO,也是在他的数据库操作的基础上再进行一次封装,这样当我们想更换数据库连接操作方式的时候,只需要改DAO及其以下的部分就可以了,而service层,从字面上翻译,就是服务,它是通过DAO给它的服务,给表示层的Action进行服务的,所有的业务操作应该都是写在service层上的,表示层只是需要调用service层给它提供的接口就行了,这样就好比我们使用手机一样,当我们给手机充电的时候,我们不需要对它的内部结构有多了解,只要我们能正确的使用它提供给我们的充电接口就对了,这就是各司其职吧,不管你内部结构怎么变化,只要你提供给我的是那个接口就不影响我的使用了。但是有些时候,根据项目的不同,耦合度的松紧是靠个人掌握的,并不一定是一定要严格做到松耦合,因为有些时候,想做到松耦合,的确很麻烦,会比紧耦合的情况下要多写很多代码,多考虑很多情况,有些时候这是不必要的。
以上仅是个人拙见,有什么不对的地方,请指点
13 楼 tczengjin 2007-12-23  
<p><font>没有Dao 一个BookService的实现,即简化开发,又降低了耦合,感觉在简化和降低耦合上所做的平衡做的实在很好。</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'>package</span><span> org.springside.bookstore.service.sysmgr;   </span></span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> java.util.HashMap;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> java.util.List;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> java.util.Map;   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.apache.commons.lang.StringUtils;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.hibernate.Criteria;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.hibernate.criterion.Restrictions;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.springside.bookstore.components.xfire.server.simple.BookService;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.springside.bookstore.model.Book;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.springside.bookstore.model.Category;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.springside.bookstore.model.Product;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.springside.core.dao.extend.HibernateEntityExtendDao;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.springside.core.dao.support.Page;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.springside.core.exception.BusinessException;   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span/><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'> * 图书管理业务类. </span> </span></li>
    <li class=''><span><span class='comment'> * 继承于HibernateEntityDao,拥有默认的对Book对象的CRUD函数. </span> </span></li>
    <li class='alt'><span><span class='comment'> * 因为<code>Category</code>实体过于简单,没有独立的Manager,因此BookManager同时充当了CategoryDao的角色. </span> </span></li>
    <li class=''><span><span class='comment'> * </span> </span></li>
    <li class='alt'><span><span class='comment'> * @author calvin </span> </span></li>
    <li class=''><span><span class='comment'> * @see HibernateEntityExtendDao </span> </span></li>
    <li class='alt'><span><span class='comment'> * @see org.springside.core.dao.HibernateGenericDao </span> </span></li>
    <li class=''><span><span class='comment'> */</span><span>  </span></span></li>
    <li class='alt'><span/><span class='annotation'>@SuppressWarnings</span><span>(</span><span class='string'>"unchecked"</span><span>)   </span></li>
    <li class=''><span/><span class='keyword'>public</span><span> </span><span class='keyword'>class</span><span> BookManager </span><span class='keyword'>extends</span><span> HibernateEntityExtendDao&lt;book&gt; </span><span class='keyword'>implements</span><span> BookService {   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='annotation'>@Override</span><span>  </span></li>
    <li class='alt'><span>    </span><span class='keyword'>protected</span><span> </span><span class='keyword'>void</span><span> onValid(Book entity) {   </span></li>
    <li class=''><span>        </span><span class='keyword'>if</span><span> (!isUnique(entity, </span><span class='string'>"name"</span><span>)) {   </span></li>
    <li class='alt'><span>            </span><span class='keyword'>throw</span><span> </span><span class='keyword'>new</span><span> BusinessException(</span><span class='string'>"书名"</span><span> + entity.getName() + </span><span class='string'>"重复"</span><span>);   </span></li>
    <li class=''><span>        }   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 分页获取最新图书. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> Page getNewBooks(Integer pageNo, Integer pageSize) {   </span></li>

<p><font>这正是我所需要的。感谢大家的回复。</font></p></ol></div>
12 楼 tczengjin 2007-12-23  
<p><font>
qmy 写道
先谢谢tczengjin的回复</font></p>
<p><font>我再想了想之前用JDBC时的DAO所做的工作,只是封装了SQL语句。<br/>
比如DAO有个insert(User)的方法,封装的是insert into t_user values(?,?,?.....)的操作,Service只要调用DAO的这个insert方法就好了。</font></p>
<p><font>可是Hibernate提供了save(user)这样的方法,已经封装了SQL语句,也就是说它已经实现了DAO的功能,没必要再写DAO了。如果为了解耦合,只有写一个Hibernate提供的这些api的抽象,然后如果想切换到JDBC,就另外写一个譬如JDBC的DAO实现。</font></p>
<p><font>还是我的菜菜的理解……望指点
<br/>
楼上其它人的回复也就是这个意思,另外抛出异常的爱的回复的确是经验之谈,结合以前看了点的spirngside关于EntityDao和HibernateEntityDao HibernateGenericDao这三个类的封装目的完全和抛出异常的爱说的一致,而在springside2 bookstore例子中省略了dao,service继承HibernateEntityDao&lt;T&gt;,如果需要复杂的查询的话,正如楼上所说,此时可以在写Dao继承HibernateEntityDao&lt;T&gt;封装查询操作,然后供service继承。在bookstore例子中没有Dao这一层,可见一般情况下可以省略Dao了。如果你需要使用其它orm解决方案可以可以继承springside 比如IbatisEntityDao&lt;T&gt; 它们均实现了EntityDao接口,这也正是接口的作用。这里把springside关于Hibernate的封装帖出来,供你参考吧,呵呵,今天算开窍了。<br/>
</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'>package</span><span> org.springside.core.dao;   </span></span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> java.io.Serializable;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> java.util.List;   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.hibernate.Criteria;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.hibernate.criterion.Criterion;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.springside.core.utils.GenericsUtils;   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span/><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'> * 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类. </span> </span></li>
    <li class=''><span><span class='comment'> * &lt;p/&gt; </span> </span></li>
    <li class='alt'><span><span class='comment'> * 子类只要在类定义时指定所管理Entity的Class, 即拥有对单个Entity对象的CRUD操作. </span> </span></li>
    <li class=''><span><span class='comment'> * &lt;pre&gt; </span> </span></li>
    <li class='alt'><span><span class='comment'> * public class UserManager extends HibernateEntityDao&lt;User&gt; { </span> </span></li>
    <li class=''><span><span class='comment'> * } </span> </span></li>
    <li class='alt'><span><span class='comment'> * &lt;/pre&gt; </span> </span></li>
    <li class=''><span><span class='comment'> * </span> </span></li>
    <li class='alt'><span><span class='comment'> * @author calvin </span> </span></li>
    <li class=''><span><span class='comment'> * @see HibernateGenericDao </span> </span></li>
    <li class='alt'><span><span class='comment'> */</span><span>  </span></span></li>
    <li class=''><span/><span class='annotation'>@SuppressWarnings</span><span>(</span><span class='string'>"unchecked"</span><span>)   </span></li>
    <li class='alt'><span/><span class='keyword'>public</span><span> </span><span class='keyword'>class</span><span> HibernateEntityDao&lt;T&gt; </span><span class='keyword'>extends</span><span> HibernateGenericDao </span><span class='keyword'>implements</span><span> EntityDao&lt;T&gt; {   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='keyword'>protected</span><span> Class&lt;T&gt; entityClass;</span><span class='comment'>// DAO所管理的Entity类型. </span><span>  </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 在构造函数中将泛型T.class赋给entityClass. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> HibernateEntityDao() {   </span></li>
    <li class='alt'><span>        entityClass = GenericsUtils.getSuperClassGenricType(getClass());   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class&lt;T&gt; entityClass,重载此函数达到相同效果。 </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>protected</span><span> Class&lt;T&gt; getEntityClass() {   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> entityClass;   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 根据ID获取对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @see HibernateGenericDao#getId(Class,Object) </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> T get(Serializable id) {   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> get(getEntityClass(), id);   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 获取全部对象 </span> </span></li>
    <li class=''><span><span class='comment'>     * </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @see HibernateGenericDao#getAll(Class) </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> List&lt;T&gt; getAll() {   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> getAll(getEntityClass());   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 获取全部对象,带排序参数. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @see HibernateGenericDao#getAll(Class,String,boolean) </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> List&lt;T&gt; getAll(String orderBy, </span><span class='keyword'>boolean</span><span> isAsc) {   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> getAll(getEntityClass(), orderBy, isAsc);   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 根据ID移除对象. </span> </span></li>
    <li class=''><span><span class='comment'>     * </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @see HibernateGenericDao#removeById(Class,Serializable) </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> </span><span class='keyword'>void</span><span> removeById(Serializable id) {   </span></li>
    <li class=''><span>        removeById(getEntityClass(), id);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 取得Entity的Criteria. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @see HibernateGenericDao#createCriteria(Class,Criterion[]) </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> Criteria createCriteria(Criterion... criterions) {   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> createCriteria(getEntityClass(), criterions);   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 取得Entity的Criteria,带排序参数. </span> </span></li>
    <li class=''><span><span class='comment'>     * </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[]) </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> Criteria createCriteria(String orderBy, </span><span class='keyword'>boolean</span><span> isAsc, Criterion... criterions) {   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> createCriteria(getEntityClass(), orderBy, isAsc, criterions);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 根据属性名和属性值查询对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @return 符合条件的对象列表 </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @see HibernateGenericDao#findBy(Class,String,Object) </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> List&lt;T&gt; findBy(String propertyName, Object value) {   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> findBy(getEntityClass(), propertyName, value);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 根据属性名和属性值查询对象,带排序参数. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @return 符合条件的对象列表 </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean) </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> List&lt;T&gt; findBy(String propertyName, Object value, String orderBy, </span><span class='keyword'>boolean</span><span> isAsc) {   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> findBy(getEntityClass(), propertyName, value, orderBy, isAsc);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 根据属性名和属性值查询单个对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @return 符合条件的唯一对象 or null </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @see HibernateGenericDao#findUniqueBy(Class,String,Object) </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> T findUniqueBy(String propertyName, Object value) {   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> findUniqueBy(getEntityClass(), propertyName, value);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 判断对象某些属性的值在数据库中唯一. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password" </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @see HibernateGenericDao#isUnique(Class,Object,String) </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> </span><span class='keyword'>boolean</span><span> isUnique(Object entity, String uniquePropertyNames) {   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> isUnique(getEntityClass(), entity, uniquePropertyNames);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>       </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 消除与 Hibernate Session 的关联 </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @param entity </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> </span><span class='keyword'>void</span><span> evit(Object entity){   </span></li>
    <li class=''><span>        getHibernateTemplate().evict(entity);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>}  </span></li>
</ol>
</div>
<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'>package</span><span> org.springside.core.dao;   </span></span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> java.io.Serializable;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> java.util.List;   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span/><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'> * 针对单个Entity对象的操作定义.不依赖于具体ORM实现方案. </span> </span></li>
    <li class=''><span><span class='comment'> * </span> </span></li>
    <li class='alt'><span><span class='comment'> * @author calvin </span> </span></li>
    <li class=''><span><span class='comment'> */</span><span>  </span></span></li>
    <li class='alt'><span/><span class='keyword'>public</span><span> </span><span class='keyword'>interface</span><span> EntityDao&lt;T&gt; {   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    T get(Serializable id);   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    List&lt;T&gt; getAll();   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='keyword'>void</span><span> save(Object o);   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='keyword'>void</span><span> remove(Object o);   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='keyword'>void</span><span> removeById(Serializable id);   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 获取Entity对象的主键名. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    String getIdName(Class clazz);   </span></li>
    <li class='alt'><span>}  </span></li>
</ol>
</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'>package</span><span> org.springside.core.dao;   </span></span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> java.io.Serializable;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> java.lang.reflect.InvocationTargetException;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> java.util.ArrayList;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> java.util.List;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> java.util.regex.Matcher;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> java.util.regex.Pattern;   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.apache.commons.beanutils.PropertyUtils;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.hibernate.Criteria;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.hibernate.Query;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.hibernate.criterion.CriteriaSpecification;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.hibernate.criterion.Criterion;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.hibernate.criterion.DetachedCriteria;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.hibernate.criterion.Order;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.hibernate.criterion.Projection;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.hibernate.criterion.Projections;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.hibernate.criterion.Restrictions;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.hibernate.impl.CriteriaImpl;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.hibernate.metadata.ClassMetadata;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.springframework.orm.hibernate3.support.HibernateDaoSupport;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.springframework.util.Assert;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.springframework.util.ReflectionUtils;   </span></li>
    <li class='alt'><span/><span class='keyword'>import</span><span> org.springside.core.dao.support.Page;   </span></li>
    <li class=''><span/><span class='keyword'>import</span><span> org.springside.core.utils.BeanUtils;   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span/><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'> * Hibernate Dao的泛型基类. </span> </span></li>
    <li class=''><span><span class='comment'> * &lt;p/&gt; </span> </span></li>
    <li class='alt'><span><span class='comment'> * 继承于Spring的&lt;code&gt;HibernateDaoSupport&lt;/code&gt;,提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换. </span> </span></li>
    <li class=''><span><span class='comment'> * </span> </span></li>
    <li class='alt'><span><span class='comment'> * @author calvin </span> </span></li>
    <li class=''><span><span class='comment'> * @author tin </span> </span></li>
    <li class='alt'><span><span class='comment'> * @see HibernateDaoSupport </span> </span></li>
    <li class=''><span><span class='comment'> * @see HibernateEntityDao </span> </span></li>
    <li class='alt'><span><span class='comment'> */</span><span>  </span></span></li>
    <li class=''><span/><span class='annotation'>@SuppressWarnings</span><span>(</span><span class='string'>"unchecked"</span><span>)   </span></li>
    <li class='alt'><span/><span class='keyword'>public</span><span> </span><span class='keyword'>class</span><span> HibernateGenericDao </span><span class='keyword'>extends</span><span> HibernateDaoSupport {   </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常. </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> &lt;T&gt; T get(Class&lt;T&gt; entityClass, Serializable id) {   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> (T) getHibernateTemplate().load(entityClass, id);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 获取全部对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> &lt;T&gt; List&lt;T&gt; getAll(Class&lt;T&gt; entityClass) {   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> getHibernateTemplate().loadAll(entityClass);   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 获取全部对象,带排序字段与升降序参数. </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> &lt;T&gt; List&lt;T&gt; getAll(Class&lt;T&gt; entityClass, String orderBy, </span><span class='keyword'>boolean</span><span> isAsc) {   </span></li>
    <li class=''><span>        Assert.hasText(orderBy);   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>if</span><span> (isAsc)   </span></li>
    <li class=''><span>            </span><span class='keyword'>return</span><span> getHibernateTemplate().findByCriteria(   </span></li>
    <li class='alt'><span>                    DetachedCriteria.forClass(entityClass).addOrder(Order.asc(orderBy)));   </span></li>
    <li class=''><span>        </span><span class='keyword'>else</span><span>  </span></li>
    <li class='alt'><span>            </span><span class='keyword'>return</span><span> getHibernateTemplate().findByCriteria(   </span></li>
    <li class=''><span>                    DetachedCriteria.forClass(entityClass).addOrder(Order.desc(orderBy)));   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 保存对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> </span><span class='keyword'>void</span><span> save(Object o) {   </span></li>
    <li class='alt'><span>        getHibernateTemplate().saveOrUpdate(o);   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 删除对象. </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> </span><span class='keyword'>void</span><span> remove(Object o) {   </span></li>
    <li class=''><span>        getHibernateTemplate().delete(o);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 根据ID删除对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> &lt;T&gt; </span><span class='keyword'>void</span><span> removeById(Class&lt;T&gt; entityClass, Serializable id) {   </span></li>
    <li class='alt'><span>        remove(get(entityClass, id));   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> </span><span class='keyword'>void</span><span> flush() {   </span></li>
    <li class='alt'><span>        getHibernateTemplate().flush();   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> </span><span class='keyword'>void</span><span> clear() {   </span></li>
    <li class='alt'><span>        getHibernateTemplate().clear();   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置. </span> </span></li>
    <li class=''><span><span class='comment'>     * 留意可以连续设置,如下: </span> </span></li>
    <li class='alt'><span><span class='comment'>     * &lt;pre&gt; </span> </span></li>
    <li class=''><span><span class='comment'>     * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list(); </span> </span></li>
    <li class='alt'><span><span class='comment'>     * &lt;/pre&gt; </span> </span></li>
    <li class=''><span><span class='comment'>     * 调用方式如下: </span> </span></li>
    <li class='alt'><span><span class='comment'>     * &lt;pre&gt; </span> </span></li>
    <li class=''><span><span class='comment'>     *        dao.createQuery(hql) </span> </span></li>
    <li class='alt'><span><span class='comment'>     *        dao.createQuery(hql,arg0); </span> </span></li>
    <li class=''><span><span class='comment'>     *        dao.createQuery(hql,arg0,arg1); </span> </span></li>
    <li class='alt'><span><span class='comment'>     *        dao.createQuery(hql,new Object[arg0,arg1,arg2]) </span> </span></li>
    <li class=''><span><span class='comment'>     * &lt;/pre&gt; </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @param values 可变参数. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> Query createQuery(String hql, Object... values) {   </span></li>
    <li class='alt'><span>        Assert.hasText(hql);   </span></li>
    <li class=''><span>        Query query = getSession().createQuery(hql);   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>for</span><span> (</span><span class='keyword'>int</span><span> i = </span><span class='number'>0</span><span>; i &lt; values.length; i++) {   </span></li>
    <li class=''><span>            query.setParameter(i, values[i]);   </span></li>
    <li class='alt'><span>        }   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> query;   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 创建Criteria对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)} </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> &lt;T&gt; Criteria createCriteria(Class&lt;T&gt; entityClass, Criterion... criterions) {   </span></li>
    <li class='alt'><span>        Criteria criteria = getSession().createCriteria(entityClass);   </span></li>
    <li class=''><span>        </span><span class='keyword'>for</span><span> (Criterion c : criterions) {   </span></li>
    <li class='alt'><span>            criteria.add(c);   </span></li>
    <li class=''><span>        }   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> criteria;   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 创建Criteria对象,带排序字段与升降序字段. </span> </span></li>
    <li class=''><span><span class='comment'>     * </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @see #createCriteria(Class,Criterion[]) </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> &lt;T&gt; Criteria createCriteria(Class&lt;T&gt; entityClass, String orderBy, </span><span class='keyword'>boolean</span><span> isAsc, Criterion... criterions) {   </span></li>
    <li class=''><span>        Assert.hasText(orderBy);   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>        Criteria criteria = createCriteria(entityClass, criterions);   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>        </span><span class='keyword'>if</span><span> (isAsc)   </span></li>
    <li class='alt'><span>            criteria.addOrder(Order.asc(orderBy));   </span></li>
    <li class=''><span>        </span><span class='keyword'>else</span><span>  </span></li>
    <li class='alt'><span>            criteria.addOrder(Order.desc(orderBy));   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> criteria;   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 根据hql查询,直接使用HibernateTemplate的find函数. </span> </span></li>
    <li class=''><span><span class='comment'>     * </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @param values 可变参数,见{@link #createQuery(String,Object...)} </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> List find(String hql, Object... values) {   </span></li>
    <li class=''><span>        Assert.hasText(hql);   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> getHibernateTemplate().find(hql, values);   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 根据属性名和属性值查询对象. </span> </span></li>
    <li class=''><span><span class='comment'>     * </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @return 符合条件的对象列表 </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> &lt;T&gt; List&lt;T&gt; findBy(Class&lt;T&gt; entityClass, String propertyName, Object value) {   </span></li>
    <li class=''><span>        Assert.hasText(propertyName);   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> createCriteria(entityClass, Restrictions.eq(propertyName, value)).list();   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 根据属性名和属性值查询对象,带排序参数. </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> &lt;T&gt; List&lt;T&gt; findBy(Class&lt;T&gt; entityClass, String propertyName, Object value, String orderBy, </span><span class='keyword'>boolean</span><span> isAsc) {   </span></li>
    <li class=''><span>        Assert.hasText(propertyName);   </span></li>
    <li class='alt'><span>        Assert.hasText(orderBy);   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> createCriteria(entityClass, orderBy, isAsc, Restrictions.eq(propertyName, value)).list();   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 根据属性名和属性值查询唯一对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @return 符合条件的唯一对象 or null if not found. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> &lt;T&gt; T findUniqueBy(Class&lt;T&gt; entityClass, String propertyName, Object value) {   </span></li>
    <li class='alt'><span>        Assert.hasText(propertyName);   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> (T) createCriteria(entityClass, Restrictions.eq(propertyName, value)).uniqueResult();   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 分页查询函数,使用hql. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @param pageNo 页号,从1开始. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> Page pagedQuery(String hql, </span><span class='keyword'>int</span><span> pageNo, </span><span class='keyword'>int</span><span> pageSize, Object... values) {   </span></li>
    <li class='alt'><span>        Assert.hasText(hql);   </span></li>
    <li class=''><span>        Assert.isTrue(pageNo &gt;= </span><span class='number'>1</span><span>, </span><span class='string'>"pageNo should start from 1"</span><span>);   </span></li>
    <li class='alt'><span>        </span><span class='comment'>// Count查询 </span><span>  </span></li>
    <li class=''><span>        String countQueryString = </span><span class='string'>" select count (*) "</span><span> + removeSelect(removeOrders(hql));   </span></li>
    <li class='alt'><span>        List countlist = getHibernateTemplate().find(countQueryString, values);   </span></li>
    <li class=''><span>        </span><span class='keyword'>long</span><span> totalCount = (Long) countlist.get(</span><span class='number'>0</span><span>);   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>        </span><span class='keyword'>if</span><span> (totalCount &lt; </span><span class='number'>1</span><span>)   </span></li>
    <li class='alt'><span>            </span><span class='keyword'>return</span><span> </span><span class='keyword'>new</span><span> Page();   </span></li>
    <li class=''><span>        </span><span class='comment'>// 实际查询返回分页对象 </span><span>  </span></li>
    <li class='alt'><span>        </span><span class='keyword'>int</span><span> startIndex = Page.getStartOfPage(pageNo, pageSize);   </span></li>
    <li class=''><span>        Query query = createQuery(hql, values);   </span></li>
    <li class='alt'><span>        List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> </span><span class='keyword'>new</span><span> Page(startIndex, totalCount, pageSize, list);   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 分页查询函数,使用已设好查询条件与排序的&lt;code&gt;Criteria&lt;/code&gt;. </span> </span></li>
    <li class=''><span><span class='comment'>     * </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @param pageNo 页号,从1开始. </span> </span></li>
    <li class=''><span><span class='comment'>     * @return 含总记录数和当前页数据的Page对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> Page pagedQuery(Criteria criteria, </span><span class='keyword'>int</span><span> pageNo, </span><span class='keyword'>int</span><span> pageSize) {   </span></li>
    <li class='alt'><span>        Assert.notNull(criteria);   </span></li>
    <li class=''><span>        Assert.isTrue(pageNo &gt;= </span><span class='number'>1</span><span>, </span><span class='string'>"pageNo should start from 1"</span><span>);   </span></li>
    <li class='alt'><span>        CriteriaImpl impl = (CriteriaImpl) criteria;   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>        </span><span class='comment'>// 先把Projection和OrderBy条件取出来,清空两者来执行Count操作 </span><span>  </span></li>
    <li class=''><span>        Projection projection = impl.getProjection();   </span></li>
    <li class='alt'><span>        List&lt;CriteriaImpl.OrderEntry&gt; orderEntries;   </span></li>
    <li class=''><span>        </span><span class='keyword'>try</span><span> {   </span></li>
    <li class='alt'><span>            orderEntries = (List) BeanUtils.forceGetProperty(impl, </span><span class='string'>"orderEntries"</span><span>);   </span></li>
    <li class=''><span>            BeanUtils.forceSetProperty(impl, </span><span class='string'>"orderEntries"</span><span>, </span><span class='keyword'>new</span><span> ArrayList());   </span></li>
    <li class='alt'><span>        } </span><span class='keyword'>catch</span><span> (Exception e) {   </span></li>
    <li class=''><span>            </span><span class='keyword'>throw</span><span> </span><span class='keyword'>new</span><span> InternalError(</span><span class='string'>" Runtime Exception impossibility throw "</span><span>);   </span></li>
    <li class='alt'><span>        }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>        </span><span class='comment'>// 执行查询 </span><span>  </span></li>
    <li class=''><span>        </span><span class='keyword'>int</span><span> totalCount = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>        </span><span class='comment'>// 将之前的Projection和OrderBy条件重新设回去 </span><span>  </span></li>
    <li class='alt'><span>        criteria.setProjection(projection);   </span></li>
    <li class=''><span>        </span><span class='keyword'>if</span><span> (projection == </span><span class='keyword'>null</span><span>) {   </span></li>
    <li class='alt'><span>            criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);   </span></li>
    <li class=''><span>        }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>        </span><span class='keyword'>try</span><span> {   </span></li>
    <li class='alt'><span>            BeanUtils.forceSetProperty(impl, </span><span class='string'>"orderEntries"</span><span>, orderEntries);   </span></li>
    <li class=''><span>        } </span><span class='keyword'>catch</span><span> (Exception e) {   </span></li>
    <li class='alt'><span>            </span><span class='keyword'>throw</span><span> </span><span class='keyword'>new</span><span> InternalError(</span><span class='string'>" Runtime Exception impossibility throw "</span><span>);   </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'>if</span><span> (totalCount &lt; </span><span class='number'>1</span><span>)   </span></li>
    <li class=''><span>            </span><span class='keyword'>return</span><span> </span><span class='keyword'>new</span><span> Page();   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>        </span><span class='keyword'>int</span><span> startIndex = Page.getStartOfPage(pageNo, pageSize);   </span></li>
    <li class='alt'><span>        List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();   </span></li>
    <li class=''><span>        </span><span class='keyword'>return</span><span> </span><span class='keyword'>new</span><span> Page(startIndex, totalCount, pageSize, list);   </span></li>
    <li class='alt'><span>    }   </span></li>
    <li class=''><span>  </span></li>
    <li class='alt'><span>    </span><span class='comment'>/** </span> </li>
    <li class=''><span><span class='comment'>     * 分页查询函数,根据entityClass和查询条件参数创建默认的&lt;code&gt;Criteria&lt;/code&gt;. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * </span> </span></li>
    <li class=''><span><span class='comment'>     * @param pageNo 页号,从1开始. </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @return 含总记录数和当前页数据的Page对象. </span> </span></li>
    <li class=''><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> Page pagedQuery(Class entityClass, </span><span class='keyword'>int</span><span> pageNo, </span><span class='keyword'>int</span><span> pageSize, Criterion... criterions) {   </span></li>
    <li class=''><span>        Criteria criteria = createCriteria(entityClass, criterions);   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> pagedQuery(criteria, pageNo, pageSize);   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的&lt;code&gt;Criteria&lt;/code&gt;. </span> </span></li>
    <li class=''><span><span class='comment'>     * </span> </span></li>
    <li class='alt'><span><span class='comment'>     * @param pageNo 页号,从1开始. </span> </span></li>
    <li class=''><span><span class='comment'>     * @return 含总记录数和当前页数据的Page对象. </span> </span></li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span></li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> Page pagedQuery(Class entityClass, </span><span class='keyword'>int</span><span> pageNo, </span><span class='keyword'>int</span><span> pageSize, String orderBy, </span><span class='keyword'>boolean</span><span> isAsc,   </span></li>
    <li class='alt'><span>                           Criterion... criterions) {   </span></li>
    <li class=''><span>        Criteria criteria = createCriteria(entityClass, orderBy, isAsc, criterions);   </span></li>
    <li class='alt'><span>        </span><span class='keyword'>return</span><span> pagedQuery(criteria, pageNo, pageSize);   </span></li>
    <li class=''><span>    }   </span></li>
    <li class='alt'><span>  </span></li>
    <li class=''><span>    </span><span class='comment'>/** </span> </li>
    <li class='alt'><span><span class='comment'>     * 判断对象某些属性的值在数据库中是否唯一. </span> </span></li>
    <li class=''><span><span class='comment'>     * </span> </span></li>
    <li class='alt'><span><span class='comment'> &amp;n</span></span></li></ol></div>
11 楼 skzr.org 2007-12-23  
个人感觉分清楚各个层还是很有必要的
目前公司的项目中:也和楼主的情形差不多,实际上每一层都只是对下层的方法的简单封装
也就是上面的Service.add(User)-->DAO.add(user) -包含-> Hibernate.save(User)
感觉很冗余,不过我也发现了,随着应用规模的扩展,在很多地方出现了重复的代码
对于分层封装来说如果前期没有规划好,会带来不必要的麻烦的
目前公司打算明年整合产品呢,底层开发尽然使用相同的接口来实现(公司的产品现在存在多个,但是他们底层所要操作的数据基本上都是一致的,目前出现了每个产品都需要实现一次它自己的底层操作,实际上那些操作在明年打算完全由一个组来提供一个接口来整合)

个人愚见:
1。根据规模,和将来来判断分层架构,至于方法的冗余实现,那是业务没有划分好导致的,未区分业务方法和持久化方法
2。至于说的数据库使用了ORM依然可以使用JDBC的,Hibernate还是提供了JDBC 原生SQL的阿,还有实在不行还可以获取Connection吖——这是jdbc的开始^-^ 有了Connection就可以做任何事情了
10 楼 抛出异常的爱 2007-12-23  
tczengjin 写道
抛出异常的爱 写道
管理方便 ,找文件不用debug
仅此而已吗?能稍微详细点吗?另外看过你在javaeye上的回帖,一般回的第一帖精简的很,如果不是我继续看你以后的回帖,恐怕偶目前还理解不了其中的深意 另外我这样dao每个方法打开session进行一次crud操作后关闭,那Session的缓存基本上利用不上了是不???

你又高看我了,
crud这里面cud三个是非常重复的劳动
由session.save(o)
就可以完成的东西不应该写在每个DAO中如果想要写也要写到公共的DAO中以减少代码重复
根据ID找实例的过程也被合谐了(就是sql:seclect XXX from x_table where id = ?)
所以dao里只要放一些非常不一般的查询语句,
并给这些查询方法定义一个好贴切好理解的名子就可以了.
或在注释中把这个东西用在某处的场景写好
到要改时不用从action -> service ->dao 这样找过去
只要简简单单的用全文搜索找到这样的注释
或新加dao 或 修改dao全看对这个方法的引用来决定了.

以上是工作方法中的方便之处.
可以提高工作效率300%左右

PS:看robbin以前的贴子,对查询的优化缓存,不以session开关为终点.好像是cache机制,不过我还没有感受过

tczengjin 写道
xuejianshan 写道
偶也正在学习之中,如果你在看看spring我想你会恍然大悟的。
但是当你学习这方面的东西时,头脑里必须有一个概念---面象接口编程。
具体它为什么这样分,当然会有它的道理,如果你还是不明白的话,那只能说你对它的思想还不够深入,我建议多读代码,和别人讨论一下。
我其实还是懂一点spring的,能够理解面向接口编程。如果说Dao接口可以不让降低我们对数据库访问接口的依赖,Service接口主要可以降低我们对于什么的依赖呢?如果大家略举一例,不胜感激!!!另外我目前写的程序与Hibernate耦合并没有关系,在这样的情况下,大家认为省去Dao是不是一个更好的选择,我一开始就不介意与Hibernate偶和,故均没有写Service接口和Dao接口,但写了Service 和 Dao的一个具体的实现(出于自己一想简化开发省了接口,又惯性使然写了这两个层),请问在这样的情况,大家能否给个建议,Service和Dao的取舍问题,谢谢!

对事务的范围的依赖.
如果你所有的业务都是简单的crud一个表,
那 么service就是摆设
但只要你的service包含多个表的操作
那么就要以service的每个方法作为事务的边界
让spring可以以这个为边界来自动补充事务.

再PS:这些在以前有过很详细的讨论. 还谈到了充血模型的问题.搜一下

相关推荐

    myeclipse中自动生成hibernate的POJO、DAO和hbm.xml文件

    为了使用MyEclipse生成Hibernate的POJO、DAO和hbm.xml文件,首先需要配置数据库连接。在MyEclipse中,可以通过Database Explorer窗口来配置数据库连接。具体步骤如下: 1. 打开Database Explorer窗口:window-&gt;open...

    Hibernate 原生通用DAO

    5. **缓存支持**:Hibernate提供了第一级缓存和第二级缓存,通用DAO可以根据需求选择是否开启和配置缓存,提高数据读取速度。 6. **实体转换**:将数据库查询结果转化为对应的Java对象,通常是通过`Session.load()`...

    hibernate eclipse插件生成dao样例

    标题中的“hibernate eclipse插件生成DAO样例”指的是使用Eclipse集成开发环境中的Hibernate插件自动生成数据访问对象(DAO)的示例。在Java应用程序开发中,尤其是使用Hibernate作为持久层框架时,DAO层是至关重要...

    Hibernate封装dao层

    在DAO层捕获和处理Hibernate抛出的异常,如`HibernateException`,并根据业务需求决定是否向上层抛出或转换为自定义异常。 8. **单元测试**: 对DAO层进行充分的单元测试,验证其功能的正确性,可以使用JUnit和...

    hibernate dao 生成工具

    Hibernate DAO(Data Access Object)生成工具是用于自动化创建数据访问层对象的实用程序,它可以显著提高开发效率,尤其是在处理大量数据库交互的项目中。DAO模式是一种设计模式,它提供了对数据库操作的抽象,使得...

    Hibernate的通用dao

    综上所述,Hibernate的通用DAO设计模式是提高开发效率、降低维护成本的有效手段,但需要注意适配项目需求,合理使用,以实现最佳的性能和可维护性。通过阅读给出的博客链接(https://lzkyo.iteye.com/blog/683285)...

    HibernateDao.java

    《深入解析HibernateDao.java》 在Java开发领域,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。本文将深入探讨`HibernateDao.java`这一关键组件,揭示其背后的原理与实践应用。 `...

    Hibernate中的DAO模式

    具体实现时,首先需要在数据库中创建带有分页参数的存储过程,如`GET_USERS_BY_PAGE`,接收两个参数:开始索引和页大小。然后在Hibernate的DAO类中,定义一个方法,如`getUsersByPage(int startIndex, int pageSize)...

    Hibernate泛型Dao

    在实际应用中,还需要理解JDBC(Java Database Connectivity)的基础知识,因为Hibernate是在JDBC之上建立的。此外,了解SQL语言也是必要的,虽然Hibernate可以自动生成SQL,但在某些复杂查询场景下,可能需要手动...

    hibernate spring通用dao

    spring集成hibernate通用dao,泛型,server都可以调用

    Hibernate_通用DAO模式,一个写好的dao层

    本资源“Hibernate_通用DAO模式”提供了一种适用于不同类型表单的DAO实现,基于SSH(Struts2、Spring、Hibernate)框架,特别强调简洁、易懂和高可移植性。 首先,SSH框架是Java Web开发中的经典组合,Struts2负责...

    hibernate4 通用dao,service

    标题中的“hibernate4 通用dao,service”指的是在Java开发中使用Hibernate框架实现的通用数据访问对象(DAO)和业务服务层(Service)。Hibernate是一个流行的对象关系映射(ORM)工具,它允许开发者使用面向对象的...

    HibernateDao 通用

    HibernateDao 是一种基于 Hibernate ORM(对象关系映射)框架的通用数据访问对象,它简化了对数据库的操作,提供了更高级别的抽象,使开发者能够更加专注于业务逻辑而不是底层的数据操作。在Java开发中,Hibernate...

    Hibernate 基于持久层框架的DAO模式应用

    在基于持久层框架的DAO(Data Access Object)模式应用中,Hibernate扮演着核心角色,使得业务逻辑和数据访问逻辑分离,提高了代码的可复用性和可维护性。 1. **DAO模式的理解** DAO模式是一种设计模式,它创建了...

    HibernateDao

    hibernateDao工具类

    JPA(hibernate) Dao 和 DaoSupport

    在实际项目中,我们还需要了解如何使用Spring Data JPA简化这一过程,并掌握如何实现分页查询以及处理查询结果。通过`DaoSupport`类,我们可以更好地组织和管理DAO实现,同时利用Spring框架提供的强大功能。

    Struts2+hibernate+spring整合泛型DAO

    在Struts2+Hibernate+Spring的集成中,泛型DAO扮演着重要的角色,它使得DAO层对所有实体类的操作变得统一和规范。 首先,让我们详细了解一下Struts2。Struts2是基于拦截器的MVC框架,它提供了强大的动作映射、结果...

    使用代理实现Hibernate Dao层自动事务

    本文将深入探讨如何使用代理来实现Hibernate Dao层的自动事务管理,以提高代码的可维护性和事务处理的效率。 首先,理解Dao(Data Access Object)层的作用至关重要。Dao层是应用与数据库之间的一层抽象,它封装了...

    HibernateDAO的写法

    《深入理解HibernateDAO的写法》 在Java企业级开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而HibernateDAO则是基于Hibernate进行数据访问的对象,是业务逻辑层和持久层之间...

Global site tag (gtag.js) - Google Analytics