ZK + Spring 3 + Hibernate:2つのヘッドが優れており、3つのヘッドが優れており、高速で、強力です

すべての良い一日。 そこで、 Spring FrameworkHibernateの 2つのモンスターを強力なj2ee ZKフレームワークと組み合わせる方法を共有することにしました。 そもそも、なぜGWTやネイティブjspでもないZKなのでしょうか? (純粋に主観的に)ZKはこれらのフレームワークと最も簡単に統合できるため、一般に、私があなたに証明しようとしていることをまだ達成していません。

私の目標は、これらのすべてのフレームワークを最小限の頭痛で機能させる方法を示すことなので、私の例は単純です。 Oracleをデータベースとして採用しています。 そして、ユーザー名を表示する簡単なWebアプリケーションを作成します。 また、ZKのパワーとシンプルさを示すために、システムからユーザーを削除したり、その名前を編集したりするなど、小さな機能を追加します。



最初に行うべきことは、ZKプロジェクト(Eclipseにプラグインをインストールした後にのみオプションが表示されます)または動的Webプロジェクトの作成です。違いは、生成されたweb.xmlファイル、index.zul、timeout.zul、zk.xmlおよびフレームワークライブラリに自動的に追加されます。

アプリケーションはMVCパターンに基づいて構築されるため、最初にモデルについて説明します。 srcフォルダーで、Personというマッピングテーブルを作成します。これは、Oracleスキーマにある必要があります。

package com.sample.data; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "PERSON") public class Person implements Serializable { private static final long serialVersionUID = 4624748294368212545L; @Id private long id; @Column(name = "Name") private String personName; public Person() { } public Person(long id, String personName) { super(); this.id = id; this.personName = personName; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } }
      
      





次のステップでは、このクラスで行うことを決定します。コレクションを表示し、ユーザー名を編集します。 クラスにアクセスするためのインターフェースを説明しましょう:

 package com.sample.service; import java.util.List; import com.sample.data.Person; public interface IPerson { List<Person> findAllPerson(); boolean delete(Person pers); boolean saveOrUpdate(Person person); }
      
      





