hibernate系列十三:0penSessionlnView模式

在Java Web应用中,通常需要调用Hibernate API获取到要显示的某个对象并传给相应的视图JSP,并在JSP中从这个对象导航到与之关联的对象或集合数据。这些关联对象或集合数据如果是被延迟加载的,Hibernate就会抛出LazylnitializationException。因为在调用完FIibernate后,Session对象已经关闭了。针对这个问题,Hibernate社区提出了OpenSessionlnView模式作为解决方案。这个模式的主要思想是:在用户的每一次请求过程中始终保持一个Session对象打开。

    OpenSessionlnView模式的具体实现有以下三个步骤:

    第一步:把Session绑定到当前线程上,要保证在一次请求中只有一个Session对象。先在DAO包中创建HibernateUtil类。在程序代码中获取Session对象时,使用HibernateUtil.currentSession()方法。这样,可以保证每一次请求的处理线程上只有一个Session对象存在;关闭Session对象时,使用HibernateUtil.closeSession()方法。

    第二步:用Filter过滤器在请求到达之前打开Session,在响应返回前关闭Session,完整案例如下所示。

============================index.jsp===========================

<body>
    <h1><a href="LoadDemo.do?stuId=115">加载范冰冰的数据</a></h1>
  </body>

=======================StudentDaoImpl.java======================

package com.obtk.dao;

import org.hibernate.HibernateException;
import org.hibernate.Session;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class StudentDaoImpl implements StudentDao {
	public StudentEntity getStuById(Integer stuId) {
		StudentEntity stu=null;
		Session session=null;
		try {
			session=HiberUtil.getSession();
			System.out.println("dao:"+session.hashCode());
			//延迟加载的报错
			stu=(StudentEntity)session.load(StudentEntity.class, stuId);
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		return stu;
	}
}


=============================LoadDemoServlet.java======================

package com.obtk.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.obtk.dao.StudentDao;
import com.obtk.dao.StudentDaoImpl;
import com.obtk.entitys.StudentEntity;

public class LoadDemoServlet extends HttpServlet {

	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doPost(request,response);
	}

	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String stuIdStr=request.getParameter("stuId");
		Integer stuId=Integer.parseInt(stuIdStr);
		StudentDao stuDao=new StudentDaoImpl();
		try {
			StudentEntity stu=stuDao.getStuById(stuId);
			request.setAttribute("theStu", stu.getStuId()+stu.getStuName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		request.getRequestDispatcher("/ShowInfo.jsp").forward(request, response);
	}



}
=======================OpenSessionInViewFilter.java==========================

package com.obtk.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.hibernate.HibernateException;
import org.hibernate.Session;

import com.obtk.utils.HiberUtil;

public class OpenSessionInViewFilter implements Filter {
	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			//和dao层获得的session是一个session
			System.out.println("filter:"+session.hashCode());
			System.out.println("请求开始了...");
			arg2.doFilter(arg0, arg1);  //执行请求
			System.out.println("请求结束了");
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();//在请求结束了再关闭连接,解决延迟加载的问题
		}
		
	}

	public void destroy() {
	}

	public void init(FilterConfig arg0) throws ServletException {		
	}
}

=======================ShowResult.jsp======================

<body>
    <h2>查看数据:${requestScope.theStu }</h2>
  </body>

=======================web.xml=======================

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  
  <filter>
  	<filter-name>OpenSessionInView</filter-name>
  	<filter-class>com.obtk.filters.OpenSessionInViewFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>OpenSessionInView</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet>
    <description>test</description>
    <display-name>test</display-name>
    <servlet-name>LoadDemoServlet</servlet-name>
    <servlet-class>com.obtk.servlets.LoadDemoServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>LoadDemoServlet</servlet-name>
    <url-pattern>/LoadDemo.do</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

由OpenSessionInViewFilter这个过滤器就能完美的解决延迟加载带来的问题。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

御前两把刀刀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值