About

ドキュメント

Javadoc

モジュール

プロジェクト文書

Built by Maven

検索

複数件検索

SQLを使って複数件検索をする場合は、 selectBySql()getResultList() を組み合わせます。

List<EmployeeDto> results = 
    jdbcManager
        .selectBySql(
            EmployeeDto.class, 
            "select ... where department_id = ?", 
            10)
        .getResultList();

結果を Map で受け取ることもできます。

List<BeanMap> results = 
    jdbcManager
        .selectBySql(
            BeanMap.class, 
            "select ...")
        .getResultList();

BeanMapはMap<String, Object>なクラスで、 存在しないキーにアクセスすると 例外が発生します。 キーの値は、AAA_BBBのような'_'記法の値ををaaaBbbのようなキャメル記法に 変換したものです。

このルールは、convention.diconで指定されている org.seasar.framework.convention.impl.PersistenceNamingConventionImpl のfromColumnNameToPropertyName()の実装を変えることで、カスタマイズすることができます。

デフォルトでは、結果がなかった場合は、 空の List が返されます。 disallowNoResult() を呼び出すと、 結果がなかった場合は javax.persistence.NoResultException が発生します。

List<BeanMap> results = 
    jdbcManager
        .selectBySql(
            BeanMap.class, 
            "select ...")
        .disallowNoResult()
        .getResultList();

1件検索

SQLを使って1件検索をする場合は、 selectBySql()getSingleResult() を組み合わせます。

Integer count = 
    jdbcManager
        .selectBySql(
            Integer.class, 
            "select count(*) from emp")
        .getSingleResult();

結果を Map で受け取ることもできます。

BeanMap result = 
    jdbcManager
        .selectBySql(
            BeanMap.class, 
            "select ...")
        .getSingleResult();

BeanMapはMap<String, Object>なクラスで、 存在しないキーにアクセスすると 例外が発生します。 キーの値は、AAA_BBBのような'_'記法の値ををaaaBbbのようなキャメル記法に 変換したものです。

このルールは、convention.diconで指定されている org.seasar.framework.convention.impl.PersistenceNamingConventionImpl のfromColumnNameToPropertyName()の実装を変えることで、カスタマイズすることができます。

デフォルトでは、結果がなかった場合は、 null が返されます。 disallowNoResult() を呼び出すと、 結果がなかった場合は javax.persistence.NoResultException が発生します。

BeanMap result = 
    jdbcManager
        .selectBySql(
            BeanMap.class, 
            "select ...")
        .disallowNoResult()
        .getSingleResult();

イテレーションによる検索

検索結果が多くの行を返すため、 List でまとめて受け取ることが困難な場合は iterate(IterationCallback) を使います。

int results = 
    jdbcManager
        .selectBySql(
            BeanMap.class, 
            "select ...")
        .iterate(
            new IterationCallback<BeanMap, Integer>() {
                int count;
                public Integer iterate(BeanMap map, IterationContext context) {
                    if (...) {
                        ++count;
                    }
                    return count;
                }
            });

iterate(IterationCallback) の引数には、 次のインターフェースを実装したクラスのインスタンスを渡します。

  • org.seasar.extension.jdbc.IterationCallback<ENTITY, RESULT>

ENTITYselectBySql() で指定したクラス、 RESULTiterate(IterationCallback) が返す結果の型を指定します。

問い合わせ結果の1行ごとに次のメソッドがコールバックされます。

  • RESULT iterate(ENTITY entity, IterationContext context)

コールバックメソッドが最後に返した値が iterate(IterationCallback) の戻り値となります。

コールバックメソッドの第2引数で渡される org.seasar.extension.jdbc.IterationContext exit プロパティを true にすると、 問い合わせ結果のイテレーションは終了となり、 検索結果の残りは無視されます。 その時の戻り値が iterate(IterationCallback) の戻り値となります。

検索結果の行数取得

SELECT COUNT(*) ~による検索結果の行数を取得する場合は、getCountBySql()を使います。

long count = 
    jdbcManager
        .getCountBySql("select ...");

このメソッドは通常、 select count(*) from ( SQL ) を 実行した結果を返します。

ページング

ページングを指定する場合は、 limit(), offset() を使います。 limit() には、取得する行数を指定します。 offset() には、最初に取得する行の位置を指定します。 最初の行の位置は0になります。 ページングを指定するには、必ず ordey by 句が必要です。 order by句で指定するカラムは、selectリストにも含めるようにしてください。

jdbcManager
    .selectBySql(
        EmployeeDto.class,
        "select id, name from employee order by name")
    .limit(100)
    .offset(10)
    .getResultList();

挿入・更新・削除

1件挿入・更新・削除

SQLを使ってエンティティを更新する場合は、 updateBySql()params()execute() を組み合わせます。 updateBySql() の2番目以降の引数はパラメータのクラスの可変長引数です。 挿入、削除も updateBySql() を使います。

int count = 
    jdbcManager
        .updateBySql(
            "update employee set salary = ? where id = ?", 
            BigDecimal.class, 
            Integer.class)
        .params(null, 1)
        .execute();

