Web層(Struts部分)の作成(HTML入力フォームの値を登録する画面の作成)

日本語文字入力対応

日本語文字(Windows-31J)入力対応のため、次の設定をstruts.propertiesに追記する。

struts.i18n.encoding = Windows-31J

入力フォームの値を保存するActionクラス作成

Actionクラスのソースは次の内容になる。従業員情報「employee」のアクセッサメソッドを用意することで、HTML入力フォームの値をアクションクラスで参照することが可能になる。

package sample.test;


import org.apache.struts2.config.Result;

import sample.test.iface.EmployeeService;
import java.text.SimpleDateFormat;

@Result(name = "success", value = "result.jsp")
public class EmployeeSaveAction {
	// 従業員情報
	private Employee employee;
	// 従業員サービス(Springがインジェクションする)
	private EmployeeService employeeService;
	//生年月日(Date型変換のため)
	private String birthDate;

	public String getBirthDate() {
		return birthDate;
	}

	public void setBirthDate(String birthDate) {
		this.birthDate = birthDate;
	}

	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	public EmployeeService getEmployeeService() {
		return employeeService;
	}

	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}

	// 従業員情報 登録
	public String execute() throws Exception {
		//Date型に変換してenployee.birtDateに設定
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		employee.setBirthDate(sdf.parse(getBirthDate()));
		employeeService.save(employee);
		return "success";
	}

}

従業員登録画面のJSPソースは次の内容になる。Struts2独自のカスタムタグのの各カスタムタグを使う。各タグは、<form>、<input type="text">、<input type="password">、<input type="submit">の各HTMLタグを生成する。これらStruts 2のカスタムタグを利用するために、JSPにtaglibディレクティブを<%@ taglib prefix="s" uri="/struts-tags" %>として定義する。

タグのkey属性には、各フィールドの名前を指定する。この名前(フィールド名)でアクションクラスから参照することが可能になる。

<?xml version="1.0" encoding="windows-31j" ?>
<%@ page language="java" contentType="text/html; charset=windows-31j"
	pageEncoding="windows-31j"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
              ;
                        途中省略
              ;
</head>
<body>
<s:form action="employeeSave">
	<s:textfield label="ID" key="employee.id" />
	<s:password label="パスワード" key="employee.password" />
	<s:textfield label="名前(姓)" key="employee.firstName" />
	<s:textfield label="名前(名)" key="employee.lastName" />
	<s:textfield label="かな名(姓)" key="employee.firstKananame" />
	<s:textfield label="かな名(名)" key="employee.lastKananame" />
	<s:textfield label="メールアドレス" key="employee.email" />
	<s:textfield label="電話番号" key="employee.phoneNumber" />
	<s:textfield label="生年月日" key="birthDate" />
	<s:submit value="登録" />
</s:form>


</body>
</html>

Web層(Struts部分)の作成(SpringとStrutsの連携)

Webデプロイメントディスクリプタファイル(WEB-INF/web.xml)を作成

次の内容でStruts2とSpring2の設定を記述する。
Struts2に関する設定
全てのリクエストに対してFilterDispatcherを定義する。また、設定ファイルstruts.xmlを書かないので、actionPackagesパラメータにアクションクラスのパッケージを設定をする必要がある。

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>
			org.apache.struts2.dispatcher.FilterDispatcher
		</filter-class>
		<init-param>
			<param-name>actionPackages</param-name>
			<param-value>sample.test</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

Spring2に関する設定
Spring では Web アプリケーション起動時に Bean 定義ファイルを読み込み ApplicationContext を生成する機能が提供されている。

	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/applicationContext.xml
		</param-value>
	</context-param>

StrutsとSpringを連携させるための設定

WEB-INF/classesに、次の内容でstruts.propertiesを作成する。

struts.objectFactory = spring
struts.objectFactory.spring.autoWire = type
struts.objectFactory.spring.autoWire = typeにするとアクションクラスのBean定義をSpringの設定ファイルに記述しなくても、型が一致していればオブジェクトを自動的にインジェクションしてくれる。

アクションクラスの作成

アクションが実行された時に呼ばれるクラス、アクションクラスを作成する。Struts 2でのアクションクラスはPOJO(Plain Old Java Objects、すなわち何も継承/実装しない普通のクラス)で実装する事ができる。また次の規約を守ることで設定ファイルstruts.xmlを記述する必要がなくなる。
  • アクションクラスの名前の末尾に「Action」をつける
  • アクションクラスを実行した後の遷移先をResultアノテーションで定義する
今回は従業員全情報を取得するEmployeeInfoActionクラスと遷移先画面のEmployeeInfoList.jspを作成した。 EmployeeInfoActionクラスの内容 EmployeeServiceクラスのオブジェクトをSpringでインジェクションさせるため、Setter、Getterメソッドを実装する。また従業員情報をemployeelistプロパティに設定することによって、Struts 2が提供するタグを利用してJSPで値を参照できるようになる。
package sample.test;

import org.apache.struts2.config.Result;

import sample.test.iface.EmployeeService;

import java.util.*;

@Result(name = "success", value = "EmployeeInfoList.jsp")
public class EmployeeInfoAction {
	private EmployeeService employeeService;
	private List<Employee> employeelist;

	public EmployeeService getEmployeeService() {
		return employeeService;
	}

	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}

	public List<Employee> getEmployeelist() {
		return employeelist;
	}

	public void setEmployeelist(List<Employee> employeelist) {
		this.employeelist = employeelist;
	}

	public String execute() throws Exception {
		setEmployeelist(employeeService.findAll());
		return "success";
	}

}
EmployeeInfoList.jspの内容
<?xml version="1.0" encoding="windows-31j" ?>
<%@ page language="java" contentType="text/html; charset=windows-31j"
    pageEncoding="windows-31j"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j" />
<title>Emplyee List</title>
</head>
<body>
<p>従業員情報一覧</p>
<s:if test="employeelist.size > 0">
	<table>
		<s:iterator value="employeelist">
			<tr>
				<td>
					<s:property value="userId" />
				</td>
				<td>
					<s:property value="firstName" />
				</td>
				<td>
					<s:property value="lastName" />
				</td>
				<td>
					<s:property value="firstKananame" />
				</td>
				<td>
					<s:property value="lastKananame" />
				</td>
				<td>
					<s:property value="email" />
				</td>
				<td>
					<s:property value="phoneNumber" />
				</td>
				<td>
					<s:property value="birthDate" />
				</td>
			</tr>
		</s:iterator>
	</table>
</s:if>
</body>
</html>
準備ができたら http://localhost:8080/コンテキストルート/employeeInfo.actionのURLにアクセスして動作確認を行う。しかし、動作確認の際に次の二つのエラーが発生した これはTomcatのインストール先のlibディレクトリにJDBCドライバのJarファイルを置くことで解決した。(Tomcat5以前はcommon/lib配下に置く必要あり)
  • org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'txProxyTemplate' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'target' is required
これは下記のようにlazy-init="true"を追記することで解決した。
	<bean id="txProxyTemplate" lazy-init="true"
		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

ビジネスロジック部分の作成

従業員情報サービスクラスのインターフェース作成

プレゼンテーション層(Struts部分)に公開するEmployeeServiceインターフェースを次の内容で作成する。(ほとんどDAOインターフェースの内容と同じ)

package sample.test.iface;

import java.util.List;

import sample.test.Employee;

public interface EmployeeService {
	// 従業員IDから情報を参照
	public Employee get(String id) throws Exception;

	// 全従業員情報を参照
	public List<Employee> findAll() throws Exception;

	// 従業員情報を登録
	public void save(Employee employee) throws Exception;

	// 従業員情報を更新
	public void update(Employee employee) throws Exception;

	// 従業員情報を削除
	public void delete(String id) throws Exception;

}

従業員情報サービスクラスの実装クラス作成

次の内容でEmployeeServiceImplクラスを作成する。
Spring定義ファイルでEmployeeDAOオブジェクトをインジェクションできるようにSetter、Getterメソッドも実装する。

package sample.test;

import java.util.List;

import sample.test.iface.EmployeeService;
import sample.test.dao.iface.EmployeeDAO;
import sample.test.Employee;

public class EmployeeServiceImpl implements EmployeeService {

	private EmployeeDAO employeeDao;

	public EmployeeDAO getEmployeeDao() {
		return employeeDao;
	}

	public void setEmployeeDao(EmployeeDAO employeeDao) {
		this.employeeDao = employeeDao;
	}

	// 従業員IDから情報を参照
	public Employee get(String id) throws Exception {
		return employeeDao.get(id);
	}

	// 全従業員情報を参照
	public List<Employee> findAll() throws Exception {
		return employeeDao.findAll();
	}

	// 従業員情報を登録
	public void save(Employee employee) throws Exception {
		employeeDao.save(employee);
	}

	// 従業員情報を更新
	public void update(Employee employee) throws Exception {
		employeeDao.update(employee);
	}

	// 従業員IDから情報を削除
	public void delete(String id) throws Exception {
		employeeDao.delete(id);

	}

}

Spring定義ファイルにビジネスロジック部分を追記(トランザクション管理の定義)

Springでは設定ファイルにAOPを使ったトランザクション管理の定義を記述することで、「宣言的トランザクション管理」が利用できる。つまりソースコードにデータベースに対するコミットやロールバックといったトランザクション制御に関する記述をしなくてもよくなる。記述内容のポイントをあげると次のとおりになる。

トランザクションマネージャーの設定

トランザクションマネージャーがトランザクションのコミットとロールバックを行う。org.springframework.orm.hibernate3.HibernateTransactionManagerクラスを使う。ここで、既に定義しているSessionFactoryクラスを注入する。

トランザクションインターセプターの設定

AOPを使うため、インターセプタークラスの定義を行う。org.springframework.transaction.interceptor.TransactionProxyFactoryBeanクラスを使う。

トランザクション属性の設定

各メソッド呼び出しにどのようなトランザクション属性を適用するかを記述する。トランザクション属性はトランザクションインターセプターのtransactionAttributesプロパティの値に設定する。キーにメソッド名、値に属性を記述する。メソッド名はワイルドカードを使用することができる。
属性はPROPAGATION_REQUIREDを設定する。これはトランザクションが開始されていればそれを継続し、存在しなければ新しいトランザクションを生成する動作になる(トランザクション定義のデフォルト)。
トランザクションで例外が発生した場合は、ロールバックするように設定する。属性値にカンマ区切りで「-Exception」と記述する。「-」はロールバックを表す(「+」にするとコミットするようになる)
参照系のメソッドは読み取り専用にする。これも属性値にカンマ区切りで「readOnly」と記述する。読み取り専用の場合、書き込み処理を行うとSpringが例外をスローする。

トランザクションインターセプターの対象クラスの設定

対象クラスはトランザクションインターセプターのtargetプロパティの値に設定する。対象クラスが追加されても設定がシンプルになるように、トランザクションマネージャーとトランザクション属性を設定したテンプレート的なトランザクションインターセプターのBean定義を設定し、それを継承するような形にする。

Spring定義ファイル(/WEB-INF/applicationContext.xml)の追記内容は次の内容になる。

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
	</bean>

	<bean id="txProxyTemplate" lazy-init="true"
		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
		<property name="transactionManager">
			<ref local="transactionManager" />
		</property>
		<property name="transactionAttributes">
			<props>
				<prop key="save*">
					PROPAGATION_REQUIRED, -Exception
				</prop>
				<prop key="update*">
					PROPAGATION_REQUIRED, -Exception
				</prop>
				<prop key="delete*">
					PROPAGATION_REQUIRED, -Exception
				</prop>
				<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
			</props>
		</property>
	</bean>

	<bean id="employeeService" parent="txProxyTemplate" >
		<property name="target">
			<bean class="sample.test.EmployeeServiceImpl">
				<property name="employeeDao">
					<ref local="employeeDao" />
				</property>
			</bean>
		</property>
	</bean>

SpringとHibernateの連携 - データアクセス処理の作成

Daoインターフェース作成

Hibernate Synchronizerで生成されたEmployeeDAOインターフェースを次の内容で修正。

package sample.test.dao.iface;

import java.util.List;
import org.springframework.dao.DataAccessException;

import sample.test.Employee;

public interface EmployeeDAO {
	// 従業員IDから情報を参照
	public Employee get(String id) throws DataAccessException;

	// 全従業員情報を参照
	public List<Employee> findAll() throws DataAccessException;

	// 従業員情報を登録
	public String save(Employee employee) throws DataAccessException;

	// 従業員情報を更新
	public void update(Employee employee) throws DataAccessException;

	// 従業員情報を削除
	public void delete(String id) throws DataAccessException;
}

Dao実装クラス作成

