`

在Hibernate中使用HibernateTemplate的三种方法

阅读更多
在我们的项目中,经常要从HibernateDaoSupport继承然后使用他的HibernateTemplate给我们封装好的方法。

我们以用户模块的持久层UserDao这个类的addUser(User user)方法为例:

第一种方法:userDao extends HibernateDaoSupport:(不推荐使用)
我们知道继承这个类,必须给他注入一个HibernateTemplate的对象,或者是SessionFactory对象但是HibernateDaoSupport这个类的所有的方法都是final的,无法重写他的setSessionFactory(SessionFactory sessionFactory)方法来注入,只能使用xml的方式来生成userDao这个对象的时候,使用<property id ="xxx" ref="xxx">来注入这个对象,但是如果这样,如果我们的Dao层的类特别多,都需要在xml文件中进行配置我们的xml配置文件就会十分的庞大 臃肿

第二种方法:
public class BaseDao extends HibernateDaoSupport {
	
	@Resource(name="sessionFactory")
	public void setSF(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}
}

我们抽取出来一个Dao层的基类然后让这个类继承HibernateDaoSupport,然后我们自己随便写个方法参数是SessionFactory,然后再方法上面加入@Resource注解,把SessionFactory对象,注入到这个方法中来然后再这个方法中调用父类中也就是HibernateDaoSupport 中的setSessionFactory(SessionFactory sessionFactory)方法把sessionFactory给他注入进去。默认情况下@Resource注解是按照名称来注入的,但是这个时候我们自己写的这个方法无法与spring配置文件中的id名称匹配起来就会按照类型进行注入了。然后我们的UserDao类继承我们的BaseDao类就可以使用HibernateTemlate中的方法了。

第三种方法:
public class BaseDao {
    private HibernateTemplate hibernateTemplate;
    @Resource
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
         this.hibernateTemplate = hibernateTemplate;
}	
}


还是抽取出一个BaseDao的类,然后我不继承HibernateDaoSupport这个类了。我在这个类中,定义一个HibernateTemplate类型的属性,然后把这个类注入进来,UserDao等这些持久化类仍然是从这个类继承,就可以使用HibernateTemplate中的方法了。
分享到:
评论
24 楼 javaliver 2010-06-13  
slaser 写道
whaosoft 写道
star022 写道
这年头 还这么多人玩DAO啊~~!

为什么不玩DAO了啊?

DAO没什么意义。
1.我只用hibernate。
2.我不换数据库。
3.sql和hql大部分写配置文件里面。
如此为什么不直接把session注入到service里面直接操作?



ession注入到service里面直接操作????
23 楼 slaser 2010-04-20  
aws 写道
ORM工具在简化单表动态查询和CRUD的时候作用很大
但是复杂查询用HQL之类的那就太过于麻烦了,还不如直接写SQL
至于一个业务逻辑里十几次操作数据库,这往往直接就写成存储过程了

对于很多遗留系统或者说设计时不是很考虑orm工具特性的系统,视图,存储过程等是不二法宝。处理非OO数据,java该歇一边去。
22 楼 slaser 2010-04-20  
downpour 写道
你认为DAO没有存在的必要性,主要是因为你做的项目还不够复杂。

在一个Service调用中,业务逻辑可能会包含十几次的数据库调用,其中有一半需要用HQL。你告诉我你把这些HQL全部写在Service层,那么你的Service层就会膨胀不堪,代码就会变得不可读。DAO层的出现,可以把这些HQL的数据库调用封装起来,让你的代码更加简洁。同时,这些被封装的函数,可以被反复调用。

HQL或者SQL写在配置文件里面是一种非常错误的做法。项目很大的时候,你会发现你的配置文件中充斥着非常类似的HQL或者SQL。同时,在你进行debug调试的时候,由于你拿到的是一个Key,增加了一个根据Key到配置文件去拿HQL的动作,从而给调试带来不便。

没看出来根据key拿hql那里麻烦了,除非key和对应的query命名非常混乱。如果合理运用named query,java代码和hql/sql相分离,将会大大减低维护工作的难度,拿sql来说,你说DBA喜欢看你java中拼出来的sql,还是单独配置文件中的sql?同样作为java程序员的我,在view代码的时候,看到一大串sql进来插入java中,我也非常无语。
21 楼 slaser 2010-04-20  
ysihaoy 写道
slaser 写道
aaa5131421 写道
downpour 写道
aaa5131421 写道

正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。


你的理解是错的。

DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。

如果我不是需要经常再不改动代码的情况下改动hql的需求,我会直接放在业务逻辑类里面。这是最理想的位置
谁说hql是属于dao层的呢?hql是属于业务逻辑的,它经hibernate转换后成变成的sql才属于dao层里面的东西。而hibernate的这个转化过程就是你在“调用dao层”
我不会直接写sql的,这违背hibernate本意,如果hql等。。实在满足不了需求,写sql是必然,但一个项目中这样的位置不会超过两处,这是技术上的问题,如果非要为这两处封装一个dao,得不偿失,假如需要写很多hql满足不了的sql,也可以考虑自己写个补充hibernate的hql解释器,而不是直接写sql并将他放在代码里面。

hql确实是业务层的东西,这个应该写在service里面,必须的sql放配置没什么问题,这个比放代码里面更干净,更容易调试。dao是jdbc时代遗留产物,不过为每一个sql的执行和把执行结果放入对象这样的操作做一个命名而已。在使用hibernate,jpa同时大量使用dao,才是一个很差的实践。所谓很薄的dao,为什么不直接用session或者jpa里面的entityManager代替,封装一下减少功能很有意思么?


这个不是绝对的,还应该具体问题具体分析吧。
如果系统比较复杂庞大,并且以后有换数据库的可能性,还是写一个dao层对日后是有好处的。
如果只是一般的系统并且数据库不会换掉可以考虑写一个自己的BaseDao。

我是基于不换数据库,不换orm工具来说的。没有限定条件,一切都是空谈。
20 楼 aws 2010-04-20  
ORM工具在简化单表动态查询和CRUD的时候作用很大
但是复杂查询用HQL之类的那就太过于麻烦了,还不如直接写SQL
至于一个业务逻辑里十几次操作数据库,这往往直接就写成存储过程了
19 楼 ysihaoy 2010-04-20  
slaser 写道
aaa5131421 写道
downpour 写道
aaa5131421 写道

正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。


你的理解是错的。

DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。

如果我不是需要经常再不改动代码的情况下改动hql的需求,我会直接放在业务逻辑类里面。这是最理想的位置
谁说hql是属于dao层的呢?hql是属于业务逻辑的,它经hibernate转换后成变成的sql才属于dao层里面的东西。而hibernate的这个转化过程就是你在“调用dao层”
我不会直接写sql的,这违背hibernate本意,如果hql等。。实在满足不了需求,写sql是必然,但一个项目中这样的位置不会超过两处,这是技术上的问题,如果非要为这两处封装一个dao,得不偿失,假如需要写很多hql满足不了的sql,也可以考虑自己写个补充hibernate的hql解释器,而不是直接写sql并将他放在代码里面。

hql确实是业务层的东西,这个应该写在service里面,必须的sql放配置没什么问题,这个比放代码里面更干净,更容易调试。dao是jdbc时代遗留产物,不过为每一个sql的执行和把执行结果放入对象这样的操作做一个命名而已。在使用hibernate,jpa同时大量使用dao,才是一个很差的实践。所谓很薄的dao,为什么不直接用session或者jpa里面的entityManager代替,封装一下减少功能很有意思么?


这个不是绝对的,还应该具体问题具体分析吧。
如果系统比较复杂庞大,并且以后有换数据库的可能性,还是写一个dao层对日后是有好处的。
如果只是一般的系统并且数据库不会换掉可以考虑写一个自己的BaseDao。
18 楼 aaa5131421 2010-04-20  
downpour 写道
你认为DAO没有存在的必要性,主要是因为你做的项目还不够复杂。

在一个Service调用中,业务逻辑可能会包含十几次的数据库调用,其中有一半需要用HQL。你告诉我你把这些HQL全部写在Service层,那么你的Service层就会膨胀不堪,代码就会变得不可读。DAO层的出现,可以把这些HQL的数据库调用封装起来,让你的代码更加简洁。同时,这些被封装的函数,可以被反复调用。

一个业务逻辑包含十来个数据库调用扥情况,如果你将这些业务逻辑只是写在一个service里面,没有进行横向的模块划分的话的确会很复杂,会膨胀不堪,会不可读,但这却不是因为没有dao层的原因,而是由于你设计的问题,安我的经验,一个业务逻辑中的十来次数据库操作,而且都是很复杂的数据库操作,通常这样的逻辑可以再拆分成更细化的逻辑,而且有一部分逻辑是属于其他模块的业务逻辑,完全可以抽象出来放在其他模块的services里面,这样也可以拿来复用。
因为services层的臃肿不堪就把业务层的东西放到dao层里面,也就是你所说把hql封装起来的函数级别的复用其实是低级的复用,把hql和此hql对应的方法逻辑封装到一起,形成services级别的复用才是最好的解决方案。
17 楼 downpour 2010-04-20  
你认为DAO没有存在的必要性,主要是因为你做的项目还不够复杂。

在一个Service调用中,业务逻辑可能会包含十几次的数据库调用,其中有一半需要用HQL。你告诉我你把这些HQL全部写在Service层,那么你的Service层就会膨胀不堪,代码就会变得不可读。DAO层的出现,可以把这些HQL的数据库调用封装起来,让你的代码更加简洁。同时,这些被封装的函数,可以被反复调用。

HQL或者SQL写在配置文件里面是一种非常错误的做法。项目很大的时候,你会发现你的配置文件中充斥着非常类似的HQL或者SQL。同时,在你进行debug调试的时候,由于你拿到的是一个Key,增加了一个根据Key到配置文件去拿HQL的动作,从而给调试带来不便。
16 楼 slaser 2010-04-20  
jackerxff 写道
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="transactionManager"       class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

然后
   @Resource protected HibernateTemplate hibernateTemplate;
   可以让BaseDAOImpl的子类也可以使用hibernateTemplate

this.hibernateTemplate.findByCriteria(DetachedCriteria.forClass(entityclass));
Hibernate提供的DetachedCriteria 可以在没有Session的情况下组装查询条件,这样将HQL转换为QBC,业务就可以脱离DAO,在Service层写好DetachedCriteria再统一使用hibernateTemplate.findByCriteria进行处理,感觉这样比较好

So,直接把hibernateTemplate放service里面好了,简单易用,维护方便。
15 楼 jackerxff 2010-04-20  
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="transactionManager"       class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

然后
   @Resource protected HibernateTemplate hibernateTemplate;
   可以让BaseDAOImpl的子类也可以使用hibernateTemplate

this.hibernateTemplate.findByCriteria(DetachedCriteria.forClass(entityclass));
Hibernate提供的DetachedCriteria 可以在没有Session的情况下组装查询条件,这样将HQL转换为QBC,业务就可以脱离DAO,在Service层写好DetachedCriteria再统一使用hibernateTemplate.findByCriteria进行处理,感觉这样比较好
14 楼 slaser 2010-04-20  
aaa5131421 写道
downpour 写道
aaa5131421 写道

正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。


你的理解是错的。

DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。

如果我不是需要经常再不改动代码的情况下改动hql的需求,我会直接放在业务逻辑类里面。这是最理想的位置
谁说hql是属于dao层的呢?hql是属于业务逻辑的,它经hibernate转换后成变成的sql才属于dao层里面的东西。而hibernate的这个转化过程就是你在“调用dao层”
我不会直接写sql的,这违背hibernate本意,如果hql等。。实在满足不了需求,写sql是必然,但一个项目中这样的位置不会超过两处,这是技术上的问题,如果非要为这两处封装一个dao,得不偿失,假如需要写很多hql满足不了的sql,也可以考虑自己写个补充hibernate的hql解释器,而不是直接写sql并将他放在代码里面。

hql确实是业务层的东西,这个应该写在service里面,必须的sql放配置没什么问题,这个比放代码里面更干净,更容易调试。dao是jdbc时代遗留产物,不过为每一个sql的执行和把执行结果放入对象这样的操作做一个命名而已。在使用hibernate,jpa同时大量使用dao,才是一个很差的实践。所谓很薄的dao,为什么不直接用session或者jpa里面的entityManager代替,封装一下减少功能很有意思么?
13 楼 aaa5131421 2010-04-20  
downpour 写道
aaa5131421 写道

正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。


你的理解是错的。

DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。

如果我不是需要经常再不改动代码的情况下改动hql的需求,我会直接放在业务逻辑类里面。这是最理想的位置
谁说hql是属于dao层的呢?hql是属于业务逻辑的,它经hibernate转换后成变成的sql才属于dao层里面的东西。而hibernate的这个转化过程就是你在“调用dao层”
我不会直接写sql的,这违背hibernate本意,如果hql等。。实在满足不了需求,写sql是必然,但一个项目中这样的位置不会超过两处,这是技术上的问题,如果非要为这两处封装一个dao,得不偿失,假如需要写很多hql满足不了的sql,也可以考虑自己写个补充hibernate的hql解释器,而不是直接写sql并将他放在代码里面。
12 楼 downpour 2010-04-19  
aaa5131421 写道

正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。


你的理解是错的。

DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。
11 楼 bavnnsym 2010-04-19  
不喜欢注解
特别那些刚刚接触框架的就学注解,,,虽然能看到最后的效果。。。其实很多根本不知道到底是怎么一回事。。。。
10 楼 aaa5131421 2010-04-19  
slaser 写道
whaosoft 写道
star022 写道
这年头 还这么多人玩DAO啊~~!

为什么不玩DAO了啊?

DAO没什么意义。
1.我只用hibernate。
2.我不换数据库。
3.sql和hql大部分写配置文件里面。
如此为什么不直接把session注入到service里面直接操作?

正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。
9 楼 Angel_Night 2010-04-19  
其实用hibernate 还老老实实写dao的不多吧

多数人都是自己封装个baseDao 然后注入到service...
8 楼 slaser 2010-04-19  
whaosoft 写道
star022 写道
这年头 还这么多人玩DAO啊~~!

为什么不玩DAO了啊?

DAO没什么意义。
1.我只用hibernate。
2.我不换数据库。
3.sql和hql大部分写配置文件里面。
如此为什么不直接把session注入到service里面直接操作?
7 楼 whaosoft 2010-04-19  
star022 写道
这年头 还这么多人玩DAO啊~~!

为什么不玩DAO了啊?
6 楼 xhbyy 2010-04-19  
怎么这么多人喜欢用注解呢? 配置文件的作用是什么,就是为了可扩展性,注解写在类里,和直接用new的有什么区别?  你的DAO配置里就不能加个属性parent="BaseDao"吗?
5 楼 star022 2010-04-19  
这年头 还这么多人玩DAO啊~~!

相关推荐

Global site tag (gtag.js) - Google Analytics