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 {
@Override
public void destroy() {
System.out.println("destroy method in hibernate plugin");
SessionFactoryManager.closeSessionFactory();
}
@Override
public 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控制台看到如下内容:
[img]http://dl.iteye.com/upload/attachment/206443/0fd2ccf2-eaf1-3572-a04a-3cba6a6f8b00.jpg[/img]
这里我们看到了写在插件实现类中的输出语句,可以说明插件类执行后就开始初始化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 {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
PrintWriter out = response.getWriter();
Session s = SessionFactoryManager.getSession();
try {
// 使用Criteria进行条件查询,参数是实体Bean
Criteria 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;
}
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值