【发布时间】:2012-02-13 00:56:41
【问题描述】:
对于 Grails,有几种方法可以做同样的事情。
查找所有域类实例:
Book.findAll()
Book.getAll()
Book.list()
检索指定 id 的域类的实例:
Book.findById(1)
Book.get(1)
你什么时候使用每一个?性能有显着差异吗?
【问题讨论】:
标签: grails grails-orm
对于 Grails,有几种方法可以做同样的事情。
查找所有域类实例:
Book.findAll()
Book.getAll()
Book.list()
检索指定 id 的域类的实例:
Book.findById(1)
Book.get(1)
你什么时候使用每一个?性能有显着差异吗?
【问题讨论】:
标签: grails grails-orm
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 检索单个实例。它使用 instance 缓存,因此在同一个 Hibernate 会话中的多次调用将导致最多一次数据库调用(例如,如果该实例在 2 级缓存中并且您已启用它)。
findById 是一个动态查找器,如findByName、findByFoo 等。因此它不使用实例缓存,但如果您启用了查询缓存(通常不是一个好主意),它可以被缓存。 get 应该是首选,因为它的缓存更智能;缓存的查询结果(即使是这样的单个实例)被悲观地清除的频率比您预期的要高,但实例缓存不需要如此悲观。
findById 的一个用例是作为与安全相关的检查,与另一个属性结合使用。例如,不是使用CreditCard.get(cardId) 检索CreditCard 实例,而是找到当前登录的用户并使用CreditCard.findByIdAndUser(cardId, user)。这假定 CreditCard 具有 User user 属性。这样,两个属性必须匹配,这将阻止黑客访问卡实例,因为卡 ID 可能匹配,但用户不会。
【讨论】:
Domain.findByID(id) 和 Domain.get(id) 之间的另一个区别是,如果您使用的是休眠过滤器,则需要使用 Domain.findById(id)。 Domain.get(id) 绕过过滤器。
【讨论】:
AFAIK,这些都是一样的
Book.findAll()
Book.getAll()
Book.list()
这些将返回相同的结果
Book.findById(1)
Book.get(1)
但get(id) 将使用缓存(如果启用),因此应该优先于findById(1)
【讨论】: