取得するカラムは一緒だけども、検索条件はいろいろ変わる…
こんな時、WHERE句以降をSQL実行時に自由に指定出来るようなSelectHandlerがあれば、コンポーネントが増えなくて済みそうです。
(メモ)そういったハンドラがあるのか後で調べる。(今晩の宿題)
見当たらないので、BasicSelectHandlerを拡張してみました。
けど、、、これだとマルチスレッドでダメ(同時にexecuteを呼ぶと、SQL文が後から呼ばれたものとして両方実行されてしまう可能性あり)なので、マルチスレッドで使われる場合には、排他かける必要があります。
import org.seasar.extension.jdbc.impl.BasicSelectHandler;
import org.seasar.framework.exception.SQLRuntimeException;
public class AppendSelectHandler extends BasicSelectHandler {
private String baseSql;
public Object execute(String append, Object[] args)
throws SQLRuntimeException {
return execute(append, args, getArgTypes(args));
}
public Object execute(String append, Object[] args, Class[] argTypes)
throws SQLRuntimeException {
super.setSql(baseSql + " " + append);
return super.execute(args, argTypes);
}
/**
* @see org.seasar.extension.jdbc.impl.BasicHandler#setSql(java.lang.String)
*/
public void setSql(String sql) {
baseSql = sql;
super.setSql(sql);
}
/**
* @see org.seasar.extension.jdbc.impl.BasicSelectHandler#execute(
* java.lang.Object[], java.lang.Class[])
*/
public Object execute(Object[] args, Class[] argTypes)
throws SQLRuntimeException {
super.setSql(baseSql);
return super.execute(args, argTypes);
}
}
setSqlをオーバライドして、diconファイルにて設定したSQLを、基本となるSQL(baseSql)として、インスタンス変数に保持します。
そして、SQL実行時(execute)にて、基本となるSQLと追加で指定されたSQLを結合し、実際に実行されるSQLとして設定(super.setSql)します。
追加するSQLを指定できるよう、下記のメソッドを追加してます。
- public Object execute(String append, Object[] args)
- public Object execute(String append, Object[] args, Class[] argTypes)
diconファイルにて、上記クラスをハンドラとして指定します。
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components>
<include path="j2ee.dicon"/>
<component name="selectBeanListHandler"
class="AppendSelectHandler">
<property name="sql">
"SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno FROM emp"
</property>
<property name="resultSetHandler">
<component class="org.seasar.extension.jdbc.impl.BeanListResultSetHandler">
<arg>@examples.jdbc.Employee@class</arg>
</component>
</property>
</component>
</components>実行は、下記のような感じになります。
mport java.util.List;
import org.seasar.extension.jdbc.SelectHandler;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
public class SelectBeanListClient {
private static final String PATH = "SelectBeanList.dicon";
public static void main(String[] args) {
S2Container container = S2ContainerFactory.create(PATH);
container.init();
try {
AppendSelectHandler handler = (AppendSelectHandler) container
.getComponent("selectBeanListHandler");
// SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno
// FROM emp
// WHERE empno = 100
List result = (List) handler.execute(
"WHERE empno = ?",
new Object[]{new Integer(100)});
for (int i = 0; i < result.size(); ++i) {
System.out.println(result.get(i));
}
// SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno
// FROM emp
// ORDER BY empno
result = (List) handler.execute("ORDER BY empno", null});
for (int i = 0; i < result.size(); ++i) {
System.out.println(result.get(i));
}
// SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno
// FROM emp
result = (List) handler.execute(null);
for (int i = 0; i < result.size(); ++i) {
System.out.println(result.get(i));
}
} finally {
container.destroy();
}
}
}