在Grails中findAll,getAll和list之间的区别
Grails有几种方法可以做同样的事情。
查找所有的域类实例:
Book.findAll() Book.getAll() Book.list()
检索指定标识的域类的实例:
Book.findById(1) Book.get(1)
你什么时候使用每一个? 性能有显着差异吗?
getAll
是get
的增强版本,它接受多个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
通过id检索单个实例。 它使用实例caching,所以在同一个Hibernate会话中多次调用最多只会导致一次数据库调用(例如,如果实例处于二级caching中,并且已启用它)。
findById
是一个dynamic查找器,如findByName
, findByFoo
等。因此,它不使用实例caching,但可以caching,如果你有查询caching启用(通常不是一个好主意)。 get
应该是首选,因为它的caching更聪明; caching的查询结果(即使对于像这样的单个实例)被悲观地清除得比你期望的更频繁,但是实例caching不需要如此悲观。
一个用例,我会为findById
作为一个安全相关的检查,结合另一个属性。 例如,我不是使用CreditCard.get(cardId)
检索CreditCard
实例,而是find当前login的用户并使用CreditCard.findByIdAndUser(cardId, user)
。 这假定CreditCard
具有User user
属性。 这样两个属性必须匹配,这将阻止黑客访问卡实例,因为卡ID可能匹配,但用户不会。
Domain.findByID(id)和Domain.get(id)之间的另一个区别是,如果您使用的是hibernate筛选器,则需要使用Domain.findById(id)。 Domain.get(id)绕过filter。
AFAIK,这些都是一样的
Book.findAll() Book.getAll() Book.list()
这些将返回相同的结果
Book.findById(1) Book.get(1)
但get(id)
将使用caching(如果启用),所以应该优先findById(1)