一意制約違反によりエンティティを挿入ができなかった場合は、 javax.persistence.EntityExistsException が発生します。

バッチ挿入・更新・削除

SQLを使って複数エンティティをバッチ更新する場合は、 updateBatchBySql()params()execute() を組み合わせます。 updateBatchBySql() の2番目以降の引数はパラメータのクラスの可変長引数です。 挿入、削除も updateBatchBySql() を使います。

List<EmployeeDto> dtoList = ...;
...
SqlBatchUpdate batchUpdate = 
    jdbcManager
        .updateBatchBySql(
            "update employee set salary = ? where id = ?", 
            BigDecimal.class, 
            Integer.class);
for (EmployeeDto dto : dtoList) {
    batchUpdate.params(dto.salary, dto.id);
}
int[] countArray = 
    batchUpdate
        .execute();

一意制約違反によりエンティティを挿入ができなかった場合は、 javax.persistence.EntityExistsException が発生します。

バッチ更新のサイズを指定する

バッチ更新のサイズを設定するには batchSize() を使います。

List<EmployeeDto> dtoList = ...;
...
SqlBatchUpdate batchUpdate = 
    jdbcManager
        .updateBatchBySql(
            "update employee set salary = ? where id = ?", 
            BigDecimal.class, 
            Integer.class);
for (EmployeeDto dto : dtoList) {
    batchUpdate.params(dto.salary, dto.id);
}
int[] countArray = 
    batchUpdate
        .batchSize(50)
        .execute();

ストアドの呼び出し

ストアドプロシージャの呼び出し

SQLを使ってストアドプロシージャを呼び出す場合は、 callBySql()execute() を組み合わせます。 callBySql() の最初の引数は、 ストアドプロシージャを呼び出すSQLです。

最初の例は、パラメータのない場合です。

jdbcManager
    .callBySql("{call myproc}")
    .execute();

INのパラメータが1つだけで、そのパラメータが null にならない場合は、 callBySql() の2番目の引数で値を直接指定します。

jdbcManager
    .callBySql(
        "{call myproc(?)}", 
        "hoge")
    .execute();

上記以外の場合は、 callBySql() の2番目の引数にJavaBeansを指定します。 プロシージャを呼び出すパラメータの順番にJavaBeansのフィールドを定義します。

注意点

S2JDBCは、ソースコード上に記述したフィールドの順番と、 コンパイルされた.classファイル内のフィールドの順番が同じになることを前提としていますが、 これはJavaの仕様では保証されていません. SunのJDKやEclipseではソースコード上と.classファイル内のフィールド順は同じになっていますが、 フィールドの順番が変わってしまう環境ではストアドの呼び出しが失敗します。 フィールドの順番が変わってしまう環境があった場合は Seasar-userメーリングリスト までお知らせください.

  • フィールドにアノテーションが付けられていない場合、 IN パラメータになります。
  • フィールドに @Out アノテーションが付けられている場合、 OUT パラメータになります。
  • フィールドに @InOut アノテーションが付けられている場合、 INOUT パラメータになります。
  • フィールドに @ResultSet アノテーションが付けられている場合、 パラメータ以外で戻される結果セットになります。 ただし、 OracleやPostgreSQLのように、 パラメータ以外で結果セットを返すことが出来ないRDBMSの場合は、 OUT パラメータとして扱われます。
  • フィールドに @Lob が付けられている場合、 そのパラメータはLOBとして扱われます。 @Lob アノテーションは他のアノテーションと組み合わせて使用することが出来ます。
public class MyDto {
    public String arg1; // 第1引数 (IN)

    @Out
    public String arg2; // 第2引数 (OUT)

    @InOut
    public int arg3;    // 第3引数 (INOUT)

    @ResultSet
    public List<String> result; // 結果セット
}
MyDto dto = new MyDto();
dto.arg1 = "hoge";
dto.arg3 = 2;
jdbcManager
    .callBySql(
        "{call myproc(?, ?, ?)}", 
        dto)
    .execute();
System.out.println(dto.arg2);
System.out.println(dto.arg3);
System.out.println(dto.result);

ストアドプロシージャが複数のカラムを持つ結果セットを返す場合は、 対応するフィールドの型をList<結果セットの行に対応するJavaBeansの型>にします。

public class MyDto {
    public int arg1; // 第1引数 (IN)

    @ResultSet
    public List<EmployeeDto> result; // 結果セット
}
MyDto dto = new MyDto();
dto.arg1 = 1;
jdbcManager
    .callBySql(
        "{call myproc(?)}", 
        dto)
    .execute();
System.out.println(dto.result);

オラクルとPostgreSQLの場合は、結果セットをパラメータで受け取る必要があります。 これらのRDBMSでは、 @ResultSet アノテーションが付けられたパラメータは OUT パラメータとして扱われるので、 ストアドプロシージャ呼び出しのSQLの中に対応するバインド変数を付け加えます。

public class MyDto {
    public int arg1; // 第1引数 (IN)

