Hibernate的检索策略包括类级别检索策略和关联级别检索策略
类级别检索策略有立即检索和延迟检索默认的检索策略是立即检索在Hibernate映射文件中通过在<class>上配置lazy属性来确定检索策略对于Session的检索方式类级别检索策略仅适用于load方法也就说对于getqurey检索持久化对象都会被立即加载而不管lazy是false还是true一般来说我们检索对象就是要访问它因此立即检索是通常的选择由于load方法在检索不到对象时会抛出异常(立即检索的情况下)因此我个人并不建议使用load检索而由于<class>中的lazy属性还影响到多对一及一对一的检索策略因此使用load方法就更没必要了
关联级别检索策略有立即检索延迟检索和迫切左外连接检索对于关联级别检索又可分为一对多和多对多多对一和一对一两种情况讨论
一对多和多对多关联关系一般使用<set>配置<set>有lazy和outerjoin属性它们的不同取值绝对了检索策略
)立即检索这是一对多默认的检索策略此时lazy=falseouterjoin=false尽管这是默认的检索策略但如果关联的集合是无用的那么就不要使用这种检索方式
)延迟检索此时lazy=trueouterjoin=false(outerjoin=true是无意义的)这是优先考虑的检索方式
)迫切左外连接检索此时 lazy=falseouterjoin=true这种检索策略只适用于依靠id检索方式(loadget)而不适用于query的集合检索(它会采用立即检索策略)相比于立即检索这种检索策略减少了一条sql语句但在Hibernate中只能有一个<set>配置成 outerjoin=true
多对一和一对一检索策略一般使用<manytoone><onetoone>配置<manytoone>中需要配置的属性是 outerjoin同时还需要配置one端关联的<class>的lazy属性(配置的可不是<manytoone>中的lazy哦)它们的组合后的检索策略如下
) outerjoin=auto这是默认值如果lazy=true为延迟检索如果lazy=false为迫切左外连接检索
) outerjoin=true无关于lazy都为迫切左外连接检索
) outerjoin=false如果lazy=true为延迟检索否则为立即检索
可以看到在默认的情况下(outerjoin=autolazy=false)对关联的one端对象Hibernate采用的迫切左外连接检索依我看很多情况下我们并不需要加载one端关联的对象(很可能我们需要的仅仅是关联对象的id)另外如果关联对象也采用了迫切左外连接检索就会出现select语句中有多个外连接表如果个数多的话会影响检索性能这也是为什么Hibernate通过hibernatemax_fetch_depth属性来控制外连接的深度对于迫切左外连接检索query的集合检索并不适用它会采用立即检索策略
对于检索策略需要根据实际情况进行选择对于立即检索和延迟检索它们的优点在于select语句简单(每张表一条语句)查询速度快缺点在于关联表时需要多条select语句增加了访问数据库的频率因此在选择即检索和延迟检索时可以考虑使用批量检索策略来减少select语句的数量(配置batchsize属性)对于切左外连接检索优点在于select较少但缺点是select语句的复杂度提高多表之间的关联会是很耗时的操作另外配置文件是死的但程序是活的可以根据需要在程序里显示的指定检索策略(可能经常需要在程序中显示指定迫切左外连接检索)为了清楚检索策略的配置效果如何可以配置show_sql属性查看程序运行时Hibernate执行的sql语句