论坛首页 Java企业应用论坛

Hibertnate与JDBC混合使用

浏览 7409 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (2)
作者 正文
   发表时间:2010-06-07   最后修改:2010-07-14

Hibernate与JDBCtemplate如何混用?
一开始在项目中使用的是Hibernate,但是发现Hibernate在做批量操作时,效率不是很理想。所以现在采用JDBCTemplate和Hibernate混用,现在问题是如何配置他们的事务?
两者都用同一个datasource ,同一spring管理事务就没有问题。

 

另外要注意两点:

1. 由于Spring JDBC 框架,它没有采用服务层缓存技术,所以可以使用 DAO 类返回数据库中的数据。如果采用 Hibernate 等 ORM 框架,由于它们采用了服务层缓存的技术,为了获取数据库中的相应数据,需要在业务方法执行后调用 HibernateTemplate.flush() 方法,将缓存中的对象同步到数据库中,这时才可以通过 SimpleJdbcTemplate 在数据库中访问业务方法的执行情况。

2. 使用hibernateTransaction manager ,才可以保证混用时候的事务。

 

补充:HibernateTransactionManager实际上是可以同时管理由JdbcTemplate或JdbcDaoSupport实现的dao以及HibernateTemplate或HibernateDaoSupport实现的事务的。

 


Spring 提供了一个能从当前事务上下文中获取绑定的数据连接的工具类,那就是 DataSourceUtils。Spring 强调必须使用 DataSourceUtils 工具类获取数据连接,Spring 的 JdbcTemplate 内部也是通过 DataSourceUtils 来获取连接的。DataSourceUtils 提供了若干获取和释放数据连接的静态方法,说明如下:

  • static Connection doGetConnection(DataSource dataSource) : 首先尝试从事务上下文中获取连接,失败后再从数据源获取连接;
  • static Connection getConnection(DataSource dataSource) : 和 doGetConnection 方法的功能一样,实际上,它内部就是调用 doGetConnection 方法获取连接的;
  • static void doReleaseConnection(Connection con, DataSource dataSource) :释放连接,放回到连接池中;
  • static void releaseConnection(Connection con, DataSource dataSource) :和 doReleaseConnection 方法的功能一样,实际上,它内部就是调用 doReleaseConnection 方法获取连接的;

来看一下 DataSourceUtils 从数据源获取连接的关键代码:

public abstract class DataSourceUtils {
    …
    public static Connection doGetConnection(DataSource dataSource) throws SQLException {
        
		Assert.notNull(dataSource, "No DataSource specified");

        //①首先尝试从事务同步管理器中获取数据连接
        ConnectionHolder conHolder = 
            (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
        if (conHolder != null && (conHolder.hasConnection() || 
            conHolder.isSynchronizedWithTransaction())) { 
            conHolder.requested();
            if (!conHolder.hasConnection()) {
                logger.debug(
                    "Fetching resumed JDBC Connection from DataSource");
                conHolder.setConnection(dataSource.getConnection());
            }
			return conHolder.getConnection();
		}
        
		//②如果获取不到,则直接从数据源中获取连接
        Connection con = dataSource.getConnection();

        //③如果拥有事务上下文,则将连接绑定到事务上下文中
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            ConnectionHolder holderToUse = conHolder;
            if (holderToUse == null) {
				holderToUse = new ConnectionHolder(con);
			}
			else {holderToUse.setConnection(con);}
            holderToUse.requested();
			TransactionSynchronizationManager.registerSynchronization(
                new ConnectionSynchronization(holderToUse, dataSource));
			holderToUse.setSynchronizedWithTransaction(true);
			if (holderToUse != conHolder) {
				TransactionSynchronizationManager.bindResource(
                dataSource, holderToUse);
			}
		}
		return con;
	}
    …
}


 

另外还有hibernate的SessionFactoryUtils(iBatis同Jdbc).

 

关于JdbcTemplate的使用可以参考下面的一篇文章:

使用 freemarker 创建动态 SQL

 


 

 

 

   发表时间:2010-06-08  
还不如 Hibernate 的 SQLQuery 呢?
0 请登录后投票
   发表时间:2010-06-08  
为什么不用ibatis呢
0 请登录后投票
   发表时间:2010-06-08  
菜菜菜 写道
为什么不用ibatis呢

同意,既然都使用了这种搭配为什么不使用ibatis呢?
0 请登录后投票
   发表时间:2010-06-08  
给你帖一个我写的方法
public Object excuteBySql(final String sql,final Object[] para){
return this.getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session) {
SQLQuery sqlQuery=session.createSQLQuery(sql);
if(null!=para&&para.length!=0)  bindProperties(sqlQuery,para);
return sqlQuery.executeUpdate();
}
});
}

这样不就能用JDBC进行批量操作了么
0 请登录后投票
   发表时间:2010-06-08   最后修改:2010-06-08
封装jdbc方法 在继承了 HibernateTemplate  方法
0 请登录后投票
   发表时间:2010-06-08  
joinsky 写道
还不如 Hibernate 的 SQLQuery 呢?

性能紧要而Hibernate又无法满足要求时,才使用JDBCTemplate。
0 请登录后投票
   发表时间:2010-06-08  
左看右看 写道
菜菜菜 写道
为什么不用ibatis呢

同意,既然都使用了这种搭配为什么不使用ibatis呢?


项目中还是尽量使用Hibernate的,只有一些非常必要的场合才使用了JDBC,
而且Spring的JDBCTemplate已经提供了很好的封装,还可以写一些动态的SQL文(使用freemarker创建动态SQL:http://tivan.iteye.com/blog/686297);
另外还有就是这个是在维护的时候添加的JDBC功能,也就没有添加ibatis。

如果是项目初期的话应该考虑ibatis与JDBCTemplate做个比较。
0 请登录后投票
   发表时间:2010-07-15  
可以考虑在每个Dao依然作为HibernateDao的子类,然后在需要的时候直接使用JDBC的DAO中注入一个SimpleJdbcTemplate
0 请登录后投票
论坛首页 Java企业应用版

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