RSS

Open Session in View模式 & 泛型DAO模式

31 Jan

Open Session in View (OSIV)

在控制层使用Hibernate,在表示层执行,有时会抛出异常,原因是延迟加载不能把所有关联都读出来 – org.hibernate.LazyInitializationException

一种方案是关闭Hibernate的延迟加载,当前持久化对象和其关联的对象都加载

另一种方案是延长Hibernate的Session对象的生命周期 – 在表现层显示完所有数据再关闭Session,相当于下面的代码:

//假设一下代码在控制层执行

Session session = sessionFactory.getCurrentSession();

Transaction tx = session.beginTransaction();

GuestBook gb = (GuestBook) session.load(GuestBook.class, new Integer(1));
//…

接着下面的代码在表示层执行

System.out.println(gb.getEmail());

System.out.println(gb.getTitle());

tx.commit();
=============================================================================================
使用Servlet过滤器实现OSIV模式

使用Servlet过滤器实现自己的OSIV模式。当用户像一个JSP页面或者Servlet发出请求的时候开启Session对象,在JSP页面或者Servlet执行后,再关闭Session对象。

HibernateSessionFilter.java
package hibernate.example.filter;

import hibernate.example.util.HibernateSessionFactoryUtil;

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.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

publicclass HibernateSessionFilter implements Filter {

private Transaction tx = null;

private SessionFactory sessionFactory = null;

public HibernateSessionFilter() {

}

publicvoid destroy() {

sessionFactory.close();

}

publicvoid doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

try {

Session session = sessionFactory.getCurrentSession();

tx = session.beginTransaction();

chain.doFilter(request, response);

tx.commit();

} catch (Exception e) {

e.printStackTrace();

if (tx.isActive()) {

tx.rollback();

}

}

}

publicvoid init(FilterConfig fConfig) throws ServletException {

sessionFactory = HibernateSessionFactoryUtil.getSessionFactory();

}

}

AdminUserServlet.java
package hibernate.example.servlet;
import hibernate.example.dao.AdminDAO;
import hibernate.example.dao.hibernate.AdminDAOHibernate;
import hibernate.example.util.StringUtil;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

publicclass AdminUserServlet extends HttpServlet {

privatestaticfinallongserialVersionUID = 1L;

public AdminUserServlet() {

super();

}

protectedvoid doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

doPost(request, response);

}

protectedvoid doPost(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

String method = request.getParameter(“q”);

if (method != null && method.equals(“login”)) {

login(request, response);

} else {

logout(request, response);

}

}

publicvoid login(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String username = request.getParameter(“username”);

String password = request.getParameter(“password”);

String message = null;

if (StringUtil.validateNull(username)) {

message = “Username cannot be blank!”;

request.setAttribute(“guestbook.admin.login.message”, message);

request.getRequestDispatcher(“/admin/loginFail.jsp”).forward(

request, response);

} elseif (StringUtil.validateNull(password)) {

message = “Password cannot be blank!”;

request.setAttribute(“guestbook.admin.login.message”, message);

request.getRequestDispatcher(“/admin/loginFail.jsp”).forward(

request, response);

} else {

AdminDAO dao = new AdminDAOHibernate();

if (dao.validateLogin(username, password) == null) {

message = “Please verify your Username and Password!”;

request.setAttribute(“guestbook.admin.login.message”, message);

request.getRequestDispatcher(“/admin/loginFail.jsp”).forward(

request, response);

} else {

HttpSession session = request.getSession();

session.setAttribute(“guestbook.admin.username”, username);

request.getRequestDispatcher(“/admin/secure/manage?q=list”)

.forward(request, response);

}

}

}

publicvoid logout(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

HttpSession session = request.getSession();

session.removeAttribute(“guestbook.admin.username”);

response.sendRedirect(request.getContextPath() + “/admin/login.jsp”);

}

}

AdminDAO.java
package hibernate.example.dao;

import hibernate.example.vo.Admin;

publicinterface AdminDAO {

public Admin validateLogin(String username, String password);

}

AdminDAOHibernate.java
package hibernate.example.dao.hibernate;

import java.util.List;

import org.hibernate.Query;

import org.hibernate.Session;

import hibernate.example.dao.AdminDAO;

import hibernate.example.util.HibernateSessionFactoryUtil;

import hibernate.example.vo.Admin;

publicclass AdminDAOHibernate extends GenericDAOHibernate<Admin, Integer>

implements AdminDAO {

@Override

public Admin validateLogin(String username, String password) {

Session session = HibernateSessionFactoryUtil.getSessionFactory()

.getCurrentSession();

Query query = session

.createQuery(“FROM Admin a WHERE a.username=? AND a.password = ?”);

query.setString(0, username);

query.setString(1, password);

@SuppressWarnings(“unchecked”)

List<Admin> list = query.list();

if (list.size() == 0) {

returnnull;

} else {

return list.get(0);

}

}

}

=============================================================================================
泛型DAO的设计与实现

如果有10个POJO类,就需要创建10个DAO进行CRUD操作,可能有很多基本的CRUD的操作是相同的,使用泛型DAO设计模式可以提供一个泛型话的DAO的接口及实现类,在这个接口及实现类实现通用的要实现的方法,再去编写具体的持久化DAO不需要再去实现这些方法,直接继承这些接口和类来完成。

GenericDAO.java
package hibernate.example.dao;

import java.io.Serializable;

import java.util.List;

publicinterface GenericDAO<T, PK extends Serializable> {

public T findById(PK id);

public List<T> findAll();

public T save(T entity);

publicvoid update(T entity);

publicvoid delete(T entity);

}

GenericDAOHibernate.java
package hibernate.example.dao.hibernate;

import java.io.Serializable;

import java.lang.reflect.ParameterizedType;

import java.util.List;

import org.hibernate.Query;

import org.hibernate.Session;

import hibernate.example.dao.GenericDAO;

import hibernate.example.util.HibernateSessionFactoryUtil;

publicclass GenericDAOHibernate<T, PK extends Serializable> implements

GenericDAO<T, PK> {

private Class<T> clazz;

@SuppressWarnings(“unchecked”)

public GenericDAOHibernate() {

// 通过反射擦拭法获取泛型参数的真正类型

clazz = (Class<T>) ((ParameterizedType) getClass()

.getGenericSuperclass()).getActualTypeArguments()[0];

}

@SuppressWarnings(“unchecked”)

@Override

public T findById(PK id) {

Session session = HibernateSessionFactoryUtil.getSessionFactory()

.getCurrentSession();

return (T) session.get(clazz, id);

}

@SuppressWarnings(“unchecked”)

@Override

public List<T> findAll() {

Session session = HibernateSessionFactoryUtil.getSessionFactory()

.getCurrentSession();

Query query = session.createQuery(“FROM “ + clazz.getName());

return query.list();

}

@Override

public T save(T entity) {

Session session = HibernateSessionFactoryUtil.getSessionFactory()

.getCurrentSession();

session.save(entity);

return entity;

}

@Override

publicvoid update(T entity) {

Session session = HibernateSessionFactoryUtil.getSessionFactory()

.getCurrentSession();

session.update(entity);

}

@Override

publicvoid delete(T entity) {

Session session = HibernateSessionFactoryUtil.getSessionFactory()

.getCurrentSession();

session.delete(entity);

}

}

Advertisements
 
Leave a comment

Posted by on 01/31/2011 in HIBERNATE

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

 
%d bloggers like this: