使い方を思い出してきたので次はs2dao!
これは、本当に久しく触ってないなぁ。
順調に出来るだろうか??
とりあえず、データベースが無いとはじまらない!!
マシンの中に入ってるDBは…
- H2
- HSQLDB
- Derby
- Oracle XE
- SQL Server 2005 Express
う〜ん
H2にするか。
データの用意
jdbc:h2:tcp://localhost:9092/sample/dataにありがちなテーブルを切ってみた
create table Employee ( id int primary key, name varchar(50), dept_id int not null); create table Department ( id int primary key, name varchar(50)); alter table Employee add constraint FK_Employee_Department foreign key (dept_id) references Department(id);
ここにありがちなデータを突っ込む!
insert into Department ( id , name ) values (1, '総務'), (2, '人事'); insert into Employee (id, name , dept_id ) values (1, '太郎', 1), (2, '二郎', 1), (3, '三郎', 2);
j2ee.diconの用意
s2daoをダウンロードして解凍したものの中にj2ee.diconがあるのでそれをコピーしていらない部分を消す!
結果こんな感じに
<?xml version="1.0" encoding="Shift_JIS"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN" "http://www.seasar.org/dtd/components.dtd"> <components namespace="j2ee"> <component name="transactionManager" class="org.seasar.extension.jta.TransactionManagerImpl"/> <component name="requiredTx" class="org.seasar.extension.tx.RequiredInterceptor"/> <component name="requiresNewTx" class="org.seasar.extension.tx.RequiresNewInterceptor"/> <component name="mandatoryTx" class="org.seasar.extension.tx.MandatoryInterceptor"/> <component name="notSupportedTx" class="org.seasar.extension.tx.NotSupportedInterceptor"/> <component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/> <component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/> <component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl"> <property name="driverClassName"> "org.h2.Driver" </property> <property name="URL"> "jdbc:h2:tcp://localhost:9092/sample/data" </property> <property name="user">"sa"</property> <property name="password">""</property> </component> <component name="connectionPool" class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl"> <property name="timeout">600</property> <property name="maxPoolSize">10</property> <property name="allowLocalTx">true</property> <destroyMethod name="close"/> </component> <component name="dataSource" class="org.seasar.extension.dbcp.impl.DataSourceImpl"/> </components>
xaDataSourceの所をH2用に書き換えてあります。
Beanを用意
データベースのデータを入れるためのbeanを作ります。
ここらへんDBのスキーマから自動生成したいところですね。
Employee.java
package org.sample.s2.bean; import org.seasar.dao.annotation.tiger.Bean; import org.seasar.dao.annotation.tiger.Relation; @Bean public class Employee { private int id; private String name; private Department department; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Relation(relationNo=0, relationKey="dept_id:id") public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } }
クラスの定義のところのBeanアノテーションと、getDepartmentの所のRelationアノテーションくらいがポイント。
後は、DBのカラム名とかとあわせてあるので特に何もしなくてOK
続いて、Department。これはBeanアノテーションつけるだけ。
Department.java
package org.sample.s2.bean; import org.seasar.dao.annotation.tiger.Bean; @Bean public class Department { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
よっしゃ次!!
DAOを用意しないと始まらない。
めんどくさいので、EmployeeDaoだけを用意する。必要最低限のメソッドのみ定義。
EmployeeDao.java
package org.sample.s2.dao; import java.util.List; import org.sample.s2.bean.Employee; import org.seasar.dao.annotation.tiger.S2Dao; @S2Dao(bean=Employee.class) public interface EmployeeDao { Employee get(int id); List<Employee> selectAll(); void update(Employee emp); void delete(Employee emp); void insert(Employee emp); }
S2Daoアノテーションで、先ほど作ったbeanと関連付けをしてあげる。
これでOK
最後に、設定ファイルを書けば準備完了!!
これも自動登録機能を使ってやります。
app.diconに以下の2つのcomponentの定義を足す。
app.dicon
<!-- dao.interceptor --> <include path="dao.dicon" /> <!-- Daoの自動登録 --> <component class="org.seasar.framework.container.autoregister.ComponentAutoRegister"> <initMethod name="addReferenceClass"> <arg>@org.sample.s2.Main@class</arg> </initMethod> <initMethod name="addClassPattern"> <arg>"org.sample.s2.dao"</arg> <arg>".*Dao"</arg> </initMethod> </component> <!-- dao.interceptorをDaoに適用 --> <component class="org.seasar.framework.container.autoregister.AspectAutoRegister" > <property name="interceptor"> dao.interceptor </property> <initMethod name="addClassPattern" > <arg>"org.sample.s2.dao"</arg> <arg>".*Dao"</arg> </initMethod> </component>
ふぅ。長かった。
後はmainメソッドでお試しだ!!
package org.sample.s2; import org.sample.s2.bean.Employee; import org.sample.s2.component.Greeter; import org.sample.s2.dao.EmployeeDao; import org.seasar.framework.container.S2Container; import org.seasar.framework.container.factory.SingletonS2ContainerFactory; public class Main { private static final String CONFIG_PATH = "app.dicon"; public static void main(String[] args) { SingletonS2ContainerFactory.setConfigPath(CONFIG_PATH); SingletonS2ContainerFactory.init(); try { new Main().execute(); } finally { SingletonS2ContainerFactory.destroy(); } } private void execute() { S2Container con = SingletonS2ContainerFactory.getContainer(); // Dao EmployeeDao dao = (EmployeeDao) con.getComponent(EmployeeDao.class); Employee emp = dao.get(1); System.out.printf("id = %d, name = %s, department.name = %s\n", emp .getId(), emp.getName(), emp.getDepartment().getName()); } }
これを実行すると
2006-11-12 20:48:05,843 DEBUG ConnectionPoolImpl - 物理的なコネクションを取得しました 2006-11-12 20:48:05,843 DEBUG DataSourceImpl - 論理的なコネクションを取得しました 2006-11-12 20:48:06,109 DEBUG ConnectionWrapperImpl - 論理的なコネクションを閉じました 2006-11-12 20:48:06,140 DEBUG BasicSelectHandler - SELECT Employee.id, Employee.name, department.id AS id_0, department.name AS name_0 FROM Employee LEFT OUTER JOIN Department department ON Employee.dept_id = department.id 2006-11-12 20:48:06,140 DEBUG DataSourceImpl - 論理的なコネクションを取得しました 2006-11-12 20:48:06,156 DEBUG ConnectionWrapperImpl - 論理的なコネクションを閉じました id = 1, name = 太郎, department.name = 総務 2006-11-12 20:48:06,171 DEBUG ConnectionWrapperImpl - 物理的なコネクションを閉じました
お〜っちゃんと取れてる!
ラクチンだけどやっぱ自動生成したいね。
CodeGenっていうのがあったけど使えるのかな?後で見てみよう