管理整个网站使用的数据库查询

时间:2013-11-17 14:48:17

标签: coldfusion coldfusion-10 cfquery cfstoredproc

随着我的应用程序的增长,我注意到我正在重复使用多个网页上的大量数据库查询。

目前,我已经使用.CFM文件完成了该文件,该文件包含许多<cfstoredproc>个标记,这些标记包含在需要数据库数据的每个页面上。我所做的就是将这些存储过程执行包装在<cfif>标记中,该标记测试调用页面的名称,然后执行相应的<cfstoredproc>代码块。

我不是任何专家,但这对我来说并不合适。我只是不知道如何正确管理我的所有数据库查询,以便可以在整个网站的任何CFM页面上共享它们。例如,一个页面可能需要“GetUsers”存储过程,而另一个页面可能需要“GetOrders”。

我即将开始创建一个CFC,它在自己的方法/函数中保存每个单独的<cfstoredproc><cfquery>。 E.g:

<cfcomponent name="DBQueries" hint="Everything for DB retrieval">
 <cffunction name="GetUsers" returntype="query">
   <cfstoredproc procedure="GetUsers">
   <cfprocresult name="rsUsers">
   </cfstoredproc>
   <cfreturn rsUsers>
 </cffunction>
.....
 <cffunction name="DBQuery100">
   <cfstoredproc procedure="GetSomething" returntype="query">
   <cfprocresult name="rsSomething">
   </cfstoredproc>
   <cfreturn rsSomething>
 </cffunction>
</cfcomponent>

然后在主.CFM页面上,我将调用返回数据所需的组件和方法。这是实现数据库查询管理的好方法吗?

3 个答案:

答案 0 :(得分:4)

它与数据库相关的事实与您重复代码的事实并不相关。您正努力使代码更易于重复使用。

如果您将查询放入cfc,您可以考虑更进一步。不要一直调用它,而是使用Application.cfc的onApplicationStart方法创建一个可供所有页面上的所有用户使用的应用程序变量。

另一种方法是将所有这些数据库标记放入.cfm文件中,并将cfinclude放在Application.cfc的onRequestStart方法中。

两种方法都有效。而且,当你比较两件事时几乎总是如此,每件事都有优势。

答案 1 :(得分:1)

考虑以下两个数据库表

用户

UserID PrimaryKey 名字 名字

安全

SecurityID PrimaryKey UserID ForeignKey 许可

所有数据库表都有创建,读取,更新,删除操作(CRUD)

CRUD操作可以存在于多个地方

  1. <cfquery>代码
  2. 内部
  3. 存储过程内部
  4. 其他
  5. 事情就是所有CRUD操作都以自己的方式组合在一起。考虑制作一个User对象(user.cfc)。

    <cfcomponent>
       <cffunction name="create"></cffunction>
       <cffunction name="read"></cffunction>
       <cffunction name="update"></cffunction>
       <cffunction name="delete"></cffunction>
     </cfcomponent> 
    

    安全性是用户管理的一部分,对象是否与db表一对一匹配?在像ORM这样的环境中,答案是肯定的,而在其他环境中则不是。

    如果您认为安全性是用户管理的一部分,那么您的user.cfc可能会是这样的

    <cfcomponent>
       <cffunction name="create"></cffunction>
       <cffunction name="read" hint="Read will also read security info"></cffunction>
       <cffunction name="update" hint="Perhaps this can update security too"></cffunction>
       <cffunction name="delete" hint="Delete will also delete security info"></cffunction>
    
       <cffunction name="create_security"></cffunction>
       <cffunction name="read_secrity" hint="This may not even be needed"></cffunction>
       <cffunction name="update_security"></cffunction>       
       <cffunction name="delete_security" hint="This may not even be needed"></cffunction>
    </cfcomponent> 
    

    在一天结束时,您可能会发现您需要的对象(*.cfc)远远少于表格。

    好的,现在你有user.cfc你用它做什么?它可以通过各种不同的方式附加到您的应用程序的其余部分

    • application.User = new user();
    • session.User = new user();
    • request.User = new user();

    这些中的每一个都来自下一个。在我们走适当的道路之前,我们必须考虑会员数据,以及我们需要多长时间。

    <cfcomponent>
       <cfset this.userid = ""><!--- This always points to the user I want to interact with --->
    
       <cffunction name="create"></cffunction>
       <cffunction name="read"></cffunction>
       <cffunction name="update"></cffunction>
       <cffunction name="delete"></cffunction>
     </cfcomponent> 
    

    您的CRUD操作可能会针对其所有操作与相同的UserID进行交互。您可能会发现更新记录后,您经常会阅读它。您可能只想设置一次,并且让所有函数都使用相同的函数,而不是总是说明您正在与哪个UserID进行交互。

    好的,现在让我们回到你将使用它们的地方

    <强> application.User

    整个系统中只存在一个User对象。当请求进入网站时,它将被创建。将为每个请求共享此对象。如果您在此处附加user对象,则表示所有请求都将查看同一用户。

    <强> session.User 对于外部世界中的给定最终用户,将存在一个User对象。它将与所有其他最终用户分开。这表明每个最终用户都会查看自己的user并且即使他们点击网站时,他们仍然会看到相同的user

    <强> request.User 每个请求将存在一个User对象。它仅存在于特定请求中,然后被丢弃。这表明,查看特定User对此请求有意义,但下一个可能会有很大不同,甚至可能与用户无关。

    ~~~~~~~~~~~~~~~

    在一天结束时,您需要决定如何捆绑数据库互动,以及将这些捆绑行动保持在一起的时间

答案 2 :(得分:1)

我会为每张桌子准备一个模型。

在那里你有任何对该表做任何事情的查询

让我们说用户表

  

Users.cfc

会有所有返回查询的方法

  

getUsers - 返回alll用户

     

getUserById - 也可能是第一个函数的参数。

然后,当您需要确定订单中的某些内容正在更新时,只有一个地方可以查看。

我得到的结果是这样的

<cfset users = new model.Users().getUsers() />

或者我使用脚本

users = new model.Users().getUsers();

如果你真的很勇敢,也可以尝试用脚本执行所有查询。

最后要考虑的是,如果数据没有变化,请缓存查询。

像OrderType或类似的东西,你将获得很多性能优势,而不是一遍又一遍地重复查询。