`
percy30856
  • 浏览: 132250 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

有关getSession().method()和getHibernateTemplate().method() 差异及用法

阅读更多

偷自  http://blog.csdn.net/yuhua3272004/archive/2009/08/31/4504775.aspx

在网上看到一篇 关于getSession().method()和getHibernateTemplate().method()比较的文章,自己感觉有些
有些偏差(当然这只限我个人的看法对错与否还请各位批评指正),我会在原文各处提出我的看法。引文如下:

在ssh或ssh2中,对数据库进行操作的DAO,都可以通过继承HibernateDaoSupport来实现对数据库的操作.

继承后的实现方式有两种:
super.getSession().A();
getHibernateTemplate().B();
用哪个好呢?
网上都是推荐用getHibernateTemplate,原因是:
getSession()和getHibernateTemplate都可以自动释放连接(当然你的配置要正确),但是在一个线程内,
若同一时间进行很多次的操作(如:1000次查询),getSession 会get很多个session(就是开很多个会话、连接),
很可能导致数据库连接超过上限。所以推荐使用getHibernateTemplate。

<--- 以下是我的看法
若你的配置是 spring2 + hibernate2。
无论是getSession()还是getHibernateTemplate()调用追溯最终会发现,它们都调用了
SessionFactoryUtils的doGetSession(...),首先从TransactionSynchronizationManager管理的本地
线程变量中查找是否存在一个SessionHolder,SessionHolder中是否包含Session,如当前线程没有绑定一个
Session变量,则新建一个Session变量,如下:

 /**
  * Get a Hibernate Session for the given SessionFactory. Is aware of and will
  * return any existing corresponding Session bound to the current thread, for
  * example when using {@link HibernateTransactionManager}. Will create a new
  * Session otherwise, if "allowCreate" is <code>true</code>.
  * <p>Same as {@link #getSession}, but throwing the original HibernateException.
  * @param sessionFactory Hibernate SessionFactory to create the session with
  * @param entityInterceptor Hibernate entity interceptor, or <code>null</code> if none
  * @param jdbcExceptionTranslator SQLExcepionTranslator to use for flushing the
  * Session on transaction synchronization (may be <code>null</code>)
  * @param allowCreate whether a non-transactional Session should be created
  * when no transactional Session can be found for the current thread
  * @return the Hibernate Session
  * @throws HibernateException if the Session couldn't be created
  * @throws IllegalStateException if no thread-bound Session found and
  * "allowCreate" is <code>false</code>
  */
 private static Session doGetSession(
   SessionFactory sessionFactory, Interceptor entityInterceptor,
   SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)
   throws HibernateException, IllegalStateException {

  Assert.notNull(sessionFactory, "No SessionFactory specified");

  SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
  if (sessionHolder != null && !sessionHolder.isEmpty()) {
   // pre-bound Hibernate Session
   Session session = null;
   if (TransactionSynchronizationManager.isSynchronizationActive() &&
     sessionHolder.doesNotHoldNonDefaultSession()) {
    // Spring transaction management is active ->
    // register pre-bound Session with it for transactional flushing.
    session = sessionHolder.getValidatedSession();
    if (session != null && !sessionHolder.isSynchronizedWithTransaction()) {
     logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");
     TransactionSynchronizationManager.registerSynchronization(
       new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false));
     sessionHolder.setSynchronizedWithTransaction(true);
     // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
     // with FlushMode.NEVER, which needs to allow flushing within the transaction.
     FlushMode flushMode = session.getFlushMode();
     if (flushMode.lessThan(FlushMode.COMMIT) &&
       !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
      session.setFlushMode(FlushMode.AUTO);
      sessionHolder.setPreviousFlushMode(flushMode);
     }
    }
   }
   else {
    // No Spring transaction management active -> try JTA transaction synchronization.
    session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator);
   }
   if (session != null) {
    return session;
   }
  }

  logger.debug("Opening Hibernate Session");
  Session session = (entityInterceptor != null ?
    sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession());

  // Use same Session for further Hibernate actions within the transaction.
  // Thread object will get removed by synchronization at transaction completion.
  if (TransactionSynchronizationManager.isSynchronizationActive()) {
   // We're within a Spring-managed transaction, possibly from JtaTransactionManager.
   logger.debug("Registering Spring transaction synchronization for new Hibernate Session");
   SessionHolder holderToUse = sessionHolder;
   if (holderToUse == null) {
    holderToUse = new SessionHolder(session);
   }
   else {
    holderToUse.addSession(session);
   }
   if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
    session.setFlushMode(FlushMode.NEVER);
   }
   TransactionSynchronizationManager.registerSynchronization(
     new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true));
   holderToUse.setSynchronizedWithTransaction(true);
   if (holderToUse != sessionHolder) {
    TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse);
   }
  }
  else {
   // No Spring transaction management active -> try JTA transaction synchronization.
   registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder);
  }

  // Check whether we are allowed to return the Session.
  if (!allowCreate && !isSessionTransactional(session, sessionFactory)) {
   closeSession(session);
   throw new IllegalStateException("No Hibernate Session bound to thread, " +
       "and configuration does not allow creation of non-transactional one here");
  }

  return session;
 }

因此,若在一个线程内,且没有被纳入事务内,getSession()和getHibernateTemplate()是一样的,每次调用它们都会
新建一个Session和新建一个connection。

若已被纳入事物内,它们无论是单独使用还是混合使用都会是使用的同一个session和connection.
我认为上面说法(getSession 会get很多个session ,就是开很多个会话、连接很可能导致数据库连接超过上限。
所以推荐使用getHibernateTemplate。)不对。
--->
 
(1)------------------------------------------
getSession的各种用法:
查询:
super.getSession().find()
super.getSession().createQuery()
保存:
super.getSession().save()
super.getSession().update()
super.getSession().delete()

query的用法:
select,update,delete,分页都可通过Query来执行:
-1->用query的好处,可以像PreparedStatement一样,可以设置参数.
-2->且不用Iterate,因为只是判断有没值,所以,用list.size()判断,若有值,也只有一个,即用list(0)来获取即可
-3->同时,query,不但可用于查询,还可以用于更新:
  String hql = "UPDATE User SET userpwd=? WHERE userid=?";
  Query q = super.getSession().createQuery(hql);
  q.setString(0, userpwd);
  q.setString(1, userid);
  q.executeUpdate();
-4->也可delete:
  String hql = "DELETE FROM Item WHERE itemid=?";
  Query q = super.getSession().createQuery(hql);
  q.setInteger(0, itemid);
  q.executeUpdate();
-5->用query进行分页:
  List all = null;
  String hql = "FROM Question AS q WHERE q.itemid=?";
  Query q = super.getSession().createQuery(hql);
  q.setInteger(0, itemid);
  q.setFirstResult((currentPage - 1) * lineSize);
  q.setMaxResults(lineSize);
  all = q.list();
如:
    Query query = session.createQuery("from User");
    query.setFirstResult(0);//从第一条记录开始
    query.setMaxResults(4);//取出四条记录
    List userList = query.list();

(2)------------------------------------------
hibernateTemplate:
HibernateTemplate的常用方法简介:
      void delete(Object entity):删除指定持久化实例
      deleteAll(Collection entities):删除集合内全部持久化类实例
      find(String ueryString):根据HL查询字符串来返回实例集合
      findByNameduery(String ueryName):根据命名查询返回实例集合
      get(Class entityClass, Serializable id):根据主键加载特定持久化类的实例
      save(Object entity):保存新的实例
      saveOrUpdate(Object entity):根据实例状态,选择保存或者更新
      update(Object entity):更新实例的状态,要求entity是持久状态
      setMaxResults(int maxResults):设置分页的大小
 
常用方法实例:
查询:
//通过HibernateTemplate的find方法返回Person的全部实例 -->返回是list类型
return getHibernateTemplate().find("from Person");
//带参数查询
用这个方法find(String hql,Object para)  -->返回是list类型
String hql = "SELECT u.userName FROM User u WHERE u.userName = ?";
List userList=this.getHibernateTemplate().find(hql,user.getUserName());
//根据主键返回特定实例 -->主键查询  -->返回是对象类型
return (Person)getHibernateTemplate().get(Person.class, new Integer(personid));
return (Person)getHibernateTemplate().load(Person.class, new Integer(personid));
//保存的Person实例
getHibernateTemplate().saveOrUpdate(person);
//删除Person实例的主键
 //先加载特定实例
Object p = getHibernateTemplate().load(Person.class, new Integer(personid));
//删除特定实例
getHibernateTemplate().delete(p);

分享到:
评论

相关推荐

    request.getSession().doc

    request.getSession().doc

    ODI_api_reference

    getAK() method............................................................................................................................ 11 getAKColList() Method........................................

    hibernate的flush机制

    对hibernate的flush机制有兴趣可以看看

    servlet2.4doc

    The default behavior of this method is to call addCookie(Cookie cookie) on the wrapped response object. addCookie(Cookie) - Method in interface javax.servlet.http.HttpServletResponse Adds the ...

    NHibernate Demo

    3.程式中使用只需要打开连接,不需要关闭 4.ISession session = NHibernateHelper.GetSession("HR"); 带参数的需要在Config中增加NHConfigSettings节,格式同AppSettings .GetCurrentSession();不带参数的情况下Web....

    java 中 request.getSession(true、false、null)的区别

    主要介绍了java 中 request.getSession(true/false/null)的区别的相关资料,需要的朋友可以参考下

    request.setAttribute 语句前总显示红色感叹号解决办法 HTTP Status 500 -

    The method setAttribute(String, Object) in the type ServletRequest is not applicable for the arguments (String, double) y2ssh.sg.chp1.action.AddAction.execute(AddAction.java:18) y2ssh.sg.chp1....

    tomcat-redis集群环境所有包

    包含: 1、apache-tomcat-7.0.41-windows-x64免安装 2、Redis-x64-3.2.100.msi (redis安装包windows 64位) 3、tomcat-cluster-redis-session-manager ...4、getsession.jsp 和setsession.jsp 测试session设置和获取

    jsp 对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)

    在网上经常看到有人对request.getSession(false)提出疑问,我第一次也很迷惑,看了一下J2EE1.3 API,看一下官网是怎么解释的。

    java 同一用户不能同时登陆问题

    if (httpssessionmap.containsKey(userid)&&httpssessionmap.get(userid).equals(event.getSession())) { //userIds.remove(userid); httpssessionmap.remove(userid); if(u!=null && userid....

    关于jsp语法和练习

    2. JSP页面需要创建仅在本页面使用的JavaBean的示例,为了完成此功能必须使用jsp:useBean的哪两个属性进行设置?(选择两个选项) A. id B. type C. name D. class E. scope F. create 答案: A, D Scope 默认值为...

    基于servlet的购物车

    //得到书号和书本对象 int bookid =Integer.parseInt(request.getParameter("id")); Map, Book&gt; books = (Map, Book&gt;)request.getSession().getServletContext().getAttribute("books"); Book book = books....

    数据库测试test.sql

    // //根据method属性的值调用相应的方法 // if("login".equals(methodName)){ // this.login(request,response); // }else if("register".equals(methodName)){ // this.register(request,response); // }else if(...

    weChatpay完整版java

    @RequestMapping(value = "/paydispatcher", method = { RequestMethod.GET }) public void payDispatcher(HttpServletRequest request, HttpServletResponse response) throws Exception { String code = ...

    Spring使用技巧

    --------------=======Spring 使用技巧========------------------- 1.在SSH中的DAO中执行SQL //申请变量 Connection conn = null; PreparementStatement ps = null;......(正常执行SQL,使用方法和JDBC使用方法一致)

    网络应用开发 之实现用户登录功能

    学会如何使用Session技术实现用户登录功能。 2、 实验环境 Win10 eclipse 3、 实验内容 应用Session知识及用户登录流程实现用户登录功能模块。 4、 实验结果及分析 1.根据session设置Attribute属性 req....

    购物网站系统

    public class Addcontentservlet extends HttpServlet { public Addcontentservlet(){ super(); } /** * Destruction of the servlet.... */ public void destroy() { ...使用数据库与用户结合

    javaweb 做图片水印,水印图片到目录图片上去

    添加水印方法(水印图片,目标图片),添加在右下角(根据坐标显示) 针对网页图片添加水印,用java语言编写,很简单。 // 获取水印图片的路径 String planeImage = request.getSession().getServletContext()....

    .jsp和servlet验证码

    request.getSession(true).setAttribute("codes", vcode); for (int i = 0; i ; i++) { g2.setFont(new Font("Times New Roman", Font.HANGING_BASELINE, FontSize)); double rot = getRandomJiao(); // 旋转...

Global site tag (gtag.js) - Google Analytics