0

我打算整合hibernate和struts2。请告知哪种方法最好,我在想在 Struts2 中,没有官方插件可以集成 Hibernate 框架。但是,您可以通过以下步骤解决:

  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;

    }   
}

伙计们请发布更新的代码非常感谢,我坚持这个..!!

4

2 回答 2

1

你不想SessionServletContext. 会话不是线程安全的,Hibernate 的最佳实践是为每个请求创建和销毁一个Session(或者如果您使用 JPA)。EntityManager

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

于 2012-07-24T17:01:54.533 回答
1

我对阅读标题感到困惑,因为它提到了 Spring 和 Hibernate,但在阅读之后,结果是 Struts2 和 Hibernate。这是我对您的输入的快速思考

Struts2 用于 Web 层作为 MVC 框架,而 Hibernate 负责处理 DB 交互,尽管您始终可以同时使用两者,并且可以在 Struts2 操作中注入休眠会话,但我不建议您使用这种方法。我的建议是创建一个服务层,它应该负责在您的 Struts2 操作类和您的 Hibernate 层之间进行交互,这将帮助您微调您的代码,并使您更容易进行任何代码更改或任何修改未来。

Struts2 中已经有一个插件允许您在动作类中注入 Hibernate 会话

  1. struts2 的全休眠插件/

但我仍然认为不要将休眠会话与 Struts2 操作混合在一起,最好在两者之间放置一个服务层来执行此操作。

此外,由于您已经用 Spring 标记了您的问题,所以我相信您也在应用程序中使用 Spring,因此最好让 Spring 处理您与 Hibernate 的交互,同时引入服务层将帮助您高效地进行事务划分并进行微调可能的。

于 2012-07-24T16:48:39.033 回答