2001/11 Run
ZSQLMethodは超便利です。データベースの中にあるデータを簡単にWebに引っ張り出せるのはZopeのとても良いところ。
で、でっかいテーブルとかを表示する時には、所謂「ページング」という技を使って、1画面に20件とか表示して
何処かに「次の20件」とか「前の20件」とかやるわけです。
で、Zopeでは繰り返しを行うタグである、 dtml-in に、 size と start という属性を与えてやれば簡単にページングが出来るので、超便利。:
<dtml-in "SQL.Employee.getAllEmployeeSQL(orderby = 'name')" size=20 start=startpos>
<dtml-var name><br>
</dtml-in>
とかやれば、最初から20件だけ表示してくれると。
ちなみに変数であるところの startpos が定義されていなくてもエラーにはならんです。
テスト
その場合は、デフォルト値として 0 が使われるです。
次の20件とか前の20件とか表示するには、こんなコードを使うですよ。:
<dtml-in "SQL.Employee.getAllEmployeeSQL(orderby = 'name')" previous size=20 start=startpos>
<a href="/Employee/showAllEmployee?<dtml-var sequence-query>&startpos=<dtml-var previous-sequnece-srart-number>">
前の<dtml-var previous-sequnece-size>件
</a>
</dtml-in>
<dtml-in "SQL.Employee.getAllEmployeeSQL(orderby = 'name')" next size=20 start=startpos>
<a href="/Employee/showAllEmployee?<dtml-var sequence-query>&startpos=<dtml-var next-sequence-start-number>">
次の<dtml-var next-sequence-size>件
</a>
</dtml-in>
ここで、 sequnece-query ってのは、 /Employee/showAllEmployee を呼び出したURLに付いている引数のうち、 startpos を
除いた物が保存されている便利な変数。
あとデータの最初から表示している時には、「前のn件」は自動的に表示されない。
「次のn件」の部分も同様にデータの最後の部分を表示している時は表示されない。ううむすばらしい。
まぁ細かい部分は Zope に内蔵されている Help の中にある dtml-in の解説に譲るとして
ページングをやるときの定石は上のようになっているということで。
で、これでページングのナビゲーションと、表の表示っていう機能はちゃんと達成されているんだけれども
よく見ると同じ ZSQLMethod を3回も呼んでいます。もしやとお思いの方、正解です。
この実装方法を使うと
「本当に3回SQLクエリーが行われてしまう」
のです。超ダサダサです。パフォーマンス悪いに決まってます。
これをどう解決するか。それはZSQLMethodの戻り値を変数に一旦バインドしてしまえば全て解決!
コードは下のようになるでしょうか:
<dtml-comment> *** データベースよりデータを得る *** </dtml-comment>
<dtml-let result="SQL.Employee.getAllEmployeeSQL(orderby = 'name')">
<dtml-comment> *** ナビゲーション部分 *** </dtml-comment>
<dtml-in result previous size=20 start=startpos>
<a href="/Employee/showAllEmployee?<dtml-var sequence-query>&startpos=<dtml-var previous-sequnece-srart-number>">
前の<dtml-var previous-sequnece-size>件
</a>
</dtml-in>
<dtml-comment> *** データ表示 *** </dtml-comment>
<dtml-in result size=20 start=startpos>
<dtml-var name><br>
</dtml-in>
<dtml-comment> *** ナビゲーション部分 *** </dtml-comment>
<dtml-in result next size=20 start=startpos>
<a href="/Employee/showAllEmployee?<dtml-var sequence-query>&startpos=<dtml-var next-sequence-start-number>">
次の<dtml-var next-sequence-size>件
</a>
</dtml-in>
</dtml-let>
dtml-let を使うのがミソです。これでデータベースへのQueryは1回だけになります。
この方法とは別に、対象のSQL Methodのキャッシュの設定をして、複数回のQueryを行わせないようにする技もありますが、
それだと、リアルタイムに変化し続けているようなテーブルには適用が難しいので、上の変数バインドの方法をお勧めしますですよ。
コメント
<dtml-let QUERY_GOAL=URL>
<dtml-in Method size=20 start=query_start>
<dtml-if sequence-start>
<dtml-if previous-sequence>
<dtml-comment> *** ナビゲーション部分 *** </dtml-comment>
<a href="<dtml-var QUERY_GOAL><dtml-var sequence-query>query_start=<dtml-var previous-sequence-start-number>">
前の<dtml-var previous-sequence-size>件
</a>
</dtml-if previous-sequence>
<dtml-comment> *** データ表示開始部分 *** </dtml-comment>
</dtml-if sequence-start>
<dtml-comment> *** データ表示 *** </dtml-comment>
<dtml-var name>
<dtml-if sequence-end>
<dtml-comment> *** データ表示終了部分 *** </dtml-comment>
<dtml-if next-sequence>
<dtml-comment> *** ナビゲーション部分 *** </dtml-comment>
<a href="<dtml-var QUERY_GOAL><dtml-var sequence-query>query_start=<dtml-var next-sequence-start-number>">
次の<dtml-var next-sequence-size>件
</a>
</dtml-if next-sequence>
</dtml-if sequence-end>
<dtml-else>
</dtml-in>
</dtml-let>
| Last edited Sun, 10 Sep 2006 19:20:16 +0900 | Edit this page |