そしてもちろん実装:



 package com.sample.service; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Restrictions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.sample.data.Person; @Repository @Transactional(readOnly = true) public class PersonImpl implements IPerson { private static SessionFactory sessionFactory; //  datasource @Autowired public void setSessionFactory(SessionFactory sessionFactory) { PersonImpl.sessionFactory = sessionFactory; } @SuppressWarnings("unchecked") @Override @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public List<Person> findAllPerson() { Session session = sessionFactory.getCurrentSession(); return (List<Person>) session.createQuery("from Person").list(); } @Override @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public boolean delete(Person pers) { try { Session session = sessionFactory.getCurrentSession(); session.delete(pers); return true; } catch (Exception e) { return false; } } @Override @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public boolean saveOrUpdate(Person person) { try { Session session = sessionFactory.getCurrentSession(); session.saveOrUpdate(person); return true; } catch (Exception e) { return false; } } }
      
      





PersonImplクラスのコードからわかるように、Springでトランザクションとデータベースへの接続に作業を置くと、hibernateはすべてのCRUDアクションを実行します。

MVCのイデオロギーに準拠して、コントローラーについて説明します。 ZKでは、これはいくつかの方法で行われますが、最も単純な方法を説明します-Windowクラスから継承します:



 package ui.component; import java.util.List; import javax.servlet.ServletContext; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import org.zkoss.zul.Listbox; import org.zkoss.zul.Listitem; import org.zkoss.zul.Messagebox; import org.zkoss.zul.Textbox; import org.zkoss.zul.Toolbarbutton; import org.zkoss.zul.Window; import com.sample.data.Person; import com.sample.service.IPerson; public class PersonInfo extends Window { private static final long serialVersionUID = -6186588639173052172L; //     persons    private Listbox personListBox; private Toolbarbutton tbbDelete; private List<Person> personList; private IPerson dao; private Textbox tbPersonName; private Toolbarbutton tbbSave; //  ,       public void onCreate() { //    ApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext((ServletContext) getDesktop().getWebApp().getNativeContext()); //   dao = (IPerson) ctx.getBean("personImpl"); personList = dao.findAllPerson(); tbPersonName = (Textbox) this.getFellow("tbPersonName"); tbbSave = (Toolbarbutton) this.getFellow("tbbSave"); if (personList.size() > 0) { //     - personListBox = (Listbox) this.getFellow("lbPerson"); tbbDelete = (Toolbarbutton) this.getFellow("tbbDelete"); //    populateListBox(); } } private void populateListBox() { for (Person pers : personList) { personListBox.appendChild(new Listitem(pers.getPersonName(), pers)); } } //    @SuppressWarnings("unchecked") public void onDeletePerson() { for (Listitem li : (List<Listitem>) personListBox.getItems()) { if (li.isSelected()) { if (dao.delete((Person) li.getValue())) { //    personList.remove((Person) li.getValue()); personListBox.removeChild(li); } } } } //   ,      public void onSelectLB() { if (personListBox.getSelectedCount() > 0) { tbbDelete.setDisabled(false); tbbSave.setDisabled(true); tbPersonName.setValue(((Person) personListBox.getSelectedItem().getValue()).getPersonName()); } else { tbbDelete.setDisabled(true); } } //   public void onSave() throws InterruptedException { if (tbPersonName.getValue() != null && tbPersonName.getValue().trim().length() > 0) { Person pers = (Person) personListBox.getSelectedItem().getValue(); pers.setPersonName(tbPersonName.getValue().trim()); if (!dao.saveOrUpdate(pers)) { Messagebox.show("      "); } else { personListBox.getSelectedItem().setLabel(pers.getPersonName()); personListBox.getSelectedItem().setValue(pers); } } else { Messagebox.show(" \"\"    "); } } }
      
      





それでは、構成ファイルに移りましょう。 データベースへの接続のコンテキスト、つまり、接続プールの設定から始めましょう。 META-INFフォルダーに次のテキストを含むcontext.xmlファイルを作成します。

 <?xml version="1.0" encoding="UTF-8"?> <!-- JDBC --> <Context path="/db1" docBase="db1" debug="5" reloadable="true" crossContext="true"> <Resource name="jdbc/taskdb" username="test" password="test" url="jdbc:oracle:thin:@localhost:1521:test" auth="Container" defaultAutoCommit="false" driverClassName="oracle.jdbc.driver.OracleDriver" maxActive="2" maxIdle="10" maxWait="-1" timeBetweenEvictionRunsMillis="60000" testOnBorrow="true" testWhileIdle="true" queryTimeout="20000" validationQueryTimeout="2" initialSize="1" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" type="javax.sql.DataSource" /> </Context>
      
      





Personテーブルへのマッピング時に注釈を使用したため、クラスを示すWEB-INFフォルダーにhibernate.cfg.xmlファイルを作成します。

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <mapping class="com.sample.data.Person" /> </session-factory> </hibernate-configuration>
      
      





Spring構成ファイルを作成しましょう。このファイルでは、jndi、bean sessionFactory、hibernate構成、およびパッケージスプリングを使用してOracleに接続するコンテキストについて説明し、注釈を適用します。 WEB-INFフォルダーにspring-config.xmlファイルを作成します。

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:annotation-config /> <context:component-scan base-package="com.sample" /> <tx:annotation-driven transaction-manager="txManager" /> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/taskdb</value> </property> </bean> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="dataSource" ref="dataSource" /> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop> <prop key="hibernate.show_sql">false</prop> </props> </property> <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> <property name="configLocation" value="/WEB-INF/hibernate.cfg.xml" /> </bean> </beans>
      
      





今度はweb.xmlの番です。 その中で、ZK設定に加えて、ばねのリスナー、およびばねと休止状態の構成ファイルのパスを指定する必要があります。

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>zkSpringHibernate</display-name> <listener> <description> Used to cleanup when a session is destroyed</description> <display-name>ZK Session cleaner</display-name> <listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class> </listener> <servlet> <description> The ZK loader for ZUML pages</description> <servlet-name>zkLoader</servlet-name> <servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class> <init-param> <param-name>update-uri</param-name> <param-value>/zkau</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <description> The asynchronous update engine for ZK</description> <servlet-name>auEngine</servlet-name> <servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.zul</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.zhtml</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>auEngine</servlet-name> <url-pattern>/zkau/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> </session-config> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-config.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>hibernateFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>hibernateFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.zul</welcome-file> </welcome-file-list> </web-app>
      
      





次のリンクは、MVCの用語に基づくビューです。 zulマークアップ(index.zulファイル、パス-WebContent)を使用してWebアプリケーションを説明しましょう。



 <?page title="ZK integration"?> <window title="view person" border="normal" width="100%" id="wndViewPerson" use="ui.component.PersonInfo"> <listbox id="lbPerson" hflex="1" vflex="1" checkmark="true" emptyMessage="data not found" onSelect="wndViewPerson.onSelectLB()"> <listhead> <listheader label="" /> </listhead> </listbox> <hlayout> <label value="" /> <textbox width="150px" id="tbPersonName" onChanging="tbbSave.setDisabled(false)" /> <toolbarbutton label="save" onClick="wndViewPerson.onSave()" id="tbbSave" disabled="true" /> <toolbarbutton label="delete" disabled="true" id="tbbDelete" onClick="wndViewPerson.onDeletePerson()" /> </hlayout> </window>
      
      





WEB-INFフォルダーに配置する必要がある構成ファイルzk.xmlの1つの小さな説明では、シリアル化を担当するクラスを示しています。

 <?xml version="1.0" encoding="UTF-8"?> <zk> <system-config> <ui-factory-class> org.zkoss.zk.ui.http.SerializableUiFactory </ui-factory-class> </system-config> </zk>
      
      





中間リンクや松葉杖がなくても簡単に、便利に、そして最も重要なことに注意を払って、refcursor、および一般的にはデータベースで作業できます。

そして、これはアプリケーションを実行するために必要なライブラリの最小リストです:



PS皆さんが始められることを願っていますが、もしそうでなければ、プロジェクトを送ります。 それでも、この記事がおもしろいと思われる場合、ZKフレームワーク自体について、またはSpring Securityとの統合などについても知りたい場合は、お知らせください。



All Articles