问题的来源:
在@ManyToOne中,由于默认的fetch=FetchType.EAGER,所以如下的代码
List<Topic> topics = session.createQuery("from Topic").list();
本来只发一条sql就能查询出所以的Topic对象,结果Topic所关联的Catagory对象也会马上查询出来,而且如果有N个Topic对象,就会再发N条sql去查询Catagory对象。
解决办法:
1、@ManyToOne(fetch=FetchType.LAZY)
//fetch=FetchType.LAZY 解决N+1问题 说明如下:
//当多对一(@ManyToOne)已经设定属性" fetch=FetchType.LAZY "时
//只有当需要时(如:t.getCategory().getName()时)才会去获取关联表中数据 可以解决N+1问题
2、@BatchSize
//@BatchSize 解决N+1问题 说明如下:
//在与查询表(此例中为Topic类)关联的表类(此例中为Category类)头处加@BatchSize(size=5)
//表示每次可查出5条记录 从而减少了select语句的个数
3、join fetch(使用join fetch后返回的是一种对象(List<Topic>),而不是像只使用join 返回多种对象List<Ojbect[]>)
//join fetch 解决N+1问题 说明如下:
//修改hql语句为--" from Topic t left join fetch t.category c "
4、QBC
//QBC(Query By Criteria) 解决N+1问题 说明如下:
//使用QBC的 createCriteria(*.class)执行查询 也可避免N+1问题