2012-07-24 57 views
0

我正在整合hibernate和struts2。请告知哪个是最好的方法,我认为在Struts2中,没有官方插件来集成Hibernate框架。但是,您可以通过以下步骤解决问题:集成Struts 2和休眠的最佳方法

  1. 注册自定义ServletContextListener。
  2. 在ServletContextListener类中,初始化Hibernate会话并将其存储到servlet上下文中。
  3. 在action类中,从servlet上下文获取Hibernate会话,并像平常一样执行Hibernate任务。

请指出,我的servlet上下文的初始化休眠会话工作室的方法是好的,也可以有其他最好的方法。这是该项目的快照。

这里是一段代码..

模型类...

package com.mkyong.customer.model; 

import java.util.Date; 

public class Customer implements java.io.Serializable { 

    private Long customerId; 
    private String name; 
    private String address; 
    private Date createdDate; 

    //getter and setter methods 
} 

的HBM映射文件..

<hibernate-mapping> 
    <class name="com.mkyong.customer.model.Customer" 
    table="customer" catalog="mkyong"> 

     <id name="customerId" type="java.lang.Long"> 
      <column name="CUSTOMER_ID" /> 
      <generator class="identity" /> 
     </id> 
     <property name="name" type="string"> 
      <column name="NAME" length="45" not-null="true" /> 
     </property> 
     <property name="address" type="string"> 
      <column name="ADDRESS" not-null="true" /> 
     </property> 
     <property name="createdDate" type="timestamp"> 
      <column name="CREATED_DATE" length="19" not-null="true" /> 
     </property> 
    </class> 
</hibernate-mapping> 

配置文件是...

<hibernate-configuration> 
    <session-factory> 
    <property name="hibernate.bytecode.use_reflection_optimizer">false</property> 
    <property name="hibernate.connection.password">password</property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mkyong</property> 
    <property name="hibernate.connection.username">root</property> 
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
    <property name="show_sql">true</property> 
    <property name="format_sql">true</property> 
    <property name="use_sql_comments">false</property> 
    <mapping resource="com/mkyong/customer/hibernate/Customer.hbm.xml" /> 
    </session-factory> 
</hibernate-configuration> 

听众类...

package com.mkyong.listener; 

import java.net.URL; 

import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 

import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 

public class HibernateListener implements ServletContextListener{ 

    private Configuration config; 
    private SessionFactory factory; 
    private String path = "/hibernate.cfg.xml"; 
    private static Class clazz = HibernateListener.class; 

    public static final String KEY_NAME = clazz.getName(); 

    public void contextDestroyed(ServletContextEvent event) { 
     // 
    } 

    public void contextInitialized(ServletContextEvent event) { 

    try { 
      URL url = HibernateListener.class.getResource(path); 
      config = new Configuration().configure(url); 
      factory = config.buildSessionFactory(); 

      //save the Hibernate session factory into serlvet context 
      event.getServletContext().setAttribute(KEY_NAME, factory); 
     } catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 
    } 
} 

最后动作类..

ackage com.mkyong.customer.action; 

import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 

import org.apache.struts2.ServletActionContext; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 

import com.mkyong.customer.model.Customer; 
import com.mkyong.listener.HibernateListener; 
import com.opensymphony.xwork2.ActionSupport; 
import com.opensymphony.xwork2.ModelDriven; 

public class CustomerAction extends ActionSupport 
    implements ModelDriven{ 

    Customer customer = new Customer(); 
    List<Customer> customerList = new ArrayList<Customer>(); 

    public String execute() throws Exception { 
     return SUCCESS; 
    } 

    public Object getModel() { 
     return customer; 
    } 

    public List<Customer> getCustomerList() { 
     return customerList; 
    } 

    public void setCustomerList(List<Customer> customerList) { 
     this.customerList = customerList; 
    } 

    //save customer 
    public String addCustomer() throws Exception{ 

     //get hibernate session from the servlet context 
     SessionFactory sessionFactory = 
      (SessionFactory) ServletActionContext.getServletContext() 
        .getAttribute(HibernateListener.KEY_NAME); 

     Session session = sessionFactory.openSession(); 

     //save it 
     customer.setCreatedDate(new Date()); 

     session.beginTransaction(); 
     session.save(customer); 
     session.getTransaction().commit(); 

     //reload the customer list 
     customerList = null; 
     customerList = session.createQuery("from Customer").list(); 

     return SUCCESS; 

    } 

    //list all customers 
    public String listCustomer() throws Exception{ 

     //get hibernate session from the servlet context 
     SessionFactory sessionFactory = 
      (SessionFactory) ServletActionContext.getServletContext() 
        .getAttribute(HibernateListener.KEY_NAME); 

     Session session = sessionFactory.openSession(); 

     customerList = session.createQuery("from Customer").list(); 

     return SUCCESS; 

    } 
} 