    @ResultSet
    public List<EmployeeDto> result; // 第2引数 (OUT)
}
MyDto dto = new MyDto();
dto.arg1 = 1;
jdbcManager
    .callBySql(
        "{call myproc(?, ?)}", 
        dto)
    .execute();
System.out.println(dto.result);

ストアドファンクションの呼び出し

SQLを使ってストアドファンクションを呼び出す場合は、 callBySql() と、 getSingleResult() または getResultList() を組み合わせます。 callBySql() の1番目の引数でストアドファンクションの戻り値の型を指定します。 2番目の引数でストアドファンクションを呼び出すSQLを指定します。

最初の例はパラメータがなく、 戻り値が結果セットでない場合です。

String result = 
    jdbcManager
        .callBySql(
            String.class, 
            "{? = call myfunc}")
        .getSingleResult();

OracleやPostgreSQLのように、 ストアドファンクションの戻り値で結果セットを返すことが出来る場合は getResultList() で結果の List を受け取ります。 callBySql() の1番目の引数で List の要素の型を指定します。

List<String> result = 
    jdbcManager
        .callBySql(
            String.class, 
            "{? = call myfunc}")
        .getResultList();

結果セットの行が複数のカラムを持つ場合は List の要素をJavaBeansにします。

List<MyDto> result = 
    jdbcManager
        .callBySql(
            MyDto.class, 
            "{? = call myfunc}")
        .getResultList();

INのパラメータが1つだけで、そのパラメータが null にならない場合は、 callBySql() の3番目の引数で値を直接指定します。

String result = 
    jdbcManager
        .callBySql(
            String.class, 
            "{? = call myfunc(?)}", 
            "hoge")
        .getSingleResult();

上記以外の場合は、 callBySql() の3番目の引数にJavaBeansを指定します。 ストアドファンクションを呼び出すパラメータの順番にJavaBeansのフィールドを定義します。

注意点

S2JDBCは、ソースコード上に記述したフィールドの順番と、 コンパイルされた.classファイル内のフィールドの順番が同じになることを前提としていますが、 これはJavaの仕様では保証されていません. SunのJDKやEclipseではソースコード上と.classファイル内のフィールド順は同じになっていますが、 フィールドの順番が変わってしまう環境ではストアドの呼び出しが失敗します。 フィールドの順番が変わってしまう環境があった場合は Seasar-userメーリングリスト までお知らせください.

  • フィールドにアノテーションが付けられていない場合、 IN パラメータになります。
  • フィールドに @Out アノテーションが付けられている場合、 OUT パラメータになります。
  • フィールドに @InOut アノテーションが付けられている場合、 INOUT パラメータになります。
  • フィールドに @ResultSet アノテーションが付けられている場合、 パラメータ以外で戻される結果セットになります。 ただし、 OracleやPostgreSQLのように、 パラメータ以外で結果セットを返すことが出来ないRDBMSの場合は、 OUT パラメータとして扱われます。
  • フィールドに @Lob が付けられている場合、 そのパラメータはLOBとして扱われます。 @Lob アノテーションは他のアノテーションと組み合わせて使用することが出来ます。
public class MyDto {
    public String arg1; // 第1引数 (IN)

    @Out
    public String arg2; // 第2引数 (OUT)

    @InOut
    public int arg3;    // 第3引数 (INOUT)

    @ResultSet
    public List<String> result; // 結果セット
}
MyDto dto = new MyDto();
dto.arg1 = "hoge";
dto.arg3 = 2;
String result = 
    jdbcManager
        .callBySql(
            String.class, 
            "{? = call myfunc(?, ?, ?)}", 
            dto)
        .getSingleResult();
System.out.println(result);
System.out.println(dto.arg1);
System.out.println(dto.arg3);
System.out.println(dto.result);

ストアドファンクションが複数のカラムを持つ結果セットを返す場合は、 対応するフィールドの型をList<結果セットの行に対応するJavaBeansの型>にします。

public class MyDto {
    public int arg1; // 第1引数 (IN)

    @ResultSet
    public List<EmployeeDto> result; // 結果セット
}
MyDto dto = new MyDto();
dto.arg1 = 1;
String result = 
    jdbcManager
        .callBySql(
            String.class, 
            "{? = call myfunc(?)}", 
            dto)
        .getSingleResult();
System.out.println(result);
System.out.println(dto.result);

オラクルとPostgreSQLの場合は、戻り値以外の結果セットをパラメータで受け取る必要があります。 これらのRDBMSでは、 @ResultSet アノテーションが付けられたパラメータは OUT パラメータとして扱われるので、 ストアドファンクション呼び出しのSQLの中に対応するバインド変数を付け加えます。

public class MyDto {
    public int arg1; // 第1引数 (IN)

    @ResultSet
    public List<EmployeeDto> result; // 第2引数 (OUT)
}
MyDto dto = new MyDto();
dto.arg1 = 1;
String result = 
    jdbcManager
        .callBySql(
            String.class, 
            "{? = call myfunc(?, ?)}", 
            dto)
        .getSingleResult();
System.out.println(result);
System.out.println(dto.result);