使用Grails有几种方法可以做同样的事情。
查找所有域类实例:
Book.findAll()
Book.getAll()
Book.list()
检索指定id的域类的实例:
Book.findById(1)
Book.get(1)
你什么时候使用每一个?性能有显着差异吗?
答案 0 :(得分:89)
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
get
按ID检索单个实例。它使用实例缓存,因此在同一个Hibernate会话中的多个调用将导致最多一个数据库调用(例如,如果实例位于二级缓存中并且您已启用它)。 / p>
findById
是一个动态查找程序,如findByName
,findByFoo
等。因此它不使用实例缓存,但如果启用了查询缓存,则可以缓存(通常不是一个好主意)。 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)