家伙请发布更新后的代码非常感谢,我坚持了这条.. !!

+0

请仅发布您的代码和配置的相关部分。这太多了。 – 2012-07-24 16:43:41

+0

@Tichodroma做到了。 – user1538526 2012-07-24 16:47:29

回答

1

我感到困惑,因为它提到关于Spring和Hibernate,但看完后读标题,它出来是Struts2的和Hibernate.Here是你输入我的最新的想法

Struts2的是Web层一个MVC框架,而Hibernate负责处理数据库交互,虽然你总是可以使用它们并且可以在Struts2动作中注入hibernate会话,但是我不会建议你这种方法。 我的建议是创建一个服务层,它应该负责在Struts2动作类和Hibernate层之间进行交互,这将帮助你微调你的代码,并且使你更容易做任何代码更改或任何修改在未来。

目前已经在Struts2的一个插件,它允许你在你的动作类

  1. full-hibernate-plugin-for-struts2/

注入Hibernate会话,但我认为仍然不与Struts2的行动和混合的Hibernate Session最好在两者之间放置一个服务层来做到这一点。

另外,因为你已经用Spring标记了你的问题,所以我相信你也在你的应用程序中使用了Spring,所以它更好地让Spring处理你与Hibernate的交互,同时引入一个服务层将有助于你有效地放置事务划分尽可能调整好。

+0

..完整的例子在URL http://www.mkyong.com/struts2/struts-2-hibernate-integration-example/请通过它,并请根据您的设计转换它是添加服务这样我就可以完全理解它了,谢谢 – user1538526 2012-07-24 17:05:20

1

你不想把休眠Session放在ServletContext。会话不是线程安全的,Hibernate的一个最佳实践是创建并销毁每个请求的Session(或者如果使用JPA,则为EntityManager)。

这可以使用拦截器来完成。正如Umesh所表明的那样,您应该倾向于使用服务层类(如DAO)直接与会话交互,而不是从操作类中使用它。这使您在模型层和控制器层之间有更明确的分离。

+0

能不能请你展示它的一个小示例 – user1538526 2012-07-24 17:07:59

+0

你可以在Struts 2中使用servlet过滤器吗?如果是这样,过滤器是拦截器的替代品。最大的区别是,拦截器会将会话包围在动作中,但过滤器会将其包装在整个请求中,包括渲染阶段。如果你的模型只包含DTO,并且没有实体,那么你只需要动作中的会话,但是如果你希望你的模型包含实体,那么如果你想避免可怕的'LazyInitializationException',那么在整个请求中你需要会话。 – 2012-07-24 17:16:26

+0

@Steven ..完整的例子是在网址mkyong.com/struts2/struts-2-hibernate-integration-example,请通过它,并根据您的设计将其转换为添加服务层的设计,以便我可以完全理解它,谢谢 – user1538526 2012-07-24 17:20:32

0

我发现此链接 Hibernate and Struts 2 Integration。这是完成整合的正确方法吗?

+0

请注意,[只有链接的答案](http://meta.stackoverflow.com/tags/link-only-answers/info)不鼓励,所以答案应该是搜索解决方案的终点(vs.而另一个引用的中途停留时间往往会随着时间推移而过时)。请考虑在此添加独立的摘要,并将链接保留为参考。 – kleopatra 2014-01-12 13:00:16

+0

我会在下次发布任何链接时记住这一点...... :) – SSaurabhJ 2014-01-20 04:04:13