Grails中findAll,getAll和list之间的区别

时间:2012-01-18 09:33:13

标签: grails gorm

使用Grails有几种方法可以做同样的事情。

查找所有域类实例:

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

检索指定id的域类的实例:

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

你什么时候使用每一个?性能有显着差异吗?

3 个答案:

答案 0 :(得分:89)

getAllget的增强版,需要多个ID并返回List个实例。列表大小将与提供的ID数相同;任何未命中都会在该位置产生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会话中的多个调用将导致最多一个数据库调用(例如,如果实例位于二级缓存中并且您已启用它)。 / p>

findById是一个动态查找程序,如findByNamefindByFoo等。因此它不使用实例缓存,但如果启用了查询缓存,则可以缓存(通常不是一个好主意)。 get应该是首选,因为它的缓存更加智能;缓存的查询结果(即使对于像这样的单个实例)也会比您预期的更频繁地被清除,但实例缓存不需要那么悲观。

我对findById的一个用例是与安全相关的检查,与另一个属性相结合。例如,我没有使用CreditCard检索CreditCard.get(cardId)实例,而是找到当前登录的用户并使用CreditCard.findByIdAndUser(cardId, user)。这假定CreditCard具有User user属性。这样两个属性都必须匹配,这会阻止黑客访问卡实例,因为卡ID可能匹配,但用户不会。

答案 1 :(得分:12)

Domain.findByID(id)和Domain.get(id)之间的另一个区别是,如果您使用的是hibernate过滤器,则需要使用Domain.findById(id)。 Domain.get(id)绕过过滤器。

答案 2 :(得分:4)

AFAIK,这些都是相同的

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

这些将返回相同的结果

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

get(id)将使用缓存(如果已启用),因此应首选findById(1)