3

次の設計で助けが必要です。データベースから実行する Web メソッドを公開しSQL selectます。問題は、レコードの数が膨大になる可能性があり、1 回の呼び出しですべてのレコードを返したくないことです。
したがって、これらのオプションを考えることができます (結果をページで返すため):
1) クライアントが毎回要求するようrecordStartに、パラメーターを含むメソッドを提供します。 2)サイズの結果セットを受け入れるようにメソッドを変更し、各リクエストが新しいものではなく、次のものを返すことをどういうわけか理解しますrecordEnd
XX記録。これを理解するために、ある種のトークンをクライアントごとに関連付けることができますが、問題は、着信要求を最初の要求または前の要求の継続として処理するために、このトークンを保持してから破棄する必要があるかどうかわからないことです。 1。

では、どの設計を採用する必要があり、言及した関連する問題をどのように解決すればよいでしょうか?
これらの問題に対処するためのより良い方法はありますか?

4

3 に答える 3

2

私の視点から:

  • 各リクエストは、基本的にオフセットとページ サイズを保持するリクエスト オブジェクトにカプセル化できます。
  • 各応答は、基本的に結果リストと合計を持つ応答オブジェクトにカプセル化できます。代わりに、応答の構築に使用される要求オブジェクトを保持することもできます。

データベースで選択を実行するためのインターフェイスは次のようになります。

public PageResponse getPage(PageRequest pageRequest);

このアプローチにより、ページング メソッドの拡張が容易になります。数か月後に、そのメソッドに並べ替えを実装する必要があると想像してください。各呼び出しを変更する必要があります。このアプローチでは、PageRequestオブジェクトを変更してデフォルトの並べ替えを指定します。何も壊れることはなく、本当に必要な呼び出しで並べ替えをカスタマイズできます。

このメソッド内で、2 つの異なるデータベースの選択が必要になります。

  • 1 つは選択リスト (応答によって保持され、プロパティ resultList を介してアクセスされるリスト) を取得するためのものです。これは、各データベースに固有の機能を使用して結果セットを制限することで実行できます ( topsybase の場合limit、mysql および PG の場合、rownumOracle では、これはデータベースごとに異なります)。
  • ビッグデータセットの場合にデータのページングを実行するために、ページングなしで選択されたレコードの合計を取得する別のもの。

あなたの問題の良い参考文献はSpring Dataです。それらには多かれ少なかれ必要なものであるPagePageRequestがあります。おそらく、彼らの API を使用してソリューションを実装できます。


実際には、リクエスト オブジェクトは次のようになります。

public class PageRequest {

    private int offset;
    private int pageSize;

    // getters and setters and convenience constructors with the given fields

}

public class PageResponse {

    private List<?> resultList;
    private int total;

    // getters and setters and convenience constructors with the given fields

}

もちろん、ジェネリックを少し使って、既に要求した型を保持する応答を持たせることもできます。これにより、次のような応答オブジェクトの使用が容易になります。

public <T> PageResponse<T> getPage(PageRequest<T> pageRequest);

次のような Request と Response のオブジェクトを持つ:

public class PageRequest<T> {

    private int offset;
    private int pageSize;

    // getters and setters and convenience constructors with the given fields

}

public class PageResponse<T> {

    private List<T> resultList;
    private int total;

    // getters and setters and convenience constructors with the given fields

}
于 2012-08-01T06:45:03.257 に答える
0

より良いアプローチで、最も広く使用されているのは1)です。

この場合、SQL プロシージャとクライアント コードの間に制約はありません (OOP のインターフェイスに基づくプログラミングと同様)。

また、トークンが存在するハッシュを確認するよりも単純でエラーが発生しにくいため、現在の位置を取得できます。また、このハッシュをどこかに覚えておく必要があります (速度のためのメモリまたは耐久性のためのディスク)。

ご覧のとおり、この方法は複雑であり、深く考えると、最初の方法よりも多くの決定を下す必要があります。

また、最初の方法では、OOP カプセル化のように動作するため、アプリケーションをより自由に設計できます。将来的には、現在の位置を記憶する別のコードを使用することもできます。クライアントはこのコードを呼び出し、このコードはデータベースを呼び出して結果をクライアントに渡します。

要するに、一緒に行き1)ます。

于 2012-08-01T06:44:17.810 に答える
0

結果の総数を返したい場合は、両方のオプションを組み合わせます。

  • 新しいクエリ (識別子なし) :
    • 最初に、order by 句を使用せずに、完全な結果セットの行数を計算します (select count(*) from ...)。
    • 結果セットが本当に大きすぎる場合、ここでエラーを返すことができます [オプション]
    • ページ データを取得します (順序付けは必須であり、あなたまたは API のユーザーによって定義されます)
    • 識別子を生成し、結果カウント [およびオプションでクエリ] と共に永続化します。
    • ページ データ、合計結果数、およびクエリの識別子を返します
  • 次のクエリ (指定された識別子) :
    • 永続化された結果数を取得する
    • ページ データを取得します (順序付けは必須であり、あなたまたは API のユーザーによって定義されます)
    • ページ データ、合計結果数、およびクエリの識別子を返します

最善の方法は、識別子とともにクエリを (ページング パーツなしで) 永続化することです。この方法では、次の呼び出しで再度クエリを作成する必要さえありません。

于 2012-08-01T09:09:32.327 に答える