上記インターフェースの実装クラスEmployeeDAOImplを作成。これはHibernate Synchronizerで生成されたものは使えないので、新たに作成。ポイントは次のとおり。

  • Hibernateを使用するためorg.springframework.orm.hibernate3.support.HibernateDaoSupport抽象クラスを継承する。
  • データベースにアクセスするためにorg.springframework.orm.hibernate3.HibernateTemplateクラスのメソッドを使用する。このクラスは内部でHibernateのSessionクラスを使用している。
  • 従業員IDから情報を参照するときは、HibernateTemplateクラスのload()メソッドを使用する。get()メソッドでも参照できるがload()メソッドは情報が存在しない場合に例外をスローする。
  • 削除処理は従業員IDのみ渡して行いたいので、HibernateTemplateの削除メソッドの中でget(id)を呼び出す。

ソースの内容は次の内容になる。

package sample.test.dao;

import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.dao.DataAccessException;

import sample.test.dao.iface.*;
impo</span>rt sample.test.Employee;

public class EmployeeDAOImpl extends HibernateDaoSupport implements EmployeeDAO{
	// 従業員IDから情報を参照
	public Employee get(String id) throws DataAccessException{
		Employee employee 
        = (Employee) getHibernateTemplate().load(Employee.class, id);
		   return employee;
    }
 
	// 全従業員情報を参照
	public List<Employee> findAll() throws DataAccessException{
        return getHibernateTemplate().loadAll(Employee.class);
    }
	// 従業員情報を登録
	public void save(Employee employee) throws DataAccessException {
		getHibernateTemplate().save(employee);
}
	// 従業員情報を更新
	public void update(Employee employee) throws DataAccessException {
		getHibernateTemplate().update(employee);
	}

	// 従業員情報を削除
	public void delete(String id) throws DataAccessException {
		getHibernateTemplate().delete(get(id));
	}
}

Dao実装クラスのBean定義

次の内容を/WEB-INF/applicationContext.xml に追加する。EmployeeDAOImplクラスが継承しているHibernateDaoSupport抽象クラスにはSessionFactory型のフィールドが定義されている。

  <bean id="employeeDao" class="sample.test.dao.EmployeeDAOImpl">
    <property name="sessionFactory"><ref local="sessionFactory"/></property>
  </bean>

テストケースの作成

  1. プロジェクトのプロパティ画面でJavaのビルドパスJUnitライブラリを追加する。ライブラリーのタブをクリックし、「ライブラリー追加」ボタンを押してJUnitを選択する。
  2. ソースフォルダーを右クリック、新規→作成を選択、ウィザード選択でJava配下のJUnitテスト・ケースを選択する。
  3. JUnitテストケース画面で名前とテスト元クラスを入力して「次へ」ボタンを押す。
  4. テスト・メソッド画面でテストを行うEmployeeImplクラスのメソッドをチェックし、「終了」ボタンを押すとテストケースの雛形が作成される。
  5. 雛形を次の内容で修正し、JUnitでテストを実行する。この際、実行時のクラスパスにプロジェクト配下の「WebContent」を追加する必要がある。
package sample.test.dao;

import sample.test.*;
import sample.test.dao.iface.*;
import java.text.SimpleDateFormat;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;

public class EmployeeDAOImplTest extends TestCase {
	private EmployeeDAO dao = null;

	protected void setUp() throws Exception {
		super.setUp();
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"/WEB-INF/applicationContext.xml");
		dao = (EmployeeDAO) ctx.getBean("employeeDao");
	}

	public void testSave() throws Exception {
		Employee employee = new Employee();
		employee.setId("12345");
		employee.setPassword("56789");
		employee.setFirstName("テスト");
		employee.setLastName("太郎");
		employee.setFirstKananame("てすと");
		employee.setLastKananame("たろう");
		employee.setEmail("sample@sample.test.com");
		employee.setPhoneNumber("999-9999");

		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String date = "20071219";
		employee.setBirthDate(sdf.parse(date));

		dao.save(employee);

		Employee newEmployee = dao.get("12345");

		assertEquals("12345", newEmployee.getId());
	}

	public void testUpdate() throws Exception {
		Employee employee = new Employee();
		employee.setId("12345");
		employee.setPassword("56789");
		employee.setFirstName("テスト");
		employee.setLastName("次郎");
		employee.setFirstKananame("てすと");
		employee.setLastKananame("たろう");
		employee.setEmail("sample@sample.test.com");
		employee.setPhoneNumber("999-9999");

		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String date = "20071219";
		employee.setBirthDate(sdf.parse(date));

		dao.update(employee);

		Employee newEmployee = dao.get("12345");

		assertEquals("次郎", newEmployee.getLastName());
	}

	public void testGet() throws Exception {
		Employee employee = dao.get("12345");
		assertEquals("テスト", employee.getFirstName());
		assertEquals("次郎", employee.getLastName());
		assertEquals("てすと", employee.getFirstKananame());
		assertEquals("たろう", employee.getLastKananame());
		assertEquals("sample@sample.test.com", employee.getEmail());
		assertEquals("999-9999", employee.getPhoneNumber());
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		assertEquals("2007/12/19", sdf.format(employee.getBirthDate()));
	}

	public void testFindAll() throws Exception {
		List<Employee> employeeList;
		int count = 0;
		employeeList = dao.findAll();
		count = employeeList.size();

		Employee employee = new Employee();
		employee.setId("010101");
		employee.setPassword("56789");
		employee.setFirstName("テスト");
		employee.setLastName("次郎");
		employee.setFirstKananame("てすと");
		employee.setLastKananame("じろう");
		employee.setEmail("tesi2@email");
		employee.setPhoneNumber("888-8888");

		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String date = "20071215";
		employee.setBirthDate(sdf.parse(date));

		dao.save(employee);
		employeeList = dao.findAll();
		assertEquals("総件数", count + 1, employeeList.size());
	}

	public void testDelete() throws Exception {
		dao.delete("12345");
		dao.delete("010101");

		try {
			dao.get("12345");
			dao.get("010101");
			fail("Employee found in database");
		} catch (DataAccessException dae) {
			assertNotNull(dae);
		}
	}

}

