えとせとら


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

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

説明
SupportsNazunaはなにもしません。(デフォルト)
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のような名前になってしまうので、
明示的に名前を付けることを推奨します。