Урок 2. Сессии, Модель данных
5. Взаимодействие с базой данных
Объектные запросы
Кроссплатформенные запросы, которые выполняются на уровне объектов класса.
При выполнении запроса идет обращение к базе данных, за исключением случаев кеширования.
Пример запроса
new OQuery(Bs_GoodsAta.Type) { where(t.sSystemName === spMnemoCode) }
Методы
-
where
Условие запроса. -
orderBy
Выражение для сортировки резуьтата -
batchAll
Массовая загрузка объектов. Возвращает строки с прогруженными записями всех коллекций этого класса. -
forUpdate
Выполнение запроса с блокированием вернувшихся записей -
forUpdateNoWait
Выполнение запроса с блокирование вернувшихся записей, без ожидания разблокирования, если записи уже заблокированы другой сессией. -
tryCacheQueryResults
Попытаться закешировать результат запроса. Смотри пункт «Кеширование» -
unique
Говорит, что запрос возвращает одну уникальную запись. Позволяет использовать cache-index’ы, указанные в orm класса
Кеширование объектных запросов
Кеширование запросов работает только для классов с разделяемым режимом кеширования(Shared
).
Кэширование по полю
Кеширование через cache-index’ы указанные в orm класса. Такой запрос должен возвращать одну строку и дополняется командой unique()
. Например для атрибутов мнемокода класса в orm формируется запись:
<cache-index>
<column-name>SSYSTEMNAME</column-name>
</cache-index>
Запрос выглядит следующим образом:
new OQuery(entityAta.Type) { unique() where(t.sSystemName*=== spMnemoCode) }
Кэширование объектных запросов
Кэширование объектных запросов возможно по требованию в случае, если класс настроен для сохранения в разделяемом кэше.
Чтобы включить кэширование запроса:
- Добавьте в запрос опцию
tryCacheQueryResults()
.
Результат такого запроса будет кэширован, если транзакция не находится в режиме редактирования разделяемых объектов.
Пример запроса:
new OQuery(entityAta.Type) { tryCacheQueryResults () where(t.sSystemName === spMnemoCode) }
Транзакционный индекс
Позволяет получить перечень строк по значению индексируемого атрибута. Индекс подгружает данные из базы данных по мере обращения к ключам индекса, а также отслеживает транзакционные изменения для получения согласованного набора строк. Это позволяет получить согласованный доступ к множеству строк по ключу, даже если индексируемое значение строки меняется в рамках этой транзакции.
Пример объявления:
lazy val idxidParent = TxIndex(Btk_GroupAta.Type)(_.idParentGroup)
Методы
-
byKey
Посетитель по ключу индекса. -
refreshByKey
Посетитель по ключу индекса c обновлением из базы данных. -
queryKeys
Кеширование ключей индекса. -
forPartition
Открывает секцию для массового обновления индекса. Используется для прозрачного массового обновления после очистки транзакционного кэша. Секции могут быть вложенными друг в друга, в таком случае ключи суммируются.
byParent
Метод есть у классов коллекций, возвращает обходчик записей отфильтрованных по идентификатору предка
Реляционные запросы
Для обработки реляционных запросов в основном используется методы на базе anorm.
Для более удобного использования в контекст бизнес логики добавлены дополнительные функции.
ASQL
Выполнение запроса на чтение Создаёт объект AnormSql для выполнения запроса к базе без модификации данных. Если в текущей сессии начата транзакция, SQL-выражение выполняется в ней. Если транзакция в сессии не начата, запрос выполнится в автономной sql-транзакции.
Пример:
val idTrigger = 1 ASQL"SELECT t.sCaption as sHeadline FROM Btk_JobSchedule t WHERE t.id = $idTrigger".as(nStr("sHeadline").*).headOption
ATSQL
Выполнение запроса с изменением данных или блокировками Создаёт объект AnormSql с возможностью модификации данных. Если в текущей сессии начата транзакция, SQL-выражение выполняется в ней. Если в текущей сессии транзакция не начата, она будет начата.
Пример:
ATSQL("alter table bs_barcode add id int8;").execute()
ASelect
Выполнение запросов на чтение\запись с большим количеством колонок.
Пример:
for (rv <- new ASelect { val nParentLevel = asInt("nParentLevel") val gidParent = asString("gidParent") val gidChild = asString("gidChild") val idParent = asLong("idParent") SQL""" select nParentLevel,gidParent,gidChild,idParent,idChild from table """ }) { println(rv.nParentLevel()) //запрос поля без его предварительного объявления println(rv.get("idChild").asNLong()) }