ところが、org.hibernate.LazyInitializationException: could not initialize proxy - no Sessionのエラーがupdate、getメソッド実行時に発生した。
このエラーは次のように、Hibernateマッピングファイルのlazy属性に"false"を設定することで回避できた。lazy属性については、Hibernate2まではデフォルトで"false"だったのが、hibernate3から仕様が変わっている。

<hibernate-mapping package="sample.test">
	<class
		name="Employee"
		table="EMPLOYEE"
		lazy="false"
		
	>

SpringとHibernateの連携

Spring設定ファイル作成(EclipseでのSpringIDEを使った作成手順)

  1. Eclipseでプロジェクトを右クリックし、「新規」→「その他」を選択。
  2. 「ウィザード選択」でSpring配下の「Spring Bean 定義」を選択する。
  3. 親フォルダー選択画面でコンテキストルート/WebContent/WEB-INF、ファイル名にapplicationContext.xmlを設定。
  4. 名前空間宣言の選択はそのままにして「終了」ボタンを押すと雛形が作成される。このファイルはSpringの設定ファイルとしてチェックされるので、誤った記述をするとエラーが表示される。

以降の内容で設定ファイルの記述を行う。

Spring設定ファイル作成(データソースの設定)

データベースへの接続に関しては、コネクションプーリングというコネクションをトランザクション毎に作成、解放するのではなく、一度作成したコネクションを解放せずに使い回す事で、データベースアクセスの負荷を減らす手法を使いたい。そこで、Tomcatに実装されているorg.apache.tomcat.dbcp.dbcp.BasicDataSourceというクラスを使うことにする。このクラスはJakarta Commons DBCPが提供しているものがベースになっているようだ。Springにはorg.springframework.jdbc.datasource.DriverManagerDataSourceというクラスも存在するが、これは常に新しいコネクションを使う。
設定ファイル/WEB-INF/applicationContext.xmlは、次の内容になる。コネクション情報は管理しやすいように別ファイル/WEB-INF/database.propertiesに記述した。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans>
	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>/WEB-INF/database.properties</value>
			</list>
		</property>
	</bean>
	<bean id="dataSource"
		class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
        <property name="driverClassName">
			<value>${database.connection.driver_class}</value>
		</property>
		<property name="url">
			<value>${database.connection.url}</value>
		</property>
		<property name="username">
			<value>${database.connection.username}</value>
		</property>
		<property name="password">
			<value>${database.connection.password}</value>
		</property>
	</bean>
</beans>

/WEB-INF/database.propertiesの内容

database.connection.driver_class=oracle.jdbc.driver.OracleDriver
database.connection.url=jdbc:oracle:thin:@localhost:1521:SAMPLE
database.connection.username=sample
database.connection.password=sample

Spring設定ファイル作成(SessionFactoryの設定)

SpringからHibernateを使うことができるようにするため、SessionFactoryの設定を行う。ここではorg.springframework.orm.hibernate3.LocalSessionFactoryBeanクラスを使い、次のプロパティの設定を行う。これでHibernate側の設定(hibernate.cfg.xml)は不要になる。

