读书人

Hibertnate与JDBC混同使用

发布时间: 2012-11-20 09:55:43 作者: rapoo

Hibertnate与JDBC混合使用

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的使用可以参考下面的一篇文章:

?


?

?

?

1 楼 joinsky 2010-06-08 还不如 Hibernate 的 SQLQuery 呢? 2 楼 菜菜菜 2010-06-08 为什么不用ibatis呢 3 楼 左看右看 2010-06-08 菜菜菜 写道为什么不用ibatis呢
同意,既然都使用了这种搭配为什么不使用ibatis呢? 4 楼 huatu122 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进行批量操作了么 5 楼 wm920 2010-06-08 封装jdbc方法 在继承了 HibernateTemplate 方法 6 楼 tivan 2010-06-08 joinsky 写道还不如 Hibernate 的 SQLQuery 呢?
性能紧要而Hibernate又无法满足要求时,才使用JDBCTemplate。 7 楼 tivan 2010-06-08 左看右看 写道菜菜菜 写道为什么不用ibatis呢
同意,既然都使用了这种搭配为什么不使用ibatis呢?

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

如果是项目初期的话应该考虑ibatis与JDBCTemplate做个比较。 8 楼 JetMah 2010-07-15 可以考虑在每个Dao依然作为HibernateDao的子类,然后在需要的时候直接使用JDBC的DAO中注入一个SimpleJdbcTemplate

读书人网 >其他数据库

热点推荐