学习日记(五)getHibernateTemplate()与getSession()的理解

一、(参考猛戳即到
自动生成hibernate配置文件的时候,会在dao层用到getSession()方法来操作数据库记录,但是他还有个方法getHibernateTemplate(),这两个方法究竟有什么区别呢?
1.使用getSession()方法你只要继承sessionFactory,而使用getHibernateTemplate()方法必须继承 HibernateDaoSupport当然包括sessionFactory,这点区别都不是特别重要的,下面这些区别就很重要了
2.getSession()方法是没有经过spring包装的,spring会把最原始的session给你,在使用完之后必须自己调用相应的 close方法,而且也不会对声明式事务进行相应的管理,一旦没有及时关闭连接,就会导致数据库连接池的连接数溢出,getHibernateTemplate()方法是经过spring封装的,例如添加相应的声明式事务管理,由spring管理相应的连接。
在实际的使用过程中发现的确getHibernateTemplate()比getSession()方法要好很多,但是有些方法在getHibernateTemplate()并没有提供,这时我们用HibernateCallback 回调的方法管理数据库.
例如如下代码:
/**      * 使用 hql 语句进行操作      * @param hql HSQL 查询语句(使用回调函数访问外部变量,必须是final的)      * @param offset 开始取数据的下标     * @param length 读取数据记录数     * @return List 结果集 */ public List getListForPage ( final String hql , final int offset , final int length ) {
              List list = getHibernateTemplate().executeFind ( new HibernateCallback ( ) {                             public Object doInHibernate ( Session session ) throws HibernateException, SQLException {                                             Query query = session.createQuery ( hql ) ;                                             query.setFirstResult ( offset ) ;                                             query.setMaxResults ( length ) ;                                             List list = query.list ( ) ;                                             return list ;                            }                }) ;                return list ; } 二、(参考猛戳即到) find(String queryString, Object[] values); 这个方法后者的参数必须是一个数组,而不能是一个List。 List ul=getHibernateTemplate().find("from User u where u.username=? and u.password=?",new String[]{user,pass}); 其中User是对应的类名,不是数据库中的表名。 如何访问数据库?我们有两个选择: getSession().createQuery("from Users"); getHibernateTemplate().find( "FROM Users); 用哪个呢?困惑啊。 网上找了找资料都是推荐用getHibernateTemplate,原因说的不是很清楚。 于是做了如下测试:分别循环调用getSession().createQuery("from Users");getHibernateTemplate().find( "FROM Users); 1000次结果getSession()很快就包无法建立连接了。而getHibernateTemplate屁事没有可以跑完。通过后台观察,使用getSession会在数据库中留下很多SQL*Net message from client的连接,终止测试后连接自动释放。而getHibernateTemplate则从头到尾都使用一个连接。难道是getSession()不会自动释放连接?于是我又分别循环调用getSession().createQuery("from Users");getHibernateTemplate().find( "FROM Users); 5次发现当前端程序一结束,getSession的5个连接立刻就释放了。结合前面1000次时终止测试后连接自动释放,可以说明getSession()是会自动释放连接的。 结论: (1)getSession()和getHibernateTemplate都可以自动释放连接(当然你的配置要正确),但是在一个线程内 getSession会get很多个session(就是开很多个会话、连接),很可能导致数据库连接超过上限。所以推荐使用 getHibernateTemplate。 (2)如果有些语句无法用getHibernateTemplate实现,可以使用 getHibernateTemplate.execute使用 HibernateCallback回调接口。另:可以设定HibernateTemplate的AllowCreate为True,并在finally 中关闭Session。也可以将true作为参数传递到super.getSession(..)方法中取得Session。这样也可以,就是麻烦点。 参数绑定 通过顺序占位符?来填充参数: 1)hibernate 2 中通过session.find方法来填充 session.find("from TUser user where user.name=?", "Erica", Hibernate.STRING); 多个参数的情况: Object[] args = new Object[] {"Erica", new Integer(20)}; Type[] types = new Type{Hibernate.STRING, Hibernate.INTEGER}; session.find("from TUser user where user.name=? and user.age=?", args, types); 2)通过Query接口进行参数填充: Query query = session.createQuery("from TUser user where user.name=? and user.age>?"); query.setString(0,"Erica"); query.setInteger(1, 20); 通过引用占位符来填充参数: String hql = "from TUser where name=:name"; Query query = session.createQuery(hql); query.setParameter("name","Erica"); 如何把两个时间类型的参数传递到find的第二个参数 public List findAll(Date begin, Date end) throws Exception { String hql="from Salebill where saleDate bewteen ? and ?"; Object[] value={begin,end}; List list = this.getHibernateTemplate().find(hql, value); return list; } List moreCats = this.getHibernateTemplate().find( "from Cat as cat where " + "cat.name = 'Fritz' or cat.id = ? or cat.id = ?", new Object[] { id1, id2 }, new Type[] { Hibernate.LONG, Hibernate.LONG } ); public AuctionUser findUserByItemAndPrice(Integer itemId , Double price) { Object[] args = {itemId , price} ; List l = getHibernateTemplate().find("from Bid as bid where bid.bidItem.id = ? and bid.bidPrice = ?",args); if (l.size() >= 1) { Bid b = (Bid)l.get(0); return b.getBidUser(); } else { return null; } }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值