PEXA Serviceについて
チュートリアル
テストツール
定義ファイル
基本プロセス
拡張プロセス
Condition
セッション
モデル
リファレンス
環境設定
|
searchプロセス概要
|
データモデルを検索するためのプロセスです。
モデルフレームワークを経由してデータベースからモデルを検索する場合と、
ServiceSession上に格納されているモデルのListから抽出を行う場合があります。
なお、PEXA2では定義ファイルだけでは検索条件(filter, extra_filter)の組み立てを動的に行うことができず、
SearchFilterのHelperクラスを作成することが多かったのですが、PEXA3以降ではこの部分が拡張されており、
Session値の内容を判定しながら柔軟に検索条件を組み立てることが可能となっています。
詳細はfilterセクションの解説を参照してください。
また、PEXA4以降では検索結果の取得制限を行う機能が追加されています。
現在、PEXAのService実行エンジンは処理対象データををモデルフレームワークで取り扱っており、
searchプロセスによる検索結果は基本的にデータモデルインスタンスとしてメモリ上にあがります。
そのため、検索で100万件ヒットすれば100万件分のデータがそのままメモリにあがってしまい、
応答の遅延やメモリ圧迫による実行時エラーを引き起こす原因となります。
このような現象を回避するために、offset, limit, proxy_onlyというパラメータが新たに追加されました。
詳細は「検索結果データによるメモリ圧迫の回避方法」を参照して下さい。
モデルの検索に必要な情報を以下の書式で記述します。
|
|
searchフォーマットタイプ書式
|
(プロセス名
format_type search
(search
source宣言部(1)
session_value宣言部(0|1)
filterセクション(0|1)
preload宣言部(0|1)
extra_filterセクション(0|1)
sort宣言部(0|1)
extra_sort宣言部(0|1)
portfolio属性(0|1)
unique属性(0|1)
zero_is_null属性(0|1)
appned属性(0|1)
offset宣言部(0|1)
limit宣言部(0|1)
proxy_only属性(0|1)
)
)
記述注:
属性 あらかじめ決められた値を選択する(true/falseなど)
宣言部 値または、値のリストを設定する
セクション 入れ子で他の属性、宣言部、セクションを保持する可能性がある
(値又は、値のリストが設定される場合もある)
(1):必須
(0|1):オプション
(1以上):一個以上必須
(0以上):0個以上(オプション)
source宣言部
|
概要:
検索対象を指定する。
データベースから検索する場合はモデル名を指定する。
Session上のモデルコレクションから抽出したい場合はセッションキーを指定する。
また、Session上の単体モデルやモデルコレクションに対してパス式で明細モデル等を指定して、そこから抽出することも出来る。
形式:
Key・値
記述1:モデルを指定する
source モデル名
記述例:
source 交通費精算書
記述2:ServiceSessionキーを指定する
source @ServiceSessionキー名
記述例:
source @TargetModelList
ServiceSessionキーの値は下記のいずれかである必要がある
- モデル(Observableのサブクラス)のコレクション
- モデル(Observableのサブクラス)の配列
- Portfolio
記述3:Session上の単体モデルやモデルコレクションに対してパス式を指定する。
source @ServiceSessionキー名/現象型パス
記述例:
source @交通費精算書/交通費精算書明細
ServiceSessionキーの値はモデルである必要がある。
また、パス式を指定して取得される対象は下記のいずれかである必要がある。
- モデル(Observableのサブクラス)のコレクション
- モデル(Observableのサブクラス)の配列
- Portfolio
|
|
session_value宣言部
|
概要:
検索結果を保持するServiceSessionのキー名を指定する。
ここではキー名の前に"@"は付けないので注意すること。
形式:
Key・値
記述:
session_value ServiceSessoinキー名
記述例:
session_value 申請書一覧
|
|
preload宣言部
|
概要:
PEXA3以降の機能です。
サーバー内でモデルマッピングの結果をキャッシュするための指定です。
preloadを使用する目的は主に以下の2つがあります。
モデルが直接持たない項目を検索条件としてextra_filterで指定する
この機能はfilterによる検索とextra_filterによるメモリ上での絞り込みの間のタイミングで動作します。
そのため、FK先のデータモデルが持つ項目をあらかじめpreloadで取得しておくことでextra_filterによる絞り込みが行えるようになります。
なお、source宣言で指定した検索対象がセッション上のモデル集合の場合、このpreloadはfilterの適用前に動作しますので、DBに対する検索時と同じように扱えます。
画面でのデータ一覧表示のパフォーマンスチューニング
PEXAでは、モデルフレームワークの機能により、モデル中にProxy(モデルをユニークに特定するプライマリキー値オブジェクト)の
現象型項目が含まれている場合は、スラッシュ区切り(パス形式)でその先につながっているモデルを取得することが出来ます。
しかし、ClientFrameworkがTableコンポーネントなどにモデルの検索結果一覧を大量に表示したりする場合は、スラッシュ区切りで
値を取得しているセルの数だけサーバー側にProxy経由でモデルの問い合わせが発生してパフォーマンスが大幅に落ちることになります。
このような場合は、このpreloadオプションを指定することによって、サーバーサイド内であらかじめ必要な問い合わせを行って結果をキャッシュした状態で
Clientに検索結果を送ることによって問題を回避できます。
また、サーバーに問い合わせが発生するようなProcedure項目の値を表示しているようなケースにおいてもpreload宣言は効果が出ます。
画面表示を行っている間でリアルタイムに値が変化して見える必要が無いのであれば、検索直後にpreload指定で値を引いてキャッシュして
おくことで画面での一覧表示等が軽くなります。
記述形式:
なお、preload宣言の指定方法には配列形式とMap形式の2通りがあります。
前者は旧来からある指定方法ですが、パス形式の値には効果が薄い形式です。(Procedure項目には効果があります)
パス形式の値を一覧表示する項目としてキャッシュする場合はMap形式による記述で指定して下さい。
Map形式での記述:
(preload
キャッシュ対象の現象型 キャッシュする値の取得パス(パス式)
キャッシュ対象の現象型 キャッシュする値の取得パス(パス式)
キャッシュ対象の現象型 キャッシュする値の取得パス(パス式)
)
記述例:
PatientNo,Creator,LastUpdator,OperatorというProxy項目に紐尽く値をあらかじめpreloadしておく。
;--------------------------------------------------------
; 操作ログモデルを検索する
;--------------------------------------------------------
(操作ログを検索する
(before_condition
exist ログイン情報
)
format_type search
(search
source OperationLog
session_value 操作ログ検索結果
filter "Operator = @ログイン情報/UserNo and OperationDatetime >= &Today"
sort ~OperationDatetime
(preload
PatientID PatientNo/PatientID
PatientName PatientNo/PatientName
CreatorName Creator/UserName
UpdatorName LastUpdator/UserName
RemoverName Remover/UserName
)
)
)
配列形式での記述:
preload キャッシュ対象の現象型(パス式),キャッシュ対象の現象型(パス式),.......
記述例:
PatientNo,Creator,LastUpdator,OperatorというProxy項目に紐尽く値をあらかじめpreloadしておく。
;--------------------------------------------------------
; 操作ログモデルを検索する
;--------------------------------------------------------
(操作ログを検索する
(before_condition
exist ログイン情報
)
format_type search
(search
source OperationLog
session_value 操作ログ検索結果
filter "Operator = @ログイン情報/UserNo and OperationDatetime >= &Today"
sort ~OperationDatetime
preload "PatientNo/PatientID,PatientNo/PatientName,Creator/UserName,LastUpdator/UserName,Operator/UserName"
)
)
|
|
sort宣言部
|
概要:
検索条件の結果に対してソートを行いたい場合に、ソート条件となる項目(=現象型名)を指定します。
ここで指定できる現象型は、DBカラムにO/Rマッピングされている現象型のみになります。
ここでの指定がDBに対して実行エンジンが発行するselect文に反映されるためです。
Procedure項目、Alias項目といったDBカラム以外にマッピングされている現象型も含めてソート条件にしたい場合はextra_sort宣言部で指定してください。
もしsortとextra_sortの両方を指定すると、最初にsortで指定された条件でDB側でソートされた検索結果が取得されて、その検索結果に対してextra_sortで指定された条件でソートし直されてしまいます。
複数項目でソートを行いたい場合は、ソート条件にする現象型名をカンマつなぎで複数個指定してください。
また、項目名の前に"~"をつけると、降順によるソートになります。つけないと昇順によるソートになります。
記述:
sort ソート項目の現象型,ソート項目の現象型,~ソート項目の現象型,.......
記述例:
CreateDatetimeの昇順およびLastUpdateDatetimeの降順でソートする
;--------------------------------------------------------
; 部署マスタを検索して、作成日と最終更新日でソートする
;--------------------------------------------------------
(部署マスタを検索してソートする
format_type search
(search
source DepartmentMaster
session_value 部署マスタ検索結果
filter "RemovedFlag = NOT_REMOVED"
sort CreateDatetime,~LastUpdateDatetime
)
)
|
|
extra_sort宣言部
|
概要:
検索条件の結果に対してソートを行いたい場合に、ソート条件となる項目(=現象型名)を指定します。
ここで指定できる現象型は、DBカラムにマッピングされている項目に加えて、Procedure項目、Alias項目といったDBカラム以外にマッピングされている現象型になります。
DBカラムにO/Rマッピングされている現象型のみをソート条件にしたい場合はsort宣言部で指定してください。
そうすることで、実行エンジンがDBに対して発行するselect文にsortで指定された条件が反映されて、DB側でソート処理を行わせることができます。
複数項目でソートを行いたい場合は、ソート条件にする現象型名をカンマつなぎで複数個指定してください。
また、項目名の前に"~"をつけると、降順によるソートになります。つけないと昇順によるソートになります。
記述:
extra_sort ソート項目の現象型,ソート項目の現象型,~ソート項目の現象型,.......
記述例:
部署存続年数(Procedure項目)の降順でソートする
;--------------------------------------------------------
; 部署マスタを検索して、作成日と最終更新日でソートして
; さらに部署存続年数(Procedure項目)の降順でソートする。
;--------------------------------------------------------
(部署マスタを検索してソートする
format_type search
(search
source DepartmentMaster
session_value 部署マスタ検索結果
filter "RemovedFlag = NOT_REMOVED"
sort CreateDatetime,~LastUpdateDatetime
extra_sort ~部署存続年数
)
)
|
|
portfolio属性
|
概要:
検索結果をPortfolioとして保持するか否かを指定する。
portfolio属性が指定されなかった場合は、portfolioで作成しない("false")が選択された物と見なされる。
形式:
Key・値
区分値:
true/false デフォルトは"false"
- true ポートフォリオで値を返す。
- false コレクションで値を返す。
記述:
portfolio true
portfolio false
|
|
unique属性
|
概要:
検索の結果を単独のモデル(Updatable)で返すか否かを指定する
ただし、検索結果が複数存在した場合は例外が発生する。
unique属性を指定しなかった場合は、uniqueにしない("false")が指定されたと見なされる。
マスタをコードで引く場合などに利用する。
形式:
Key・値
区分値:
true/false デフォルトでは"false"
- true 単独のモデルで返す。複数返ってきたら例外を送信する
- false 1つ場合でもコレクションを返す。
記述:
unique true
unique false
|
|
zero_is_null属性
|
概要:
検索結果が0の場合、nullを返すか否かを指定する。
zero_is_nullが省略された場合は、nullを返さない("false")が指定された物と見なされる。
zero_is_nullがfalseの場合は検索結果が0の場合は空のコレクションを返す。
重複チェックなどで、存在したら終了条件で例外を投げるなどの処理をしたい場合に利用する
形式:
Key・値
区分値:
true/false デフォルトでは"false"
- true 検索結果が0の場合はnullを返す
- false 検索結果が0の場合は空のコレクションを返す。
記述:
zero_is_null true
|
|
appned属性
|
概要:
appendにtrueが設定されている場合、session_valueに設定されているCollectionに検索結果が追加されます。
ただし、unique属性ならびに、zero_is_null属性が設定されている場合はappend属性の宣言は無視されます(設定されていても追加処理は行われない)
portfolio属性が追加されている場合は、portfolioに対して追加が行われます。
形式:
Key・値
区分値:
true/false デフォルトでは"false"
- true session_valueに設定されているCollectionに検索結果が追加されます。
- false 検索結果が0以上ならsession_valueに設定されているServiceSessionのキー名に格納する。
false指定の時に、すでにCollectionにデータが入っていた場合はすでに入っていたデータは破棄されます。
記述:
appned true
|
|
offset宣言部
|
概要:
PEXA4以降の機能です。
検索結果の集合から特定の開始インデックス以降のデータのみ取得したい場合に、その開始オフセットを指定する。
offsetが省略された場合は、0が指定された物と見なす。
このoffset宣言部と後述のlimit宣言部と組み合わせて使用することで、検索結果の取り扱いを柔軟に行うことが出来ます。
例えば、検索条件に合致するデータが1万件あったとしても、一度に画面表示させるのを20件ずつとしてそれ以降は
「進む」「戻る」ボタンで特定の開始位置(=offset)から20件分を取得するといった事が可能となります。
なお、このoffset値は「0」からスタートとなります。「1」ではありませんので注意して下さい。
記述:
offset 検索結果の集合から抽出する開始インデックス(@付きのセッション値も指定可)
記述例:直接記述
offset 0
記述例:セッション値で動的に指定
offset @開始オフセット値
|
|
limit宣言部
|
概要:
PEXA4以降の機能です。
検索結果の集合から特定の件数分だけデータを取得したい場合に、その取得最大件数を指定する。
limitが省略された場合は、-1(無制限)が指定された物と見なす。以下のような動作となります。
- 検索結果件数 > limit : limitで指定された件数のデータのみメモリにあがる
- 検索結果件数 <= limit : 検索結果データが全てメモリにあがる
例えばlimit=100と指定されている場合、
検索条件に合致したデータが1万件あったとしても、100件分のみが検索結果としてメモリ上にあがることになります。
逆に、検索条件に合致したデータが10件しかない場合は10件が全てメモリにあがります。
前述のoffset宣言部とこのlimit宣言部と組み合わせて使用することで、検索結果の取り扱いを柔軟に行うことが出来ます。
例えば、検索条件に合致するデータが1万件あったとしても、一度に画面表示させるのを20件ずつとしてそれ以降は
「進む」「戻る」ボタンで特定の開始位置(=offset)から20件分を取得するといった事が可能となります。
記述:
limit 検索結果の集合から抽出するデータ件数(@付きのセッション値も指定可)
記述例:直接記述
limit 50
記述例:セッション値で動的に指定
limit @抽出件数
|
|
proxy_only属性
|
概要:
PEXA4以降の機能です。
検索結果をデータモデルではなくProxy値のリストで取得したい場合に指定する。
proxy_onlyが省略された場合は、データモデルとして返す("false")が指定された物と見なされる。
この属性でtrueを指定した場合、searchプロセスの以下の機能と組み合わせることは出来ない。
- portfolio属性
- extra_filter宣言部
- extra_sort宣言部
- preload宣言部
offset宣言部およびlimit宣言部は同時に指定できます。
上記2つを同時に指定すると、何件目から何レコード分のProxy値のみ取得という形で検索結果を取得できます。
この機能は、以下のようなケースで使用して下さい。
- バッチ処理などで大量のデータを処理する場合で一度に大量のメモリを占有したくない場合
- 大量の検索結果をメモリ上で保持しておいて、指定された分だけ表示に回す場合
形式:
Key・値
区分値:
true/false デフォルトでは"false"
- true 検索結果をProxy値のリストで返す
- false 検索結果をモデルのリストで返す(デフォルト)
記述:
proxy_only true
|
|
|
|
filterサブセクション
|
概要:
検索条件を指定する。
検索条件文の書式については以降で解説しているので、詳細はこちらを参照して下さい。
検索対象がモデルの場合、filterに記述された検索条件はSQLのselect文に変換される。
モデルがカラムとして保持していない業務項目を指定した場合はシステム例外が発生する。
手続きによる現象型などに対する条件を記述する場合は、extra_filterサブセクションを利用する事。
filterサブセクションおよびextra_filterサブセクションの両方が存在しない場合は、検索条件なしの検索が実行される。
ただし、モデルに"static_filter"が設定されている場合は、検索条件に対して常にstatic_filterの内容が"and"で適用される。
モデル以外の場合は、特にDBで保持しているか否かに関する制限は存在しない。
指定の仕方は、
の4種類が存在する。それぞれの記述形式について以降で個別に解説する。
記述:
固定的なフィルタ条件式を指定する
|
検索条件式の構成そのものが必ず固定である場合、検索条件式を右辺に直接記述します。
filter "モデル検索条件式"
これは、検索条件値そのものが固定であるか、もしくはSession値として呼出元から値を必ずもらえる場合の記述方法です。
例えば、以下のような形です。
;;-----------------------------------------------------
;;例:絶対にnullにならないセッション値及び固定値で指定
;;-----------------------------------------------------
filter "現象型A = @A and RemovedFlag = NOT_REMOVED"
モデル検索条件式の書式については、以降で解説していますので詳細はこちらを参照してください。
|
|
動的なフィルタ条件式を指定する
|
PEXA3以降の機能です。
従来はSearchFilterクラスを作成して外部Helperとして指定しないと対応できなかった、
動的な検索条件式の組み立てを定義ファイルの記述のみで行えます。
condition宣言部及びexist宣言部を上から順に判定されて、
判定結果がtrueになったブロックのfilterの内容がモデルの検索条件式に加えられていく形になります。
以下のような書式で指定します。
書式:
(プロセス名
format_type search
(search
source xxxx
session_value yyyy
[filter
operator属性(0|1)
condition宣言部(0|1)
exist宣言部(0|1)
append属性(0|1)
filterセクション(1)
,
operator属性(0|1)
condition宣言部(0|1)
exist宣言部(0|1)
append属性(0|1)
filterセクション(1)
,
operator属性(0|1)
condition宣言部(0|1)
exist宣言部(0|1)
append属性(0|1)
[filter
operator属性(0|1)
condition宣言部(0|1)
exist宣言部(0|1)
append属性(0|1)
filterセクション(1)
,
operator属性(0|1)
condition宣言部(0|1)
exist宣言部(0|1)
append属性(0|1)
filterセクション(1)
]
,
:
:
:
]
)
)
記述注:
属性 あらかじめ決められた値を選択する(true/falseなど)
宣言部 値または、値のリストを設定する
セクション 入れ子で他の属性、宣言部、セクションを保持する可能性がある
(値又は、値のリストが設定される場合もある)
(1):必須
(0|1):オプション
(1以上):一個以上必須
(0以上):0個以上(オプション)
説明:
conditionには、任意のセッション条件式を指定することができます。
conditoinが成立した場合のみ、filter条件がモデルの検索条件式に追加されます。
また、conditionの代わりにexistで、存在、非存在のsessionキーを指定することも可能です。
;;---------------------------------------------------------
;;existの指定例:AとBがnullではなく、Cがnullの場合に適用
;;---------------------------------------------------------
[filter
exist A,B,~C
filter "現象型A = @A and 現象型B = @B"
,
exist D
filter "現象型D = @D"
]
また、append=falseを指定すると、conditionが真の場合、そこでfilter内容を確定して先の評価を行いません。
これにより、switch的にfilterを選択することもできます。
内部に、入れ子の[filter...]を指定した場合は、条件分で()を指定したのと同じように評価されます。
なお、appendフラグの評価は、[filter...]の単位で評価されます。
また、condition、operator,appendは、省力可能です。
その場合は、それぞれ条件無し、AND,trueが指定されたのと同じです。
filterに記述するモデル検索条件の書式は以降で解説していますので、こちらを参照してください。
また、動的検索条件の記述例は別途用意してありますので、こちらを参照してください。
|
|
外部Helperを指定する
|
先頭の"!"に続けて外部Helperを指定する。
filter !外部Helper
外部Heplerには以下の2種類の外部Helperを指定することができる
- JavaHelperクラス
- SessionBeanHelper
JavaHelperクラスを指定する場合は、パッケージ名を含むクラス名を記述する。
記述例:
filter !imeg.share.business.filter.交通費精算書.交通費精算書未申請検索SearchFilter
JavaHelperクラスは、下記のインタフェースを実装する必要がある。
pexa.share.service.ServiceSessionObservableFilter
なお、pexaは外部Helperクラスオブジェクトを取得するに当たって、下記の順番でメソッド、コンストラクタを検索する
- staticなgetInstance(pexa.share.util.res.Resource)
- staticなgetInstance()
- pexa.share.util.res.Resourceを引数に持つコンストラクタ
- デフォルトコンストラクタ
|
|
検索SessionBeanのJNDIパス名を指定する
|
SessionBeanHelperクラスを指定する場合は、JNDIパス名を指定する。
filter !JNDIパス名
JNDIパス名には必ず":"が含まれている必要がある。
記述例:
filter !facade:交通費精算書未申請検索SearchFilterSession
ただし、ServiceSessionHelperは以下のインタフェースを実装している必要がある。
pexa.share.service.process.SearchFilterFacade
|
|
|
|
extra_filterサブセクション
|
概要:
データベースのテーブルにマッピングされていない現象型に対する検索条件を指定する。
extra_filterは、filterが存在すれば
(filter条件式) and (extra_filter条件式)
に相当する条件でモデルの検索が行われる。
ただし、extra_filterで記述された検索条件は、常にメモリー上のモデルのコレクションに対して行われる。
すなわち、filterの検索条件で行われたDBに対する検索条件が適用された後、メモリー上に存在する検索結果に対してextra_filterの検索条件が適用される。
よって、extra_fliterの検索条件にはそれがDB上の値であるか、動的な値であるかを関わらず、検索条件を記述することができる。
filterが存在しない場合は、モデルに対して無条件の検索が行われて、その結果に対してextra_filter条件の検索が行われる。
filterもextra_filterも存在しない場合は、無条件での検索結果が返される。
ただし、モデルのstatic_filterが存在すれば、その検索条件はfilterやextra_filterの有無にかかわらず常に適用される。
extra_filterでの指定の仕方は、filterサブセクションと全く同じです。
記述:
filterサブセクションの書式に同じ。
動的なフィルタ条件式を指定する場合も同じ記述になります。
記述例:動的なフィルタ条件式
(Session上のXXXから抽出する
format_type search
(search
source @XXX
session_value 抽出結果
[extra_filter
condition "@A is not null"
filter "現象型A = @A"
append true
,
operator and
condition "@B is not null"
filter "現象型B = @B"
]
)
)
|
|
検索結果データによるメモリ圧迫の回避方法
|
searchプロセスはPEXAのモデルフレームワークに接続してデータ検索を行います。
そのため、基本的な動作としては検索条件に合致したデータを全てデータモデルインスタンスとしてメモリ上に格納するため、
大量のデータがヒットした場合は以下のような問題が発生することがあります。
- 大量のデータモデルインスタンスがメモリを圧迫して実行時エラーを引き起こす
- 大量のデータモデルインスタンスの生成に時間がかかって応答が遅延する
このような現象を回避するための方法として、PEXA4以降では以下のパラメータが追加されました。
これらのパラメータを組み合わせることで、検索結果を全てメモリに格納せず、特定のデータのみ処理することが可能となりました。
以下のようなケースで活用して下さい。
検索結果を「進む」「戻る」で行き来させて表示
|
ネットショップや検索エンジンの検索結果などで、検索結果自体の件数が数万件に上ることがありますが、
そのような場合でもWebブラウザで表示されるのは一度に30件程度となって次に進むリンクをクリックすると
次の30件が表示されるような画面を見たところがあると思います。
offset宣言部およびlimit宣言部を利用することで、このような画面の動作をさせることが可能となります。
画面に一度に表示させる件数をlimit宣言部で指定し、offset宣言部で何件目をスタート地点とするかを指定してください。
どちらもセッション値を指定できるので処理の都度、動的に指定できます。
また、検索実行時の結果を保持しておきたいのであればproxy_only属性でProxy値のみをメモリに格納してください。
このようにすれば大量データでもメモリを圧迫せずにすみます。
|
|
大量データのバッチ処理におけるメモリ圧迫回避
|
バッチ処理で一度に大量のデータを扱うような場合に、対象データをそのままメモリに上げてしまうと検索が終了した時点で
実行時エラーになるようなケースでは、proxy_only属性を指定することである瞬間のメモリ消費量を節約することが出来ます。
たとえば、ある一日の業務データを夜間バッチで集計するような場合に、その日の日付指定で業務データを検索した結果が
30万件あるような場合はproxy_only属性を指定して検索結果をProxy値のリストとして取得するだけにしておくことで
30万件分のデータモデルインスタンスが処理中にずっとメモリに居座ることが無くなります。
プロキシ値はPEXA4においてはlong型整数値なので、単純に考えれば1件に付き8Byte分しかとらないので、
例え30万件分のデータであっても2.4MB分しかメモリを使用しません。
|
|
|
|
IN条件でのDBエラー対応
|
searchプロセスでDB検索条件に以下のようなIN比較式を指定すると、DBの種類によっては実行時エラーが発生します。
- 1000件以上の値をIN比較の右辺値に指定した場合(Oracle)
- 483件以上のIdentifiedProxyをIN比較の右辺値に指定した場合(SQLServer)
このような現象に可能な限り対応するために、実行エンジンではこれに該当する検索条件が記述された場合は内部で自動的に検索条件式を分割します。
例:1800件の値を比較するIN条件の分割イメージ
分割前:項目A IN("値1","値2", ..... , "値1800")
分割後:項目A IN("値1","値2", ..... , "値900") OR 項目A IN("値901", "値902", ... ,"値1800")
これにより、ある程度の件数に対してはDB実行時エラーを発生させずに検索実行することができます。
ただし、IN比較式は比較対象の件数が多いと色々なDBがエラーを返しやすいので、件数が多くなる場合はなるべく他の手段を検討するほうが無難です。
実行エンジン側では対応できないエラーもありえます。
例:SQLServerは1SQL文のPreparedStatementで"?"の数が2200件を越えるとエラー
→2200件以上のIN比較はSQLServerでは実行不可能。
分割対象の件数設定
|
IN条件のエラー回避のために内部で行われるフィルタ分割の閾値は/src/plugins/pexa_plugins.entryでプロジェクトごとに設定できます。
記述例
;;---------------------------------------------------------------
;; SearchFilter Option
;;---------------------------------------------------------------
singlevalue_in_compare_max 900
multivalued_in_compare_max 450
指定がない場合はデフォルトで以下のようになります。
- SingleValueのIN最大件数:900件
- MultiValuedのIN最大件数:450件
|
|
|
|
モデル検索条件式書式
|
書式:
現象型名 比較演算子 比較値
モデルに対する検索条件式については、モデル評価式のガイドに別途記載されています。
詳細はそちらを参照して下さい。
|
|
動的なモデル検索条件式の記述例
|
ケース毎に、モデル検索条件式の記述例を以下に何点か挙げておきます。
例1:Session値の有無で検索条件式を組み立てる場合
|
サービスの呼び元から渡されたパラメータとして、セッションキーA,B,Cがあるとします。
それぞれはnullになる可能性があるため、nullではない値に対してのみ検索条件を組み立てるとします。
;;---------------------------------------------------------
;; 記述例:セッション値A,B,Cを元に検索条件を組み立てる場合
;;---------------------------------------------------------
(XXXを検索する
format_type search
(search
source XXX
session_value XXX検索結果
[filter
;;-------------------------------------------
;; Aに対する条件式
;;-------------------------------------------
eixst A
filter "現象型A = @A"
,
;;-------------------------------------------
;; Bに対する条件式
;;-------------------------------------------
operator and
eixst B
filter "現象型B = @B"
,
;;-------------------------------------------
;; Cに対する条件式
;;-------------------------------------------
operator and
eixst C
filter "現象型C = @C"
]
)
)
セッションキーA,B,Cの値が全てnullでなければ、モデルの検索条件式は
"現象型A = @A and 現象型B = @B and 現象型C = @C"
となり、仮にセッションキーBの値がnullの場合はモデルの検索条件式は
"現象型A = @A and 現象型C = @C"
となる。
|
|
例2:Session値の内容の組み合わせで検索条件式を組み替える場合
|
サービスの呼び元から渡されたパラメータとして、セッションキーA,B,Cがあるとします。
それぞれのうちどれか一つでもnullでなければその項目で検索条件式を組み立てるが、全てnullの場合は別の条件式を適用する。
;;---------------------------------------------------------
;; 記述例:セッション値A,B,C全てnullなら別条件式にする
;;---------------------------------------------------------
(XXXを検索する
format_type search
(search
source XXX
session_value XXX検索結果
[filter
;;-------------------------------------------
;; A, B, Cが全てnullの場合の条件式
;;-------------------------------------------
condition "@A is null and @B is null and @C is null"
filter "RemovedFlag = NOT_REMOVED"
append false
,
;;-------------------------------------------
;; Aに対する条件式
;;-------------------------------------------
eixst A
filter "現象型A = @A"
append true
,
;;-------------------------------------------
;; Bに対する条件式
;;-------------------------------------------
operator and
eixst B
filter "現象型B = @B"
append true
,
;;-------------------------------------------
;; Cに対する条件式
;;-------------------------------------------
operator and
eixst C
filter "現象型C = @C"
append true
]
)
)
セッションキーA,B,Cの値が全てnullの場合、appendがfalseなので以降のブロックは評価されないため、モデルの検索条件式は
"RemovedFlag = NOT_REMOVED"
だけとなる。
セッションキーA,B,Cのいずれかがnullでは無い場合は、例1と同じ結果になる。
|
|
例3:入れ子の条件式を作成する
|
以下のような、入れ子の条件式を作成したいとする。
"現象型A = @A or (現象型B = @B and 現象型C = @C and 現象型D = @D)"
更に括弧内の条件はセッションキーB,C,Dのいずれかがnullではない場合に含めたいという条件を付けると、
この場合は以下のように記述になる。
;;---------------------------------------------------------
;; 記述例:入れ子の条件式を作成する
;;---------------------------------------------------------
(XXXを検索する
format_type search
(search
source XXX
session_value XXX検索結果
[filter
;;-------------------------------------------
;; Aに対する条件式
;;-------------------------------------------
eixst A
filter "現象型A = @A"
append true
,
;;-------------------------------------------
;; B,C,Dに対する入れ子の条件式
;;-------------------------------------------
operator or
condition "@B is not null or @C is not null or @D is not null"
[filter
;;-------------------------------------------
;; Bに対する入れ子内の条件式
;;-------------------------------------------
exist B
filter "現象型B = @B"
append true
,
;;-------------------------------------------
;; Cに対する入れ子内の条件式
;;-------------------------------------------
operator and
exist C
filter "現象型C = @C"
append true
,
;;-------------------------------------------
;; Dに対する入れ子内の条件式
;;-------------------------------------------
operator and
exist D
filter "現象型D = @D"
]
]
)
)
|
|
|
|
メモリ上でのソートにおけるNULL値の扱いについて
|
メモリ上でデータモデルをソートする場合、ソート項目に指定された現象型の値がNULLだった場合はデフォルトでは最小値の扱いとなります。
これは場合によってはDBでSQLによるソートを実行した場合と逆になることがあるため、都合が悪い場合は以下の2通りの方法で逆転させることができます。
なお、この設定は以下の機能によるソート時に反映されます。
- メモリ上のデータモデルリストに対するsearchプロセスでのsort,extra_sort
- DBに対するsearchプロセスでのextra_sort
- ディレクティブによるソート(&Sort,&SortByPhenomenonTypeNames)
VM起動パラメータで指定する
|
一番優先順位の高い指定です。
ClientおよびServerのJavaVMの起動パラメータで以下のように指定します。
-Dreverse_null_sort_order=true
ただし、それぞれのVM起動パラメータで指定するので忘れるとClient側とServer側で挙動が変わります。
そのため、後述のpexa_plugins.entryに記載するほうが確実です。
|
|
|
|
更新情報
|
- 最終更新者 : $Author: morishita $
- 最終更新日時 : $Date:: 2012-06-11 20:19:52 #$
- バージョン : $Revision: 6959 $
|
|
|