Представления SQL/ базы данных в Grails
Кто-нибудь знает, каков наилучший подход к доступу к представлению SQL через Grails (или, если это вообще возможно)? Кажется очевидным способом сделать это было бы использовать executeQuery против представления, чтобы выбрать набор строк из представления, которые мы не будем рассматривать как список объектов домена. Однако даже в этом случае не очевидно, с каким классом домена запускать executeQuery, поскольку на самом деле мы просто используем этот класс домена, чтобы выполнить запрос к совершенно не связанной сущности (представление).
Было бы предпочтительным создать класс домена, представляющий представление, и тогда мы могли бы просто использовать list() для этого класса домена? Похоже, что с этим возникнут проблемы, поскольку Grails, вероятно, рассчитывает вставить, обновить, удалить и изменить схему таблицы любого класса домена.
[Редактировать:
Дополнительный вопрос здесь: класс домена Grails без поля идентификатора или с частично пустым составным полем
3 ответа
Вы можете использовать простой SQL в Grails, который в случае доступа к представлению является предпочтительным способом (IMO):
Например, в вашем контроллере:
import groovy.sql.Sql
class MyFancySqlController {
def dataSource // the Spring-Bean "dataSource" is auto-injected
def list = {
def db = new Sql(dataSource) // Create a new instance of groovy.sql.Sql with the DB of the Grails app
def result = db.rows("SELECT foo, bar FROM my_view") // Perform the query
[ result: result ] // return the results as model
}
}
и часть просмотра:
<g:each in="${result}">
<tr>
<td>${it.foo}</td>
<td>${it.bar}</td>
</tr>
</g:each>
Я надеюсь, что источник говорит само за себя. Документация может быть найдена здесь
Вы можете поместить это в сопоставления классов вашего домена:
static mapping = {
cache 'read-only'
}
Но я не уверен, поможет ли это Hibernate понять, что это представление... http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/
В любом случае, мы используем представления базы данных как классы домена grails в нашем текущем проекте, потому что HQL - это задница, и проще использовать SQL для объединения таблиц.
Однако нужно быть осторожным с одной вещью - это пакетирование запросов в Hibernate (и весь процесс очистки). Если вы вставляете что-то в таблицу, а затем в той же транзакции выбираете представление, зависящее от этой таблицы, вы не получите последние вставленные строки. Это связано с тем, что Hibernate на самом деле еще не вставил строки, тогда как если бы вы выбрали таблицу, в которую вы вставили строки, Hibernate выяснил бы, что необходимо сбросить ожидающие запросы, прежде чем дать вам результат выбора.
Одним из решений является (flush:true
) при сохранении экземпляра домена, который, как вы знаете, после этого потребуется прочитать в той же транзакции.
It would be cool however to have some kind of way to tell Hibernate that a view/domain depends on which other domain classes, so that the Hibernate flushing works well seemlessly.
Вполне возможно отобразить класс домена в представление, просто относиться к нему как к обычной таблице. Я думаю, что Grails напечатает некоторые сообщения журнала о невозможности вставки, удаления и т. Д., Но не выдаст никаких ошибок, если вы на самом деле не попытаетесь сделать что-то кроме запроса с классом домена.