おきらくmanholeの日記

id:manhole
 | 

2004-07-23

ちょっとした検証 - S2DaoとS2JDBCを1つのDaoインタフェースで使う 01:56

※これも実験結果のメモ書きです。

----

Daoのメソッドによって

  • 自動生成SQL
  • S2JDBCで指定したSQL (diconファイルに書いたSQL)

を任意に使用できるか可能か試してみました。

----

  • Daoの自動生成以外にもSQL文を書く必要がある場合
    • 集計する
    • ソート順が変化する
    • UNION ALLする
    • ヒント句を使う
  • Daoの"BEAN"アノテーション以外の型でデータを返したい場合
    • 集計する場合など

----

  • [テストケース] EmployeeDaoTest
    • テストケースでは1つのDaoとして使用する
package examples.dao.manhole;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import org.seasar.dao.unit.S2DaoTestCase;
public class EmployeeDaoTest extends S2DaoTestCase {
    private EmployeeDao dao_;
    public EmployeeDaoTest(String arg0) {
        super(arg0);
    }
    public void setUp() {
        include("examples/dao/manhole/EmployeeDao.dicon");
    }
    public void testGetScott() {
        Employee emp = dao_.getEmployee(7788);
        assertEquals("SCOTT", emp.getEname());
    }
    public void testGetHighestSalEmployee() {
        Employee emp = dao_.getHighestSalEmployee();
        assertEquals("KING", emp.getEname());
    }
    public void testGetCount() {
        int count = dao_.getCount();
        assertEquals(14, count);
    }
    public void testGetEmployeeNumbersPerDepartment() {
        List actual = dao_.getEmployeeNumbersPerDepartment();
        assertEquals(3, actual.size());
        Map m = (Map)actual.get(0);
        assertEquals(new Integer(6), m.get("NUMBERS"));
        assertEquals(new BigDecimal(30), m.get("DEPTNO"));
    }
}
  • [Dao] EmployeeDao
    • 自動生成用のメソッド・手書きのSQL(S2Dao)用のメソッド、S2JDBC用のメソッドを全て宣言する
package examples.dao.manhole;
import java.util.List;
public interface EmployeeDao {
    public Class BEAN = Employee.class;
    public String getEmployee_ARGS = "empno";
    // 自動生成SQL
    public Employee getEmployee(int empno);
    // diconにSQLを書く
    public Employee getHighestSalEmployee();
    // *.sqlにSQLを書く
    public int getCount();
    // diconにSQLを書く, Employee.classとは異なる型(ここではMap)で返す
    public List getEmployeeNumbersPerDepartment();
}
  • [抽象Dao] AbstractEmployeeDao
    • S2JDBCのメソッドはここに実装する
    • S2Daoで処理するメソッドは実装しないため、このクラスはabstractにする
package examples.dao.manhole;
import java.util.List;
import org.seasar.extension.jdbc.SelectHandler;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
public abstract class AbstractEmployeeDao implements EmployeeDao {
    private static final String PATH = "examples/dao/manhole/EmployeeDao.dicon";
    public Employee getHighestSalEmployee() {
        S2Container container = S2ContainerFactory.create(PATH);
        container.init();
        try {
            SelectHandler handler = (SelectHandler)container.getComponent("getHighestSalEmployee");
            Employee emp = (Employee)handler.execute(null);
            return emp;
        } finally {
            container.destroy();
        }
    }
    public List getEmployeeNumbersPerDepartment() {
        S2Container container = S2ContainerFactory.create(PATH);
        container.init();
        try {
            SelectHandler handler = (SelectHandler)container.getComponent("getEmployeeNumbersPerDepartment");
            return (List)handler.execute(null);
        } finally {
            container.destroy();
        }
    }
}
  • [SQL] AbstractEmployeeDao_getCount.sql
    • ファイル名にAbstractが付いちゃうのね...
SELECT COUNT(*) FROM EMP
  • [dicon] examples/dao/manhole/EmployeeDao.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 class="examples.dao.manhole.AbstractEmployeeDao">
        <aspect>
            <component class="org.seasar.dao.interceptors.S2DaoInterceptor"/>
        </aspect>
    </component>

    <component name="getHighestSalEmployee"
        class="org.seasar.extension.jdbc.impl.BasicSelectHandler">
        <property name="sql">
"
SELECT
    EMP.ename
   ,EMP.empno
   ,EMP.deptno
  FROM EMP
  WHERE SAL = (SELECT MAX(SAL) FROM EMP)
"
        </property>
        <property name="resultSetHandler">
            <component class="org.seasar.extension.jdbc.impl.BeanResultSetHandler">
                <arg>@examples.dao.manhole.Employee@class</arg>
            </component>
        </property>
    </component>

    <component name="getEmployeeNumbersPerDepartment"
        class="org.seasar.extension.jdbc.impl.BasicSelectHandler">
        <property name="sql">
"
SELECT
    COUNT(*) AS NUMBERS
   ,DEPTNO
  FROM EMP
  GROUP BY DEPTNO
  ORDER BY 1 DESC
"
        </property>
        <property name="resultSetHandler">
            <component class="org.seasar.extension.jdbc.impl.MapListResultSetHandler"/>
        </property>
    </component>
</components>
  • [Bean] Employee

下に載せたのと同じ

ちょっとした検証 - 自動生成されるSELECT文 08:01

Beanのアノテーションがどう影響するのかと思い、ちょっと確認してみる。

public String getEmployee_ARGS = "empno"; のとき

SELECT EMP.ename, EMP.empno, EMP.deptno FROM EMP WHERE  EMP.empno = 7788

public String getEmployee_ARGS = "ename"; のとき

SELECT EMP.ename, EMP.empno, EMP.deptno FROM EMP WHERE  EMP.ename = 7788

public String getEmployee_ARGS = "aaaaa"; のときは例外が発生する

org.seasar.extension.jdbc.ColumnNotFoundRuntimeException: [ESSR0068]テーブル(EMP)のカラム(aaaaa)が見つかりません

アノテーションが無い場合 (コメントアウトした)

SELECT EMP.ename, EMP.empno, EMP.deptno FROM EMP

----

わかったこと

  • アノテーションの値は、where句のカラム名になった。存在しないカラムの場合は例外が発生する。
  • テーブルの項目よりもBeanのプロパティが少ない場合は、Beanのプロパティ項目がSELECTされる。(実際には、EMP.JOBといったカラムが存在するがSELECTされていない)
  • アノテーションが無い場合は、where句が生成されない。→全検索になる

----

使用したのは以下のソース。(S2Daoのサンプルを簡略化したもの)

自動生成のテストが目的なので、*.sqlファイルはありません。

  • テストクラス
    • 上記SQLはtestGetScottを実行した際のもの
package examples.dao.manhole;
import org.seasar.dao.unit.S2DaoTestCase;
public class EmployeeDaoTest extends S2DaoTestCase {
    private EmployeeDao dao_;
    public EmployeeDaoTest(String arg0) {
        super(arg0);
    }
    public void setUp() {
        include("examples/dao/manhole/EmployeeDao.dicon");
    }
    public void testGetScott() {
        Employee emp = dao_.getEmployee(7788);
        assertEquals("SCOTT", emp.getEname());
    }
}
  • DAO
package examples.dao.manhole;
public interface EmployeeDao {
    public Class BEAN = Employee.class;
    public String getEmployee_ARGS = "empno";
    public Employee getEmployee(int empno);
}
  • Bean (S2サンプルのものから項目を幾つか削った)
package examples.dao.manhole;
import java.io.Serializable;
public class Employee implements Serializable {
    public static final String TABLE = "EMP";
    private long empno;
    private String ename;
    private short deptno;
以下Setter/Getterが続く
  • dicon (examples/dao/manhole/EmployeeDao.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 class="examples.dao.manhole.EmployeeDao">
        <aspect>
            <component class="org.seasar.dao.interceptors.S2DaoInterceptor"/>
        </aspect>
    </component>
</components>

BrendyBrendy2012/02/16 13:18Smart thinking - a cevler way of looking at it.

iqeemirnyiqeemirny2012/02/16 19:32V4EXp1 <a href="http://vffeiklxdzrh.com/">vffeiklxdzrh</a>

fsrcizmmadfsrcizmmad2012/02/17 17:568JhhFX , [url=http://mreyvbmnhtif.com/]mreyvbmnhtif[/url], [link=http://rczlragszegk.com/]rczlragszegk[/link], http://pfiskobgaqqf.com/

ziuqcpvgtisziuqcpvgtis2012/02/20 03:00OoXyQS <a href="http://hfjnoesmzvkk.com/">hfjnoesmzvkk</a>

 | 
2004 | 05 | 06 | 07 | 08 | 09 |