2009-03-06 6 views
3

データベース内の注文を検索するオブジェクトを作成しています。ユーザーが設定できる一連の可能なパラメータがあり、検索ごとに必要な数だけ設定することができます。私は、検索に必要なすべてのパラメータを収集するためのセッターメソッドを作成しました。個々のパラメータまたはビルド場所句

私の質問はこれです。 「ベストプラクティス」

  1. doSearch方法は、私がしたいパラメータが

に設定されているよう

  • WHERE句の構築と呼ばれるWHERE句をパラメータを格納し、建物の何だろう推薦の背後にある理由を理解する。

    オブジェクトは検索ごとに生成されるので、別のパラメータで2回目の検索をする必要はありません。

  • 答えて

    13

    あなたがSQLを構築したコードからのご注文の検索のためのコードを分離する必要があります。 SQLは、OrderSearchクラスの派生物(またはStrategy派生)で構築する必要があります。このように分割した後は、 SQLをビルドするときには、実際にはは問題になりません。

    これをもう少し簡単にするにはOrderSearchという名前のクラスには、検索基準のセッターメソッドがたくさんあるので、OrderSearchSQLBuilderという名前のサブクラスが必要です。サブクラスはベースクラスに依存し、ベースクラスはサブクラスとは独立していることに注意してください。これはとても重要です。この独立性により、SQLがsetterメソッドに組み込まれているのか、検索メソッドに組み込まれているのかを無視できます。 The Dependency Inversion Principle (DIP)を参照してください。

    この種の分離が完了したら、その派生物を他の戦略に置き換えることができます。たとえば、SQLデータベースに接続せずにアプリケーションをテストする場合は、ダミー・インラム・データベースを作成し、そのダミー・データベースを処理するOrderSearchの派生物を作成できます。アプリケーションの残りの部分は幸せに認識されないでしょうし、テストはデータベース接続や既存のデータなどの恐怖から独立しています。

    1

    検索を実行する前にwhere句を作成しないでください。あなたは、反復でパラメータを供給するユーザーインターフェイスで終わるかもしれません。そして、あなたはすべてをいつ持っているのか分かりません。また、あなたは検索を実行することはできませんので、なぜwhere句を心配してください。

    0

    SQLServerデータベースでは、すべてのパラメータを即座に構築するのではなく、where句に含める方が効率的です。次に、検索するすべての列を含むデータベース索引を作成します。これにより、ステートメントの実行時に常に索引が使用されます。

    3

    この方法では、検索を行う動的SQLのパラメータを使用します。こうすることで、where節はSQLの実行の直前に構築されます。検索パラメータを引数として渡すだけです。

    このような何か...

    <cffunction name="getByAttributesQuery" access="public" output="false" returntype="query"> 
        <cfargument name="id" type="numeric" required="false" /> 
        <cfargument name="userName" type="string" required="false" /> 
        <cfargument name="firstName" type="string" required="false" /> 
        <cfargument name="lastName" type="string" required="false" /> 
        <cfargument name="createdAt" type="date" required="false" /> 
        <cfargument name="updatedAt" type="date" required="false" /> 
        <cfargument name="orderby" type="string" required="false" /> 
    
        <cfset var qList = "" />   
        <cfquery name="qList" datasource="#variables.dsn#"> 
         SELECT 
          id, 
          userName, 
          firstName, 
          lastName, 
          createdAt, 
          updatedAt 
         FROM users 
         WHERE  0=0 
        <cfif structKeyExists(arguments,"id") and len(arguments.id)> 
         AND id = <cfqueryparam value="#arguments.id#" CFSQLType="cf_sql_integer" /> 
        </cfif> 
        <cfif structKeyExists(arguments,"userName") and len(arguments.userName)> 
         AND userName = <cfqueryparam value="#arguments.userName#" CFSQLType="cf_sql_varchar" /> 
        </cfif> 
        <cfif structKeyExists(arguments,"firstName") and len(arguments.firstName)> 
         AND firstName = <cfqueryparam value="#arguments.firstName#" CFSQLType="cf_sql_varchar" /> 
        </cfif> 
        <cfif structKeyExists(arguments,"lastName") and len(arguments.lastName)> 
         AND lastName = <cfqueryparam value="#arguments.lastName#" CFSQLType="cf_sql_varchar" /> 
        </cfif> 
        <cfif structKeyExists(arguments,"createdAt") and len(arguments.createdAt)> 
         AND createdAt = <cfqueryparam value="#arguments.createdAt#" CFSQLType="cf_sql_timestamp" /> 
        </cfif> 
        <cfif structKeyExists(arguments,"updatedAt") and len(arguments.updatedAt)> 
         AND updatedAt = <cfqueryparam value="#arguments.updatedAt#" CFSQLType="cf_sql_timestamp" /> 
        </cfif> 
        <cfif structKeyExists(arguments, "orderby") and len(arguments.orderBy)> 
         ORDER BY #arguments.orderby# 
        </cfif> 
        </cfquery> 
    
        <cfreturn qList /> 
    </cffunction> 
    
    +0

    len(...)チェックを削除してください。 –

    +0

    実際の検索を行う前に検索のパラメータを設定する必要があるので、すべてのパラメータをdoSearchメソッドに渡すだけです。私はまた、doSearchメソッドの外にsetterメソッドを用意することで、より柔軟なorderSearchオブジェクトを得ることができると考えています。 – Yisroel

    +0

    >>実際の検索を行う前に検索のパラメータを設定する必要があるので、doSearchメソッド<< ? doSearch(ArgumentCollection = Variables.SearchData)のようなものはありませんか? –

    1

    は、私はそれが大きな違いを作るとは思わないが、私はそれがあなたdoSearch WHERE句を構築するためのより良い練習だと思います。 WHERE句の文字列にどこかに追加するパラメータを設定する責任は、私が考えるべきではないと思います。

    0

    あなたの抽象のようなものはまったく鳴りません。

    "orders"オブジェクトのメソッドとしては、検索が優れている可能性があります。パラメータを検索関数に渡して、クエリを手動でruss suggestedとして構築します。検索ではなく注文に固有のものは、orders initメソッドで設定できます。

    注文検索オブジェクトを作成することができますが、これは注文オブジェクトを介して行う必要があり、フロントエンドコードを簡単に保つことができます。

    +0

    Ordersオブジェクトはどのような機能を提供していますか? – Yisroel

    0

    オプション1が最適です。オプション2は危険です。パラメータが更新されたらどうなりますか? WHERE節でどのように置き換えるのですか?

    私はこのような何かをするだろう:

    <cffunction name="doSearch" access="public" output="false" returntype="query">   
        <cfset var qList = "" /> 
        <cfquery name="qList" datasource="#variables.dsn#"> 
         SELECT 
          ... 
         FROM 
          ... 
         WHERE 0=0 
         <cfif len(getID())> 
          AND id = <cfqueryparam value="#getID()#" CFSQLType="cf_sql_integer" /> 
         </cfif>  
         <cfif len(getUserName())> 
          AND userName = <cfqueryparam value="#getUserName()#" CFSQLType="cf_sql_varchar" /> 
         </cfif> 
        </cfquery> 
        <cfreturn qList /> 
    </cffunction> 
    
    +0

    パラメータの更新について心配する必要はありません。新しいorderSearchが検索ごとに開始されるためです。 本質的に、私はあなたが上記のように正確にやっています。私はちょうど間違っていることを明確に理解したかったのです。 btw、getUserName()を呼び出した後、arguments.userName – Yisroel

    関連する問題