Hibernate的OpensessionInView模式

tech2022-11-01  126

一 、在javaweb中使用hibernate实现DAO,出现关联方数据在视图层加载的问题。

解决办法:

把关联方的加载方式,改为lazy=false, 即时加载使用OpenSessionInView模式,在视图层重新打开session,访问数据库。

二 、OpenSessionInView模式的实现原理: 首先要使用getCurrentSession打开session openSession和getCurrentSession方法的区别:

openSession 从字面上可以看得出来,是打开一个新的session对象,而且每次使用都是打开一个新的session,假如连续使用多次,则获得的session不是同一个对象,并且使用完需要调用close方法关闭session。

getCurrentSession,从字面上可以看得出来,是获取当前上下文一个session对象,当第一次使用此方法时,会自动产生一个session对象,并且连续使用多次时,得到的session都是同一个对象, 这就是与openSession的区别之一, 简单而言,getCurrentSession 就是:如果已经存在,就用旧的,如果没有,建新的。 不用手动关闭session,在事务提交后,会自动关闭。 要求增删改查都要有事务环境

实现的步骤: 1.实现OpenSessonInViewFilter

public class OpenSessionInViewFilter implements Filter { @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Transaction tx = null; try { Session session = HibernateSessionUtils.getSessionFactory().getCurrentSession(); tx = session.beginTransaction(); //往下访问资源: 访问下一个过滤器,或者到目标资源 chain.doFilter(request, response); tx.commit(); } catch (HibernateException e) { tx.rollback(); e.printStackTrace(); } } @Override public void destroy() { // TODO Auto-generated method stub } }

2.过滤器的配置

<filter> <filter-name>opensession</filter-name> <filter-class>com.gec.hiber.utils.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>opensession</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

3.Hibernate.cfg.xml指定session的上下文

<property name="current_session_context_class">thread</property>

4.优化DAO的实现,获取Session的方式必须和filter相同。增删改查都要有事务环境。

public Session getSession() { return HibernateSessionUtils.getSessionFactory().getCurrentSession(); } @Override public List<Emp> findAll() { List<Emp> list = this.getSession().createCriteria(Emp.class).list(); return list; }

三 、综合案例

技术 : hibernate + servlet/jsp数据库: 使用反向工程生成双向一对多的关系。使用OpenSessionInView模式实现DAO

FilmInfoDao 主要的方法: 添加电影信息 addFilm(); 组合查询电影信息 searchFilmByCondition(); 要求使用QBC查询

FilmTypeDao 主要方法: 查询所有电影类别: findAllFilmType();

Servlet的实现 FilmSearchServlet FilmAddServlet

JSP

最新回复(0)