首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Hibernate单例兑现(Struts1+Hibernate整合)

2012-10-12 
Hibernate单例实现(Struts1+Hibernate整合)大家都知道的一件事情,Hibernate启动时需要加载配置文件,连接数

Hibernate单例实现(Struts1+Hibernate整合)
    大家都知道的一件事情,Hibernate启动时需要加载配置文件,连接数据库并映射对象,这一过程需要大量时间,每次运行测试文件时控制台的反馈已经可以看出来了,那么在整合开发时,必然不能每次数据操作都让Hibernate执行一次这个过程,需要在程序初始化时一并完成,完成这件事情需要单例模式的实现,这一过程是简单的。我们可以如下进行:

package demo;import java.io.Serializable;import org.hibernate.*;import org.hibernate.cfg.Configuration;public final class HibernateUtil {private static SessionFactory sessionFactory;// 单例模式,只创建一次对象private HibernateUtil() {}// 初始化,开销很大,只做一次static {Configuration cfg = new Configuration();cfg.configure();// 不是hibernate.cfg.xml时将文件名传入sessionFactory = cfg.buildSessionFactory();}/** * 相当于JDBC的注册驱动 */public static SessionFactory getSessionFactory() {return sessionFactory;}/** * 相当于JDBC的getConnection<BR> * 注意:和HttpSession无关 */public static Session getSession() {return sessionFactory.openSession();}/** * 保存对象 */public static void add(Object entity) {Session s = null;Transaction tx = null;try {s = HibernateUtil.getSession();tx = s.beginTransaction();s.save(entity);tx.commit();} finally {if (s != null) {s.close();}}}/** * 更新对象 */public static void update(Object entity) {Session s = null;Transaction tx = null;try {s = HibernateUtil.getSession();tx = s.beginTransaction();s.update(entity);tx.commit();} finally {if (s != null) {s.close();}}}/** * 删除对象 */public static void delete(Object entity) {Session s = null;Transaction tx = null;try {s = HibernateUtil.getSession();tx = s.beginTransaction();s.delete(entity);tx.commit();} finally {if (s != null) {s.close();}}}/** * 获得对象 */public static Object get(Class clazz, Serializable id) {Session s = null;try {s = HibernateUtil.getSession();Object obj = s.get(clazz, id);return obj;} finally {if (s != null) {s.close();}}}}

    单例模式实现的基本方法是:构造方法私有,这是为了只能是类本身来实例化自己,而不能让其他对象来二次调用;给外部一个方法来获取需要单例运行的那个对象;类内控制只运行一次单例对象的初始化。这样的三个限制就实现了单例模式,非常简单。
    本例中构造方法内没有做任何事情,初始化工作在static块中完成,static的执行是在构造方法调用之前完成的,从而保证读取配置,创建sessionFactory在程序运行期间只执行了一次,就是在程序加载时完成。后面的四个方法简单实现了CRUD操作,非常简单,这里不做过多说明。
    下面来介绍Struts1和Hibernate框架的简单整合。要把二者结合起来,必然有一种机制实现了二者之间的互认。Hibernate本身只是ORM框架,工作比较专一,而Struts是负责Web控制层的框架,自然要Struts来认识Hibernate。这里不绕弯子了,就是Struts的plug-in(插件)功能来实现的。
    在struts的配置文件中最后一项是<plug-in>,是Struts的插件选项,插件可以是和Struts整合的第三方类库提供的,也可以是用户自定义的。用户自定义时,插件类需要实现org.apache.struts.action.PlugIn接口,覆盖init()和destroy()两个生命周期方法。
package test.plugin;import javax.servlet.ServletException;import org.apache.struts.action.ActionServlet;import org.apache.struts.action.PlugIn;import org.apache.struts.config.ModuleConfig;public class HibernatePlugIn implements PlugIn {@Overridepublic void destroy() {System.out.println("destroy method in hibernate plugin");SessionFactoryManager.closeSessionFactory();}@Overridepublic void init(ActionServlet actionServlet, ModuleConfig config)throws ServletException {System.out.println("init method in hibernate plugin");SessionFactoryManager.openSessionFactory();}}

    Hibernate单例实现类如下:
package test.plugin;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;public class SessionFactoryManager {private static Configuration configuration = null;private static SessionFactory sessionFactory = null;private SessionFactoryManager() {}static {configuration = new Configuration();configuration.configure();sessionFactory = configuration.buildSessionFactory();}public static SessionFactory openSessionFactory() {return sessionFactory;}public static Session getSession() {return sessionFactory.openSession();}public static void closeSessionFactory() {if (sessionFactory != null && sessionFactory.isClosed() == false) {sessionFactory.close();}}}

    Struts配置文件如下:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts-config PUBLIC          "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"          "http://struts.apache.org/dtds/struts-config_1_3.dtd"><struts-config>… … …<plug-in className="test.plugin.HibernatePlugIn"></plug-in></struts-config>

    需要说明的是plug-in标签的配置是最后一个,Struts配置文件标签需要按顺序进行,否则可能出现前后依赖的错误。在程序启动时,我们可以在Tomcat控制台看到如下内容:

    这里我们看到了写在插件实现类中的输出语句,可以说明插件类执行后就开始初始化Hibernate了,这说明Struts已经知道Hibernate了。
写一个测试Action,就可以这样进行:
package test.action;import java.io.PrintWriter;import java.util.List;import javax.servlet.http.*;import org.apache.struts.action.*;import org.hibernate.*;import org.hibernate.criterion.Restrictions;import test.bean.User;import test.plugin.SessionFactoryManager;public class HibernateTestAction extends Action {@Overridepublic ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {PrintWriter out = response.getWriter();Session s = SessionFactoryManager.getSession();try {// 使用Criteria进行条件查询,参数是实体BeanCriteria c = s.createCriteria(User.class);//条件是name=?c.add(Restrictions.eq("name", "Sarin"));List<User> list = c.list();for (User user : list) {out.println(user.getId() + "<br>");}} finally {if (s != null) {s.close();}}return null;}}

    测试实例中的表可以参照http://sarin.iteye.com/admin/blogs/593991中的结构进行设置,也可以应用于自定义的表结构中,id和name字段还是很普遍的。
    最后再说一点就是再整合Spring时就可以不用插件方式将Spring给注册进来,而是把Struts1交给Spring管理,为什么?Struts1的Action默认是单例的,会有线程安全问题,而交给Spring后,可以将单例Action多实例化,在一定程度上解决线程安全的问题,而且业务层交给Spring处理后,Spring容器对bean的管理和配置相对方便的多。

热点排行