1

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

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

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

我即将着手创建一个 CFC,它包含每个单独的<cfstoredproc><cfquery>在其自己的方法/函数中。例如:

<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 主页面上,我将调用返回数据所需的组件和方法。这是实现数据库查询管理的好方法吗?

4

3 回答 3

4

它与数据库相关的事实并不像您有代码重复的事实那样相关。您在努力使代码更可重用方面走在正确的轨道上。

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

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

两种方法都有效。而且,当你比较两件事时,几乎总是这样,每一件事都比另一件事更有优势。

于 2013-11-17T14:57:10.293 回答
1

考虑以下两个数据库表

用户

用户 ID PrimaryKey firstname lastname

安全

SecurityID PrimaryKey UserID ForeignKey 权限

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

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

  1. <cfquery>标签内部
  2. 存储过程内部
  3. 其他

问题是所有的 CRUD 操作都以它们自己的方式归为一类。考虑制作一个用户对象 ( 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,你用它做什么?它可以以各种不同的方式附加到您的应用程序的其余部分

  • 应用程序.用户 = 新用户();
  • session.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您可能只想设置一次,然后让所有功能都使用同一个,而不是总是说明您正在与之交互。

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

应用程序.用户

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

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

request.UserUser每个请求将存在 一个对象。它只会针对特定的请求存在,然后被丢弃。这表明User在这个请求上查看特定是有意义的,但下一个可能会完全不同,甚至可能与用户无关。

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

归根结底,您需要决定如何捆绑您的数据库交互,以及将这些捆绑的操作保持在一起多长时间

于 2013-11-17T19:45:34.170 回答
1

每张桌子我都会有一个模型。

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

让我们说用户表

用户.cfc

将拥有所有返回查询的方法

getUsers - 返回所有用户

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

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

我得到这样的结果

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

或者我使用脚本

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

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

最后一件事要考虑,如果数据没有改变,缓存查询。

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

于 2013-11-18T03:26:16.870 回答