浏览 3226 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-12-30
class A has_many :Bs, :class_name=>'B',:foreign_key=>'b_id' end a = A.find(:first) 如果我仅想知道a.Bs.size()的话,那么在hibernate中就得单独写count语句来获取,如果使用a.getBS().size()的方式时,会先填充list,把所有Bs都初始化,也即会向数据库中发送.size()条SQL语句来初始化对象,影响性能。 但在ror中,像上面使用a.Bs.size方法的时候,它会先判断Bs是否已经被初始化,如果已经初始化过,则直接返回Bs.size,不需要查询数据库。若尚未初始化,则发送一条count(*)语句,返回总的记录条数。这一点我感觉比hibernate要聪明。 在这个过程中发现一个有趣的现象: N.times do print("a.Bs.size=#{a.Bs.size}"); end 如果a.Bs是可以获取到数据的话,那么上面语句,会发送N条count(*)的SQL。 反之如果a.Bs是空集合,数据库中根本没有相关记录的话,那么系统只会发送一条count(*)的SQL。为什么呢? 思考了一下,ROR是否是这样处理的,如果a.Bs.size>0,则它认为在下次查询时仍然需要去发送count(*)SQL。反之如果a.Bs.size==0,则它认为没必要再去发送count(*)的SQL了?但还是觉得有些离奇。 再次思考之后,是否是这样:如果第一次发现a.Bs.size>0,则它认为a.Bs是不为空的,但是先不去初始化它。而如果size==0,则它认为a.Bs是空值。直接就给a.Bs赋为空记录集了,所以再取a.Bs.size就不需要查询数据库了 另外的一点是,如果代码改成: print((a.Bs[0] rescue nil)); N.times do print("a.Bs.size=#{a.Bs.size}"); end 则只会发送select * from xxx的SQL。相当于初始化了a.Bs集合。在这个基础上再计算a.Bs.size,则不会发送count(*)的SQL,直接返回a.Bs集合的长度了。 这该怎么解释才更合理呢???? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |