一 、在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