## えとせとら

- 自動トランザクション制御
- Nazuna Remoting
- フィルタ
- ソート
- グルーピング

## 自動トランザクション制御

Nazunaは、transAttributeの設定に応じて、自動でトランザクション制御を行ってくれます
設定可能な値は以下のとおりです。

値 | 説明
--- | ---
Supports | Nazunaはなにもしません。(デフォルト)
Required | トランザクションが開始されていなければ、 Nazunaがトランザクションを開始します。 既にトランザクションが開始されていれば、 そのトランザクションを引き継ぎます。
RequiresNew | 常に新しいトランザクションを開始させます。 既存のトランザクションが開始されているなら、 既存のトランザクションを中断し、 自分自身のトランザクションの終了後、 中断したトランザクションを復帰させます。
Mandatory | トランザクションが既に開始されてなければエラーにします。

## Nazuna Remoting

別のSeasarにデプロイされているルールを、ローカルのルールと同じように
呼び出すことができます。
呼び出し方は、これまでと全く同じで、Nazuna.executeXxx(...)です。
WEB-INF/classesのnazuna-remoting.xmlに設定内容に従って
Nazunaが透過的に、リモート呼び出しを実行してくれます。

#### nazuna-remoting.xmlの例

    <nazuna-remoting>
        <remote name="remote">
            <url>rmi://foo:1108</url>
            <url>rmi://bar:1108</url>
        </remote>

        <default location="local"/>

        <rule name="aaa.RemoteRulet" location="remote"/>
    </nazuna-remoting>

remoteタグのname属性で、リモートの設定に名前をつけます。
後でlocation属性で参照するときに利用します。

urlタグのボディにリモートSeasarに接続するために情報を記述します。
プロトコルのrmiは今のところ固定です。
ホスト名:ポートの部分は、リモートSeasarのseasar-config.xmlの
RMIAdaptorServiceのポートとあわせます。
urlタグを複数記述すると、ラウンドロビンによる負荷分散と障害発生時の
フェールオーバーをしてくれるようになります。

defaultタグのlocation属性で、後述するruleタグで指定されていないルールを
呼び出すときのNazunaの位置を指定します。
localだと同一VM内のNazunaを呼び出します。
remoteタグのname属性で設定した名前を指定すると、デフォルトの呼び出しが
すべてリモート呼び出しになります。

ruleタグのname属性には、Rulet,Flowlet,Sqletの名前を指定します。
ここで指定したルールが、location属性で指定した位置で実行されます。
location属性には、local及びremoteタグのname属性で設定した名前を指定できます。

## フィルタ

Nazuna.executeQuery()した結果(List)を、特定の条件で絞り込見たい場合、
org.seasar.nazuna.FilterDescクラスを使います。
例えば、departmentNoが20である従業員のデータを絞り込みたいときには次のようにします。
Listの要素は、itemという名前で参照します。

    List result = Nazuna.executeQuery(...);
    FilterDesc filterDesc = new FilterDesc("item.departmentNo = 20");
    List filteredResult = filterDesc.filter(result);

条件にはパラメータも使えます。
次の例は、deptnoという名前でパラメータを渡しています。

    List result = Nazuna.executeQuery(...);
    FilterDesc filterDesc = new FilterDesc("item.departmentNo = deptno");
    Map parameters = new HashMap();
    parameters.put("deptno", new Integer(20));
    List filteredResult = filterDesc.filter(result, parameters);

FilterDesc.filterFirst()を使うと、条件に一致した最初の要素を取得できます。
条件に一致する要素が見つかった時点で、処理をやめて結果を返すため、
1件しか結果が返ってこないことがわかっている場合は、filterFirst()を使ったほうが、
パフォーマンスが良くなります。

    List result = Nazuna.executeQuery(...);
    FilterDesc filterDesc = new FilterDesc("item.employeeNo = 7788");
    Employee emp = (Employee) filterDesc.filterFirst(result);

## ソート

Nazuna.executeQuery()した結果(List)を、ソートしたい場合、
org.seasar.nazuna.SortDescクラスを使います。
例えば、departmentNoで降順、employeeNameで昇順にソートする場合、次のようにします。
SQLのOrdery By句と同じです

    List result = Nazuna.executeQuery(...);
    SortDesc sortDesc = new SortDesc("departmentNo desc, employeeName");
    List sortedResult = sortDesc.sort(result);

## グルーピング

Nazuna.executeQuery()した結果(List)を、グルーピングしたい場合、
org.seasar.nazuna.GroupDescクラスを使います。
例えば、departmentNo単位で、salaryの合計を求める場合、次のようにします。
SQLでGroup Byするときの選択リスト(SELECT句とFROM句の間)と同じです

    List result = Nazuna.executeQuery(...);
    GroupDesc groupDesc = new GroupDesc("departmentNo, SUM(salary) as totalSalary");
    List groupedResult = groupDesc.group(result);
    for (int i = 0; i < groupedResult.size(); i++) {
        EMap item = (EMap) groupedResult.get(i);
        System.out.println(item.get("departmentNo"));
        System.out.println(item.get("totalSalary"));
    }

グルーピングした結果のリストの各要素は、org.seasar.util.EMapオブジェクトになります。
上記の場合、EMapには、departmentNo, totalSalaryをキーとする値が存在します。
EMapは、java.util.Mapを実装したクラスですが、ArrayListのような側面も持っていて、
get(int index)、getKey(int index)のようにputした順番で、アクセスできます。
上記の場合、get(0)でdepartmentNoの値が取得でき、get(1)でtotalSalaryの値が取得できます。
集計した項目は、asで名前を付けます。名前を付けない場合は、_0のような名前になってしまうので、
明示的に名前を付けることを推奨します。