dataSourcedataSourceへの参照
mappingResourcesHibernateマッピングファイルへのパス
hibernate.dialect使用するデータベースのdialect
Spring設定ファイル/WEB-INF/applicationContext.xmlに次の内容を追加する。

	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
                </property>
		<property name="mappingResources">
			<list>
				<value>sample/test/Employee.hbm.xml</value>
                        </list>
                </property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
                        </props>
                </property>
	</bean>

Hibernateのマッピングファイルの設定とデータベース関係のクラス作成

Hibernate Synchronizerプラグインを使って、マッピングファイルとデータベース関係のクラス(エンティティクラス、Daoクラス)を自動生成する。環境設定で指定した内容でデータベースに接続できることが必要。

  1. プロジェクト配下のソースフォルダー(パッケージ)を右クリック、「新規」→「その他」選択。
  2. 「ウィザードを選択」で「Hibernate」の「Hibernateマッピングファイル」を選択し、「次へ」ボタンを押す。
  3. パスワードを設定して、「更新」ボタンを押す。
  4. テーブルの一覧が表示されるので、今回作成したEMPLOYEEテーブルを選択する。
  5. パッケージを選択して「終了」ボタンを押す。
  6. マッピングファイルが自動生成される。プライマリーキーを示すIDタグが作られないので、手動で修正しておく。(この時、キーをアプリ側で作成する場合は「generator class="assigned"」とする)
  7. マッピングファイルを保存するか、右クリックで「Hibernate Synchronizer」→「同期化および上書き」を選択するとエンティティクラスが自動生成される。さらに「attribute="sync-DAO"」をtrueにしておくとDAOクラスが自動生成される。具体的には例えば「sample.test」というパッケージを指定した場合に、「sample.test.base」、「sample.test.dao」、「sample.test.dao.iface」というパッケージと配下のクラス、インターフェースが自動生成される。


作成されたマッピングファイルの一部

<hibernate-mapping package="sample.test">
	<class
		name="Employee"
		table="EMPLOYEE"
        lazy="false"
	>
		<meta attribute="sync-DAO">true</meta>
		<id
			name="Id"
			column="ID"
			type="string"
            >
              <generator class="assigned" />
             </id>
		<property
			name="Password"
			column="PASSWORD"
			type="string"
			not-null="false"
			length="20"
		/>
		<property
			name="FirstName"
			column="FIRST_NAME"
			type="string"
			not-null="false"
			length="20"
        ;
        ;
		</class>	
</hibernate-mapping>

作成されたエンティティクラスの一部

	// primary key
	private java.lang.String id;

	// fields
	private java.lang.String password;
	private java.lang.String firstName;
	private java.lang.String lastName;
	private java.lang.String firstKananame;
	private java.lang.String lastKananame;
	private java.lang.String email;
	private java.lang.String phoneNumber;
	private java.util.Date birthDate;

	public java.lang.String getId () {
		return id;
	}
	public void setId (java.lang.String id) {
		this.id = id;
		this.hashCode = Integer.MIN_VALUE;
	}
	public java.lang.String getPassword () {
		return password;
	}
	public void setPassword (java.lang.String password) {
		this.password = password;
	}
	public java.lang.String getFirstName () {
		return firstName;
	}
	public void setFirstName (java.lang.String firstName) {
		this.firstName = firstName;
	}
        ;
        ;

作成されたDaoインターフェースの一部

public interface EmployeeDAO {
	public sample.test.Employee get(java.lang.String key);
	public sample.test.Employee load(java.lang.String key);
	public java.util.List<sample.test.Employee> findAll ();
	public java.lang.String save(sample.test.Employee employee);
	public void saveOrUpdate(sample.test.Employee employee);
	public void update(sample.test.Employee employee);
	public void delete(java.lang.String id);
	public void delete(sample.test.Employee employee);
}

Hibernateの環境設定

Hibernate Synchronizerプラグインを使って、構成ファイル(hibernate.cfg.xml)を作成する。

  1. プロジェクト配下のWEB-INFを右クリック、「新規」→「その他」選択。
  2. 「ウィザードを選択」で「Hibernate」の「Hibernate構成ファイル」を選択し、「次へ」ボタンを押す。
  3. データベースに「Oracle(any version)」、ドライバークラスに「oracle.jdbc.OracleDriver」、接続先(例:jdbc:oracle:thin:@dbserver:1521:oracle)、接続ユーザー、パスワードを設定して「終了」ボタンを押す。