0

hibernateとstruts2を統合するつもりでした。そのための最善のアプローチを教えてください。Struts2には、Hibernateフレームワークを統合するための公式プラグインはないと思っていました。ただし、次の手順で回避できます。

  1. カスタムServletContextListenerを登録します。
  2. ServletContextListenerクラスで、Hibernateセッションを初期化し、サーブレットコンテキストに格納します。
  3. アクションクラスで、サーブレットコンテキストからHibernateセッションを取得し、通常どおりHibernateタスクを実行します。

Hibernateセッションファクトリーを初期化するためのサーブレットコンテキストの私のアプローチは問題ないか、または最善のアプローチもある可能性があることをアドバイスしてください。これがプロジェクトのスナップショットです。

これがコードの一部です。

モデルクラス...

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

Spring と Hibernate について言及されていたので、タイトルを読むのに戸惑いましたが、読んだ後、Struts2 と Hibernate であることがわかりました。

Struts2 は MVC フレームワークとしての Web レイヤー用であり、Hibernate は DB 相互作用を処理する責任がありますが、いつでも両方を使用でき、Struts2 アクションで休止状態セッションを挿入できますが、このアプローチはお勧めしません。私の提案は、Struts2 アクション クラスと Hibernate レイヤーの間の対話を担当するサービス レイヤーを作成することです。将来。

Struts2 には、アクション クラスに Hibernate セッションを挿入できるプラグインが既にあります。

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

しかし、休止状態セッションと Struts2 アクションを混在させず、これを行うために間にサービス層を配置する方がよいという意見はまだあります。

また、Spring で質問にタグを付けたので、アプリケーションでも Spring を使用していると思われるので、Spring に Hibernate とのやり取りを処理させる方がよいでしょう。また、サービス層を導入すると、トランザクションの境界を効率的に配置し、微調整するのに役立ちます。可能。

于 2012-07-24T16:48:39.033 に答える
1

Sessionに Hibernateを入れたくありませんServletContext。セッションはスレッドセーフではなく、Hibernate のベスト プラクティスは、リクエストごとにSession(またはEntityManagerJPA を使用する場合は) を作成および破棄することです。

これは、インターセプターを使用して実現できます。Umesh が指摘しているように、DAO などのサービス層クラスを使用して、アクション クラス内から使用するよりも、セッションと直接やり取りすることを優先する必要があります。これにより、モデル レイヤーとコントローラー レイヤーをより明確に分離できます。

于 2012-07-24T17:01:54.533 に答える