使用hql或条件查询解决一对多关联查询的N+1查询问题

  如下两个实体类有一对多和多对一的双向关联
public class DictType
{
	@Id
	private int id;
	private String className;
	private String classDesc;
	@Column(name="isSys")
	private boolean sysParam;
	@OneToMany(cascade=CascadeType.MERGE,mappedBy="dictType",fetch=FetchType.LAZY)
	private Set<Parameter> parameters=new HashSet<Parameter>();

      //getter and setter...

}
@Entity
public class Parameter implements java.io.Serializable {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	private String parameterName;
	private String parameterValue;
	private String parameterDesc;
	@ManyToOne
	@JoinColumn(name="dictType")
	private DictType dictType;
//getter and setter...
}

现在要查询DictType 的同时关联查询出它下面的parameters。在集合延迟查询的情况下一次性出结果避免N+1问题(有关hibernate的N+1查询问题请自行百度)

使用hql解决:

String hqlString="select distinct d from DictType d left join fetch d.parameters";

注意这里的关键是left join 加了fetch,使得在延迟的情况下强制抓取关联。而加distinct是因为使用的是left join语句,如果一个DictType的parameters有多条数据那就会有多条DictType返回。

使用条件查询:
使用条件查询同样我们要解决延迟情况下关联集合的抓取和重复结果的筛选问题,以下代码使用的离线集合:

DetachedCriteria criteria=DetachedCriteria.forClass(clazz);
		criteria.setFetchMode("parameters", FetchMode.JOIN)
		.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
这里使用setFetchMode抓取关联集合,使用setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)筛选重复结果。需要注意的是:
Criteria通过setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)方法对查询后结果进行排重,这种方式是先查询出可能重复的记录然后根据每个对象的equals方法进行排重,所以: 
  • 1. 要排重的对象要实现equals方法。
  • 2. 不能进行分页处理,因为是先查询后distinct,结果会不准确。
  • 3. 查询处理的结果集太大的话,可能存在性能问题,相同记录会查询多次;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值