Question

J'ai écrit une passerelle pour obtenir un résultat de ma base de données. Comment puis-je stocker chaque ligne dans un dao séparé afin que je puisse manipuler chaque enregistrement plus loin? Ou puis-je accéder directement au jeu de résultats pour obtenir les enregistrements?

Ceci est ma passerelle (au fait, devrais-je écrire la logique conditionnelle de la cfquery dans un cfc séparé qui étend celui-ci?)

<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>

J'ai déjà lu beaucoup d'articles et il semble qu'il existe différentes opinions à ce sujet (DAO ou Gateway, DAO et Gateway, etc.). Quelle est la meilleure pratique, que font les pros?

Était-ce utile?

La solution

Les pros utilisent un seul motif pour la couche d'accès à la base de données. L'utilisation à la fois d'un DAO et d'une passerelle est un terme impropre dont je ne suis pas sûr du point de départ, mais qui n'existe que dans la foule ColdFusion. Les modèles DAO et Gateway peuvent à peu près remplir la même fonction, mais je pense que le modèle DAO convient davantage lorsqu'il parle d'interaction de base de données.

Les DAO doivent inclure des fonctionnalités pour les méthodes CRUD ainsi que le renvoi d’ensembles d’enregistrements. Étant donné que CRUD et les ensembles d’enregistrements de base sont très répétitifs, j’utilise un générateur de code pour créer le code de cette interaction, puis personnaliser ce dont j'ai besoin. C’est un bon endroit pour la logique conditionnelle pour la sélection des enregistrements dont vous avez besoin.

Comme Aaron l’a mentionné, le retour d’un tableau d’objets pour un ensemble d’enregistrements dans votre base de données n’est pas réalisable dans ColdFusion en raison de la surcharge de performances liée à la création d’objets. En général, je n'utilise que la requête de base renvoyée par le DAO dans mes vues. Cependant, si la chose que je modélise nécessite un comportement dans une vue, je placerai la requête dans un objet en utilisant quelque chose de similaire à ce que fait Peter Bell.

Autres conseils

Peter Bell a présenté, il y a quelques mois, une superbe présentation de sa publication de l’objet métier itérateur CFC, qui vous permet de créer plusieurs enregistrements et de les parcourir sur un enregistrement à la fois, à l’aide de ce cadre simple: http://ibo.riaforge.org/ . Jusqu'à ce que CF génère un peu plus rapidement les objets, recycler une seule instance d'un objet et repeupler les propriétés est probablement votre meilleur atout. Cela peut peut-être vous aider à charger un enregistrement à la fois dans votre DAO.

La logique conditionnelle peut aller dans la passerelle ou dans un gestionnaire CFC. En règle générale, j'inclue une logique simple comme celle décrite dans votre message directement dans le CFC.

Un conseil, vous souhaiterez peut-être définir le paramètre arguments.distinct non requis et effectuer une vérification simple avec if (structKeyExists (arguments, "distinct")) {faire quelque chose}.

Cordialement,

-Aaron Greenlee

Au sein de notre société, nous avons longuement réfléchi à ce sujet pendant quelques mois, en essayant le créateur DAO d’Adobe CF via RDS et quelques autres plus anciens (tout le monde se souvient de CFPowerTools?).

Nous avons finalement décidé d’écrire notre propre générateur de code DAO et j’ai pensé partager ici nos réflexions. La raison pour laquelle nous avons décidé, c'est parce que nous devions ajouter des astuces de verrouillage à SQL, nous voulions le rendre plus efficace, plus sécurisé et plus propre.

La configuration que nous avons choisie consistait à créer un objet DAO de base prédéfini (appelé DAO.cfc ) qui générait tous des DAO "de table" étendus. Il ne contenait que quelques méthodes d’utilité, mais l’essentiel est que nous puissions y ajouter toutes les fonctions auxquelles nous avons besoin que tous nos DAO générés aient accès.

Nous générons donc automatiquement du code en sélectionnant une table dans la base de données (à l'aide de l'API d'administration CF) et en créant le DAO [TableName] .cfc avec les init init, setters et getters habituels. trucs de base CRUD.

En plus de cela, nous générons également un [NomTable] GatewayBase.cfc et un [NomTable] Gateway.cfc . [TableName] Gateway.cfc étend [TableName] GatewayBase.cfc .

Ainsi, pour un exemple de DAO exécuté sur une table appelée "Clients", les fichiers créés sont les suivants:

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

L'idée est donc que la passerelle offre un moyen de traiter de nombreux enregistrements "Client" - la DAO est utilisée pour traiter un et un seul. Toutes les méthodes de la passerelle renverront généralement un objet de requête CF. CF est trop inefficace pour créer des tableaux massifs d'objets DAO et, dans notre esprit, l'objet de requête dans CF est très flexible. Nous sommes donc ravis de l'utiliser.

Lors du codage, la sous-classe CustomerGateway.cfc est la seule instanciée et utilisée. Cependant, la classe de base qu’elle étend contient des fonctions génériques très utiles, telles que getFieldListByProperty () qui, en fonction des paramètres passés, renverront certains champs (par exemple, les colonnes de la table) par une certaine propriété (par exemple, une valeur de colonne), par exemple:

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

Cet appel renverra les valeurs "customerName" et "customerID" pour tous les clients ayant le statut 1, classés par date de création. Le code est également renforcé contre l’injection SQL et validé afin que des exceptions sensibles soient générées.

Cette fonction fournira 99% (nous l’espérons!) des requêtes multi-enregistrements effectuées sur une table. Si vous avez besoin d'une requête plus sophistiquée, le CustomerGateway.cfc vous permet d'ajouter des fonctions.

Enfin, nous vous permettons d'ajouter des fonctions à CustomerGateway CFC uniquement , car si vous modifiez la table des clients (par exemple, ajoutez une colonne), vous devrez la recréer. et cela écrasera le Customers.cfc et le CustomersGatewayBase.cfc . Cependant, votre code personnalisé (le cas échéant) est sécurisé dans la sous-classe.

Quoi qu’il en soit, il s’agit peut-être d’un sujet légèrement en dehors du sujet, mais j’ai bien pensé que quelqu'un pourrait trouver notre expérience utile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top