Spring JDBCTemplate与Hiberante混用

就像我们知道的一样,Hibernate是ORM领域事实上的标准,它在操作数据库方面,提供了最大程度的遍历与快捷,而hibernate与 spring的结合,更是将这种便利发挥到了极致,这其中得益于HibernateDaoSupport 和HiberateTemplate以及HibernateTransation的大力支持.简单的来说,有了spring,使得使用Hibernate 的时候,更简洁,更便利,而统一的声明事务,又让本来就已经很简洁的Hibernate对事务的处理,大大简化.这其中,得益于AOP思想的应用.可以 说,有了Spring之后,Hibernate就像插上了翅膀,转化为软件开发人员手中一件天使一般的工具.不能不说,这是我们这个时代的一个骄傲.
     但任何事务都有两面性,在带来大量便捷的同时,Hibernate也给我们留下了一点小小的遗憾,比如众所周知的,在处理大批量数据查询的时 候,Hibernate的查询效率,是不尽人意的,有人做过测试,在高并发查询的时候,hibernate的查询效率,仅仅相当于使用jdbc效率7成左 右,这对于对速度有着很高要求的互联网应用来说,不能不说是悲剧.尽管有存在有各种各样的缓存解决方案,但还是在高并发查询下,让人们对 hibernate的性能,捏了一把汗.同时,hibernate在查询的时候,所带来的n+1问题,也一直让人所诟病.
    进而在批量操作方面,比如在早期,在没有使用jdbc3.0的batch update的时候,hibernate的批量删除,是让人很头痛的, 甚至是一条记录的删除,也不能做到像jdbc一样让人满意.
     所以,在我们的项目框架中,混合使用hibernate与jdbc,各自发挥各自的优势与长处,弥补对方的缺陷,提高系统的响应速度.但是需要注意 的时, jdbcTemplate的HibernateTemplate混合使用的时候,要注意其混合事务的处理.
      正如我们以前的项目一样,一开始在项目中使用的是JDBCTemplate,为了提高开发效率决定采用Hibernate,但是发现Hibernate 在做批量操作时,效率不是很理想。所以现在采用JDBCTemplate和Hibernate混用,JDBCTemplate和Hibernate混用是 可以的,有几个注意事项. 

1.如果采用JDBCTemplate的部分只涉及到查询,则可以使用Hibernate的应用缓存,即二级缓存. 

2.如果采用JDBCTemplate的部分涉及到对数据库的更新操作,即增,删,改.则不能开启Hibernate的二级缓存,如果系统有缓存的需要, 我觉得可以自己在逻辑层实现缓存.Java的缓存方案还是很多的. 

3.在使用Spring做为容器的系统中,混用JDBCTemplate和Hibernate,事务管理请统一使用 HibernateTransactionManager,前提是JDBCTemplate和Hibernate共用一个DataSource. 
在HibernateTransactionManager的类说明中有一段原话

This transaction manager is appropriate for applications that use a single Hibernate SessionFactory for transactional data access, but it also supports direct DataSource access within a transaction (i.e. plain JDBC code working with the same DataSource). This allows for mixing services which access Hibernate and services which use plain JDBC (without being aware of Hibernate)! Application code needs to stick to the same simple Connection lookup pattern as with DataSourceTransactionManager (i.e. DataSourceUtils.getConnection(javax.sql.DataSource) or going through a TransactionAwareDataSourceProxy).
复制代码


从代码的角度上看也是可以混用的.事务可以统一管理。HibernateTransactionManager的doBegin方法中有这么一段代码

1    // add the Hibernate transaction to the session holder
2    txObject.getSessionHolder().setTransaction(session.beginTransaction());
3    // register transaction timeout
4    if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT)

6    {
7       txObject.getSessionHolder().setTimeoutInSeconds(definition.getTimeout());
8    }
9    // bind the session holder to the thread
10    if (txObject.isNewSessionHolder())
11    {
12        TransactionSynchronizationManager.bindResource(this.sessionFactory,      txObject.getSessionHolder());
13    }
14    // register the Hibernate Session's JDBC Connection for the DataSource, if set
15    if (this.dataSource != null)
16 
17    {
18      ConnectionHolder conHolder = new ConnectionHolder(session.connection());
19      if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT)
20      {
21           conHolder.setTimeoutInSeconds(definition.getTimeout());
22      }
23     TransactionSynchronizationManager.bindResource(this.dataSource, conHolder);
24    }
25
复制代码

26   
注意这一注释  register the Hibernate Session's JDBC Connection for the DataSource, if set

你可能感兴趣的:(Spring)