Управление запросами к базе данных, которые используются на всем веб-сайте

StackOverflow https://stackoverflow.com//questions/20032044

Вопрос

По мере роста моего приложения я заметил, что повторно использую множество запросов к базе данных на нескольких веб-страницах.

На данный момент я сделал это, используя файл .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 я вызываю компонент и метод, необходимые для возврата данных.Это хороший способ добиться управления запросами к БД?

Это было полезно?

Решение

Рассмотрим следующие две таблицы БД

Пользователь

Userid primarykey firstname lastname

Безопасность

SecurityId PrimaryKey UserId Иид иностранка

Все таблицы базы данных имеют операции создания, чтения, обновления и удаления (CRUD).

CRUD-операции могут существовать в нескольких местах

  1. Внутри <cfquery> теги
  2. Внутри хранимых процедур
  3. Другие

Дело в том, что все операции CRUD по-своему связаны друг с другом.Рассмотрите возможность создания объекта User (user.cfc).

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

Безопасность является частью управления пользователями, поэтому соответствует ли объект таблице БД?В некоторых средах, таких как 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> 

В конце концов вы можете обнаружить, что вам нужно гораздо меньше объектов (*.cfcs), чем таблицы.

ОК, теперь у тебя есть ты user.cfc что ты делаешь с этим?Его можно прикрепить к остальной части вашего приложения различными способами.

  • application.User = новый пользователь();
  • session.User = новый пользователь();
  • request.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 здесь объект, который предполагает, что все запросы будут относиться к одному и тому же пользователю.

сеанс.ПользовательОдин User объект будет существовать для данного конечного пользователя во внешнем мире.Он будет отделен от всех других конечных пользователей.Это говорит о том, что каждый конечный пользователь будет смотреть на свои собственные user И даже переходя по сайту, они все равно будут смотреть на одно и то же. user

запрос.ПользовательОдин User объект будет существовать для каждого запроса.Он будет существовать только для определенного запроса, а затем будет отброшен.Это говорит о том, что рассмотрение конкретного User имеет смысл в этом запросе, но следующий может быть совсем другим, а может быть, даже не касаться пользователей.

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

В конце концов, вам нужно будет решить, как объединить ваши взаимодействия с БД и как долго вы будете хранить эти связанные действия вместе.

Другие советы

Тот факт, что это связано с базой данных, не так важен, как тот факт, что у вас есть повторение кода.Вы на правильном пути, стремясь сделать код более пригодным для повторного использования.

Если вы поместите свои запросы в cfc, вы можете рассмотреть возможность сделать еще один шаг вперед.Вместо того, чтобы вызывать его постоянно, используйте метод onApplicationStart вашего Application.cfc, чтобы создать переменную приложения, доступную всем пользователям на всех страницах.

Другой подход — поместить все эти теги базы данных в файл .cfm и поместить cfinclude в метод onRequestStart вашего Application.cfc.

Оба метода работают.И, как это почти всегда бывает при сравнении двух вещей, каждая из них имеет преимущества перед другой.

У меня была бы модель для каждого стола.

там у вас есть каждый запрос, который когда-либо делал что-либо с этой таблицей

Допустим, таблица пользователей

Пользователи.cfc

будут иметь все методы, которые возвращают запросы

getUsers — вернуть всех пользователей

getUserById — также может быть параметром первой функции.

Затем, когда вам нужно выяснить, где что-то обновляется в заказах, есть только одно место для поиска.

Я получаю такие результаты

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

или я использую скрипт

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

А если вы действительно смелы, попробуйте также выполнить все запросы в сценарии.

И последнее, что следует учитывать: если данные не меняются, кэшируйте запрос.

Такие вещи, как OrderType или аналогичные, вы получите большой выигрыш в производительности вместо повторения запроса снова и снова.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top