取得するカラムは一緒だけども、検索条件はいろいろ変わる…
こんな時、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(); } } }