سؤال

أنا بناء كائن إلى البحث أوامر في قاعدة البيانات الخاصة بي.هناك مجموعة من المعلمات المحتملة التي يمكن للمستخدم تعيين, ويمكن تعيين العديد كما تريد ثم لكل بحث.لقد خلق واضع طرق جمع جميع المعلمات اللازمة للبحث.

سؤالي هو هذا.ما يمكن أن يكون "أفضل الممارسات"

  1. تخزين المعلمات ، WHERE الشرط عندما doSearch الطريقة تسمى
  2. بناء WHERE شرط كما يتم تعيين معلمات

أود أن أفهم السبب وراء أي توصية.

لاحظ أن الكائن instatiated لكل بحث ، لذا لا داعي للقلق حول البحث الثاني مع معلمات مختلفة.

هل كانت مفيدة؟

المحلول

يجب فصل رمز النظام الخاص بك البحث من التعليمات البرمجية التي يبني 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 عند doSearch.أنا لا أعتقد أنه يجب أن يكون مسؤولية اضع للمعلمة إضافة إلى جملة WHERE السلسلة في مكان ما.

على قاعدة بيانات SQLServer هو أكثر كفاءة لتشمل جميع المعلمات في جملة where بدلا من بناء ذلك على الطاير.ثم لديك قاعدة بيانات مؤشر والذي يتضمن كافة الأعمدة إلى البحث عن.وهذا يضمن مؤشر يستخدم دائما عند تنفيذ البيان.

ممتلئا تماما يبدو التجريد هو الصحيح تماما.

البحث قد يكون أفضل أسلوب "أوامر" الكائن.تمرير المعلمات إلى وظيفة البحث و بناء الاستعلام يدويا كما روس اقترح.أي شيء غير محددة أوامر بدلا من البحث ومن ثم يمكن تعيين على أوامر طريقة الحرف الأول.

فمن الممكن أن كنت قد ترغب في بناء أوامر البحث كائن ولكن ينبغي أن يتم ذلك عن طريق أوامر كائن للحفاظ على الواجهة الأمامية رمز بسيط.

الخيار 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