문제

데이터베이스에서 주문을받을 수있는 객체를 구축하고 있습니다. 사용자가 설정할 수있는 가능한 매개 변수가 많이 있으며 각 검색에 대해 원하는만큼 설정할 수 있습니다. 검색에 필요한 모든 매개 변수를 수집하기 위해 Setter 메소드를 만들었습니다.

내 질문은 이것입니다. "모범 사례"는 무엇입니까

  1. 매개 변수를 저장하고 빌드 WHERE 할 때 절 doSearch 메소드가 호출됩니다
  2. 건물 WHERE 매개 변수로서의 조항이 설정되어 있습니다

추천의 이유를 이해하고 싶습니다.

객체는 각 검색마다 설치되어 있으므로 매개 변수가 다른 두 번째 검색에 대해 걱정할 필요가 없습니다.

도움이 되었습니까?

해결책

주문 검색 코드를 SQL을 빌드하는 코드에서 분리해야합니다. SQL은 파생물 (또는 전략 유도체) OrderSearch 수업. 이 분리를 한 후에는 실제로 중요하지 않습니다. 언제 SQL을 만듭니다.

이것을 좀 더 평범하게 만들기 위해. 이름이 지정된 수업이 주어졌습니다 OrderSearch 검색 기준에 대한 세터 메소드가 많으면 서브 클래스가 이름을 지정하고 싶습니다. OrderSearchSQLBuilder. 서브 클래스는 기본 클래스에 따라 다르며 기본 클래스는 서브 클래스와 무관합니다. 이건 매우 중요합니다. 이 독립성을 사용하면 SQL이 세터 메소드 또는 검색 방법에 내장되어 있는지 무시할 수 있습니다. 보다 의존성 반전 원리 (DIP).

이런 종류의 분리가 있으면 파생물을 다른 전략으로 대체 할 수 있습니다. 예를 들어, 애플리케이션을 SQL 데이터베이스에 연결하지 않고 애플리케이션을 테스트하려면 더미 인쇄 데이터베이스를 만들고 의도를 만들 수 있습니다. OrderSearch 그것은 그 더미 데이터베이스를 다루었습니다. 응용 프로그램의 나머지 부분은 행복하게 알지 못하며 테스트는 데이터베이스 연결의 공포, 기존 데이터 등과 독립적입니다.

다른 팁

방법에서 검색을 수행하는 동적 SQL의 매개 변수를 사용하십시오. 그렇게하면 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>

검색을 실행하는 데 필요한 위치 절을 구축하지 마십시오. 반복에서 매개 변수를 공급하는 사용자 인터페이스로 끝날 수 있으며 모든 것이 언제 있는지 알 수 없습니다. 또한 검색을 실행할 수 없으므로 WHERE 절에 대해 걱정하는 이유는 무엇입니까?

나는 그것이 큰 차이를 만든다고 생각하지 않지만, 당신이 검색 할 때 Where 조항을 구축하는 것이 더 나은 연습처럼 보인다고 생각합니다. 나는 매개 변수가 어딘가에 where 절에 추가하는 것이 세터의 책임이라고 생각하지 않습니다.

SQLSERVER 데이터베이스에서는 즉시 구축하는 대신 WHERE 절에 모든 매개 변수를 포함시키는 것이 더 효율적입니다. 그런 다음 검색 할 모든 열이 포함 된 데이터베이스 색인이 있습니다. 이를 통해 명령문을 실행할 때 인덱스가 항상 사용됩니다.

당신의 추상화가 옳은 것처럼 들리지 않습니다.

"주문"객체의 방법으로 검색이 더 나을 수 있습니다. 매개 변수를 검색 기능으로 전달하고 수동으로 쿼리를 빌드하십시오. 러스가 제안했다. 검색이 아닌 주문에 특정한 내용은 주문 메소드에서 설정할 수 있습니다.

주문 검색 개체를 작성하려는 경우가 가능하지만 프론트 엔드 코드를 간단하게 유지하려면 Orders Object를 통해 수행해야합니다.

옵션 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>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top