2009-06-22 102 views
0

我写了一个网关从我的数据库中获取结果集。我如何将每一行存储在单独的道具中,以便我可以进一步操纵每条记录?或者,我可以直接访问结果集来获取记录吗?如何将查询中的记录放入DAO中?

这是我的网关(顺便说一句,我应该写CFQUERY内的条件逻辑到扩展这一个单独的CFC?)

<cfcomponent name="MaterialDao" hint="data access object" output="false"> 
<cffunction name="init" hint="constructor" access="public" output="false" returntype="MaterialDao"> 
    <cfargument name="dsn" type="String" required="true" hint="datasource" /> 
    <cfset variables.instance.dsn = arguments.dsn /> 
    <cfreturn this /> 
</cffunction> 

<cffunction name="readMaterial" hint="read" access="public" output="false" returntype="Query"> 
    <cfargument name="district" type="String" /> 
    <cfset var qReadMaterial = "" /> 
    <cfquery name="qReadMaterial" datasource="#variables.instance.dsn#"> 
    <cfif StructKeyExists(arguments,"district")> 
    SELECT A.NR, A.BEZ, D.BES, D.STA 
    <cfelse> 
    SELECT A.NR, A.BEZ 
    </cfif> 
    FROM DEK AS D INNER JOIN ART AS A 
    ON D.NR = A.NR 
    WHERE 0=0 
    <cfif StructKeyExists(arguments,"district")> 
    AND D.BEZ = #arguments.district# 
    </cfif> 
    ORDER BY A.BEZ 
</cfquery> 
<cfreturn qReadMaterial /> 
</cffunction> 
</cfcomponent> 

我已经读了很多文章,似乎有对此事有不同的看法(DAO与Gateway,DAO &网关等)。最佳做法是什么?专业人员做什么?

+1

我注意到你在你的cfif语句中使用了#号。没有必要使用#符号,除非使用变量作为某些输出的一部分,例如查询,视图或标记参数,就像您使用datasource =“#variables.instance.dsn#”所做的那样它位于引号之间。只是一个小技巧,可以为您节省一些键入击键。 :) – Jayson 2009-06-22 13:49:58

+0

我整合了Aaron的提示,并将我的网关更改为dao以便更加符合专业人员的要求:) – mrt181 2009-06-22 14:58:16

+0

您错过了StructKeyExist检查中的闭合零件。 – 2009-06-22 22:53:25

回答

3

优点仅使用一个图案数据库访问层。同时使用DAO和Gateway是个误区,我不确定它是从哪里开始的,但似乎只存在于ColdFusion人群中。 DAO和网关模式几乎可以提供相同的功能,但我认为DAO在讨论数据库交互时更适合这个账单。

DAO应该包含CRUD方法和返回记录集的功能。由于CRUD和基本记录集是高度重复的,因此我使用代码生成器为此交互创建代码,然后自定义需要的内容。这是用于选择所需记录的条件逻辑的好地方。

正如Aaron提到的,由于创建对象的性能开销,在数据库中返回一组记录的对象数组在ColdFusion中不可行。我通常只使用我的视图中从DAO返回的基本查询。但是,如果我正在建模的东西需要某个视图中的某些行为,那么我会使用类似于Peter Bell所做的一些东西将查询放入对象中。

2

Peter Bell在几个月前发表了一个很棒的演讲,讲述了他发布的迭代业务对象CFC,该演示允许您使用以下简单框架同时记录多个记录并一次迭代一条记录:http://ibo.riaforge.org/。直到CF在生成对象时稍微快一点,回收对象的单个实例并重新填充属性可能是您最好的选择。也许这可以帮助你一次加载一条记录到你的DAO中。

条件逻辑可以进入网关或Manager CFC中。通常情况下,我会在CFC中直接包含简单的逻辑,就像您在帖子中概述的逻辑一样。

有一点建议,你可能希望使arguments.distinct不是必需的,并用if(structKeyExists(arguments,“distinct”)){do something}做一个简单的检查。

问候,

-Aaron格林利

1

在我们公司,我们想了很长时间并且努力了几个月,尝试通过RDS和其他一些较旧的产品(任何人都记得CFPowerTools?)Adobe CF DAO创建者。

我们最终决定写我们自己的DAO代码生成器,我想我会在这里分享我们的想法。我们决定的原因是因为我们需要增加SQL锁定提示,所以我们想让它更高效,更安全,更清洁。

我们决定的设置是创建一个预定义的基本DAO对象(称为DAO.cfc),这些对象都生成了“表”DAO对象。它只有一些实用方法,但关键是我们可以在其中添加其他任何需要我们生成的DAO才能访问的功能。

因此,我们通过从数据库中选择一个表(使用CF管理API)自动生成代码,并使用通常的init,setter和getter创建DAO,所以基本的CRUD东西。

除此之外,我们还生成[TableName]GatewayBase.cfc[TableName]Gateway.cfc[TableName]Gateway.cfc延伸[TableName]GatewayBase.cfc

因此,对于一个表上的样品DAO运行所谓的“客户”,创建的文件有:

Customers.cfc /* extends DAO.cfc [not created, already exists] */ 
CustomersGateway.cfc 
CustomersGatewayBase.cfc /* extends CustomersGateway */ 

所以,这个想法是,网关提供了一种方法来处理许多“客户”记录 - 在处理唯一的一个时使用DAO。网关中的所有方法通常都会返回一个CF查询对象。 CF的效率太低,无法创建海量的DAO对象,而我们脑海中CF中的查询对象非常灵活,所以我们很乐意使用它。

编码时,子类CustomerGateway.cfc是唯一实例化和使用的。然而,它扩展的基类有一些非常有用的通用函数,如getFieldListByProperty(),它们基于传递的参数将返回特定属性(即列值)的某些字段(例如列值),例如:

myGateway.getFieldListByProperty(property="status", value="1", fieldList="customerName,customerID", orderBy="createdOn") /> 

这调用将返回“客户名称”和“的customerID”价值观为所有客户提供的1状态,通过他们创建的日期排序。该代码也针对SQL注入进行了强化并进行了验证,因此引发了明显的异常。

此功能将提供99%(我们希望!)查询您在桌面上执行的多记录。如果您需要更复杂的查询,那么CustomerGateway.cfc是您需要添加功能的地方。

最后,我们允许你添加功能CustomerGateway CFC 只有,因为如果你改变了客户表(比如添加一列),您将需要重新创建表,塔将覆盖Customers.cfcCustomersGatewayBase.cfc。但是,您的自定义代码(如果有的话)在子类中是安全的。

无论如何,这可能有点偏离主题,但肯定我认为有人可能会发现我们的经验有用。

相关问题