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

Art*_*ero 50 grails grails-orm

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

查找所有域类实例:

Book.findAll()
Book.getAll()
Book.list()
Run Code Online (Sandbox Code Playgroud)

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

Book.findById(1)
Book.get(1)
Run Code Online (Sandbox Code Playgroud)

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

Bur*_*ith 90

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会话中的多个调用将导致最多一个数据库调用(例如,如果实例位于二级缓存中并且您已启用它).

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

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


Bra*_*ads 12

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