Разница между findAll, getAll и списком в Grails

С Grails существует несколько способов сделать то же самое.

Находит все экземпляры класса домена:

Book.findAll()
Book.getAll()
Book.list()

Получает экземпляр класса домена для указанного id:

Book.findById(1)
Book.get(1)

Когда вы используете каждый из них? Существуют ли существенные различия в производительности?

Ответ 1

getAll - расширенная версия get, которая принимает несколько идентификаторов и возвращает List экземпляров. Размер списка будет таким же, как и количество предоставленных идентификаторов; любые промахи приведут к null в этом слоте. См. http://grails.org/doc/latest/ref/Domain%20Classes/getAll.html

findAll позволяет использовать запросы HQL и поддерживает разбиение на страницы, но они не ограничены экземплярами вызывающего класса, поэтому я использую executeQuery. См. http://grails.org/doc/latest/ref/Domain%20Classes/findAll.html

List находит все экземпляры и поддерживает разбиение на страницы. См. http://grails.org/doc/latest/ref/Domain%20Classes/list.html

get извлекает один экземпляр по id. Он использует кеш экземпляра, поэтому несколько вызовов в одном сеансе Hibernate приведут к не более чем одному вызову базы данных (например, если экземпляр находится в кэше второго уровня и вы включили его).

findById - это динамический искатель, такой как findByName, findByFoo и т.д. По сути, он не использует кеш экземпляра, но может быть кэширован, если включено кэширование запросов (как правило, это не очень хорошая идея). get должно быть предпочтительным, поскольку его кеширование намного умнее; кэшированные результаты запроса (даже для одного экземпляра, подобного этому) пессимистически очищаются чаще, чем вы ожидали, но кеш экземпляра не должен быть настолько пессимистичным.

В одном случае, который я использовал бы для findById, как проверка безопасности, в сочетании с другим свойством. Например, вместо того, чтобы извлекать экземпляр CreditCard с помощью CreditCard.get(cardId), я бы нашел пользователя, который в настоящее время вошел в систему, и используйте CreditCard.findByIdAndUser(cardId, user). Это предполагает, что CreditCard имеет свойство User user. Таким образом, оба свойства должны совпадать, и это заблокировало бы хакеру доступ к экземпляру карты, поскольку идентификатор карты мог бы совпадать, но пользователь этого не сделал.

Ответ 2

Другая разница между Domain.findByID(id) и Domain.get(id) заключается в том, что если вы используете фильтр спящего режима, вам нужно использовать Domain.findById(id). Domain.get(id) обходит фильтр.

Ответ 3

AFAIK, все они идентичны

Book.findAll()
Book.getAll()
Book.list()

Они вернут те же результаты

Book.findById(1)
Book.get(1)

но get(id) будет использовать кеш (если он включен), поэтому следует предпочесть findById(1)