第五章Hibernate -OSIV与泛型DAO模式
使用Servlet过滤器实现OSIV模式
1.编写泛型DAO接口
2.编写泛型DAO的实现类
3.使用GenericDao接口
4.使用GenericDaoHibernate类
我们使用servlet过滤器来实现自己的OSIV模式。当用户向一个JSP页面或者Servlet发出请求的时候开启Session对象,在JSP页面或者Servlet执行之后,在关闭Session对象。
编写HibernateSessionFilter.java
public class HibernateSessionFilter implements Filter { private Transaction transaction = null; private SessionFactory sessionFactory = null; public void destroy() { sessionFactory.close(); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try{ Session session = sessionFactory.getCurrentSession(); transaction = session.beginTransaction(); chain.doFilter(request, response); transaction.commit(); }catch(Exception e){ e.printStackTrace(); try{ if(transaction.isActive()){ transaction.rollback(); } } catch(Exception e2){ e2.printStackTrace(); } } } public void init(FilterConfig arg0) throws ServletException { sessionFactory = new Configuration().configure().buildSessionFactory(); } }
配置web.xml
<filter> <filter-name>HibernateSessionFilter</filter-name> <filter-class>com.crazy.HibernateSessionFilter</filter-class> </filter> <filter-mapping> <filter-name>HibernateSessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
1 编写泛型DAO接口
2 编写泛型DAO的实现类
3 GenericDao.java
4 GenericDaoHibernate.java
public interface GenericDao<T,PK extends Serializable> { public T findById(PK id); public List<T> findAll(); public T save(T entity); public void update(T entity); public void delete(T entity); }
public class GenericDaoHibernate<T, PK extends Serializable> implements GenericDao<T,PK> { private Class<T> clazz; public GenericDaoHibernate(){ clazz = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } public void delete(T entity) { Session session = new Configuration().configure().buildSessionFactory().openSession(); session.delete(entity); } public List findAll() { Session session = new Configuration().configure().buildSessionFactory().openSession(); Query query = session.createQuery("from" +clazz.getName()); return query.list(); } public T findById(PK id) { Session session = new Configuration().configure().buildSessionFactory().openSession(); return (T)session.get(clazz, id); } public T save(T entity) { Session session = new Configuration().configure().buildSessionFactory().openSession(); session.save(entity); return entity; } public void update(T entity) { Session session = new Configuration().configure().buildSessionFactory().openSession(); session.update(entity); } }
由于Java中的泛型采用擦拭方法,因此无法直接通过反射获取到T.class。而getGenericSuperclass()方法会返回一个ParameterizedType对象,这个对象保存负累的泛型绑定参数的类型,所以通过该对象即可获取T.class。
public interface GuestbookDao extends GenericDao <Guestbook,Integer> { public List<Guestbook> findAllOrderById(); }
public class GuestbookDaoHibernate extends GenericDaoHibernate<Guestbook,Integer> implements GuestbookDao{ public List<Guestbook> findAllOrderById() { Session session = new Configuration().configure().buildSessionFactory().openSession(); Query query = session.createQuery("from Guestbook order by id desc"); return query.list(); } }