Как поместить записи из запроса в DAO?
-
06-07-2019 - |
Вопрос
Я написал шлюз для получения набора результатов из моей базы данных.Как мне сохранить каждую строку в отдельном дао, чтобы можно было дальше манипулировать каждой записью?Или я могу получить доступ к набору результатов напрямую, чтобы получить записи?
Это мой шлюз (кстати, стоит ли мне записать условную логику внутри 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 vs.Шлюз, DAO и шлюз и т. д.).Какова лучшая практика, что делают профессионалы?
Решение
Профессионалы используют только один шаблон для слоя доступа к базе данных. Использование DAO и Gateway - это неправильное название, так как я не совсем уверен, с чего оно началось, но, похоже, существует только в толпе ColdFusion. Шаблоны DAO и Gateway могут в значительной степени выполнять одну и ту же функцию, но я думаю, что DAO больше отвечает требованиям, когда речь идет о взаимодействии с базой данных.
DAO должны включать функциональность для методов CRUD, а также возвращать наборы записей. Поскольку CRUD и базовые наборы записей очень повторяются, я использую генератор кода для создания кода для этого взаимодействия, а затем настраиваю то, что мне нужно. Это хорошее место для условной логики для выбора нужных вам записей.
Как упоминал Аарон, возврат массива объектов для набора записей в вашей базе данных невозможен в ColdFusion из-за снижения производительности при создании объектов. Обычно я просто использую базовый запрос, возвращаемый из DAO, в своих представлениях. Однако если моделируемому объекту требуется некоторое поведение в представлении, я помещу запрос в объект, используя нечто похожее на то, что делает Питер Белл.
Другие советы
Несколько месяцев назад Питер Белл провел отличную презентацию о своем выпуске Iterating Business Object CFC, который позволяет вам брать несколько записей и выполнять итерацию по одной записи за раз, используя эту простую структуру: http://ibo.riaforge.org/.Пока CF не станет немного быстрее генерировать объекты, лучше всего будет перерабатывать один экземпляр объекта и повторно заполнять свойства.Возможно, это поможет вам загружать в DAO по одной записи за раз.
Условная логика может использоваться в шлюзе или в управляющем CFC.Обычно я бы включил простую логику, такую как логика, изложенная в вашем сообщении, непосредственно в CFC.
Небольшой совет: возможно, вы захотите сделать аргумент groups.distinct НЕ обязательным и выполнить простую проверку с помощью if (structKeyExists(arguments, "distinct") ) { do Something }.
С уважением,
-Аарон Гринли
В нашей компании мы долго и много думали об этом, пытаясь создать Adobe CF DAO через RDS и некоторые другие более старые (кто-нибудь помнит CFPowerTools?). Р>
В конце концов мы решили написать собственный генератор кода DAO, и я решил поделиться своими мыслями здесь. Причина, по которой мы решили, заключалась в том, что нам нужно было добавить подсказки блокировки в SQL, мы хотели сделать его более эффективным, безопасным и чистым. Р>
Мы решили создать предварительно заданный базовый объект DAO (называемый DAO.cfc
), который расширил все сгенерированные «таблицы» DAO. Все, что у него было, - это несколько служебных методов, но главное, что мы можем добавить туда любые другие функции, к которым нам нужны все наши сгенерированные DAO. Р>
Таким образом, мы автоматически генерируем код, выбирая таблицу из базы данных (используя API администрирования CF) и создаем DAO [TableName] .cfc
с обычными init, setter и getters, поэтому основные вещи 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") />
Этот вызов вернет значения 'customerName' и 'customerID' для всех клиентов со статусом 1, упорядоченных по дате их создания. Код также защищен от SQL-инъекций и проверен, поэтому создаются разумные исключения. Р>
Эта функция обеспечит 99% (мы надеемся!) запросов к нескольким записям, которые вы делаете для таблицы. Если вам нужен более сложный запрос, то CustomerGateway.cfc
поможет вам добавить функции. Р>
Наконец, мы разрешаем вам добавлять функции в CustomerGateway
CFC only , потому что если вы измените таблицу клиентов (скажем, добавьте столбец), вам нужно будет воссоздать таблицу, и это перезапишет Customers.cfc
и CustomersGatewayBase.cfc
. Тем не менее, ваш собственный код (если есть) безопасен в подклассе. Р>
В любом случае, это может быть немного не по теме, но я уверен, что кто-то может найти наш опыт полезным. Р>