среда, 15 августа 2012 г.

Grails GORM: Избегайте HQL и уже тем более SQL запросов

GORM построен поверх Hibernate а в нём есть два API для работы с БД: Hibernate Query Langauge (HQL) и Criteria API.
HQL по сути тот же SQL, только не специфичный для конкретной БД:
def results = Book.findAll("from Book as b where b.title like 'Lord of the%'")

Criteria API это объектно ориентированный подход к построению запросов. От этого он может получатся менее выразительным и громоздким. Но в замен вы получаете более удобный механизм генерации сложных запросов в ООП стиле, вместо генерирования HQL как текста (а значит и меньше ошибок связанных с некорректным HQL):
def c = Account.createCriteria()
def results = c {
    between("balance", 500, 1000)
    eq("branch", "London")
    or {
        like("holderFirstName", "Fred%")
        like("holderFirstName", "Barney%")
    }
    maxResults(10)
    order("holderLastName", "desc"

Кроме того, вам не нужно отдельно учить синтаксис SQL и HQL, что позволит новичкам быстрей разобраться с этим кодом. И уж тем более новичкам будет сложней сделать ошибку, поскольку запрос становится статически типизированным и ваша IDE может подсказать автодополнение а компилятор ругнутся на ошибку.
Если в Java иногда предпочитают HQL за его краткость, то Grails предоставляет удобный DSL для Criteri API, так что даже этот аргумент теряет свою важность.

И самое главное, запросы в Criteria API стиле могут быть программно проанализированы и это позволяет покрыть интеграционными тестами код который работают БД. Grails предоставляет просто шикарный тестовый фреймворк который позволяет тестировать работу с доменными объектами имитируя работу с GORM через лёгое in-memory хранилище.

Самое вкусное что большую часть простых запросов вы можете выполнить через механизм динамических методов с префиксом findBy (finders, файндеры):
def book = Book.findByTitle("The Stand")
book = Book.findByTitleLike("Harry Pot%")
book = Book.findByReleaseDateBetween(firstDate, secondDate)
book = Book.findByReleaseDateGreaterThan(someDate)
book = Book.findByTitleLikeOrReleaseDateLessThan("%Something%", someDate)
Внутри себя Grails конвертирует их в Criteria API запросы.
По возможности старайтесь использовать такие динамические файндеры они более краткие и очень выразительные.

И напоследок, обязательно изучите руководство по GORM'у чтобы не плодить проблем. Именно запросы в БД чаще всего являются узким местом в вашем приложении из-за которого проседает производтельность.
К сожалению в GORM очень много ловушек многих из которых избежать вам помогут три статьи евангелиста Grails Питера Ледбрука (Peter Ledbrook):
  1. GORM GOTCHAS (PART 1) Перевод на русский
  2. GORM GOTCHAS (PART 2) Перевод на русский
  3. GORM GOTCHAS (PART 3) (перевода на русский нет)

Комментариев нет:

Отправить комментарий