您的位置:首页 > 其它

hibernate criteria 多表关联查询

2017-09-24 14:06 1406 查看
当QBC criteria关联查询的时候一般都需要取别名。今天就遇到一个问题

先贴代码(修改之后正确的代码):

@Override
public SearchResult<TravelAirticket> findListPageByKeyword(Integer page, Integer pageSize, String keyword,
Long airlineCompanyId, Integer transfNum) {
Criteria criteria = createCriteria();
if (StringUtils.isNotBlank(keyword)) {
if (keyword.equals(String.valueOf(Constant.Airticket.ONE_WAY_TICKET))) {// 单程
criteria.add(Restrictions.eq("travelAirticketType", Constant.Airticket.ONE_WAY_TICKET));
} else if (keyword.equals(String.valueOf(Constant.Airticket.RETURN_TICKET))) {// 往返
criteria.add(Restrictions.eq("travelAirticketType", Constant.Airticket.RETURN_TICKET));
} else {
keyword = "%" + keyword + "%";
criteria.createAlias("departureAirport", "departureAirport");
criteria.createAlias("destinationAirport", "destinationAirport");
criteria.createAlias("departureAirport.city", "departureAirportCity");
criteria.createAlias("destinationAirport.city", "destinationAirportCity");
criteria.createAlias("airlineCompany", "airlineCompany");
criteria.add(Restrictions.or(
Restrictions.like("departureAirport.codeName", keyword),
Restrictions.like("departureAirport.cnName", keyword),
Restrictions.like("departureAirport.enName", keyword),
Restrictions.like("destinationAirport.codeName", keyword),
Restrictions.like("destinationAirport.cnName", keyword),
Restrictions.like("destinationAirport.enName", keyword),
Restrictions.like("airlineCompany.shortName", keyword),
Restrictions.like("airlineCompany.enName", keyword),
Restrictions.like("airlineCompany.cnName", keyword),
Restrictions.like("departureAirportCity.codeName", keyword),
Restrictions.like("departureAirportCity.cnName", keyword),
Restrictions.like("departureAirportCity.enName", keyword),
Restrictions.like("destinationAirportCity.codeName", keyword),
Restrictions.like("destinationAirportCity.cnName", keyword),
Restrictions.like("destinationAirportCity.enName", keyword)));
}
}
criteria.add(Restrictions.eq("state", Constant.Airticket.STATE_PASS));
if (airlineCompanyId != null) {
criteria.add(Restrictions.eq("airlineCompany.id", airlineCompanyId));
}
if (transfNum != null && transfNum != Constant.Airticket.TRANSF_UNRESTRICTED) {
criteria.add(Restrictions.eq("transfNum", transfNum));
}
criteria.addOrder(Order.desc("id"));
long count = (Long)criteria.setProjection(Projections.rowCount()).uniqueResult();
List list = criteria.setProjection(null).setFirstResult((page - 1) * pageSize).setMaxResults(pageSize).list();
return new SearchResult<TravelAirticket>(count, list);
}


我需要进行模糊查询机票和机场以及机场的城市的中英文名,这里就是三张表了。

开始的时候一直报错org.hibernate.QueryException: could not resolve property:......内容就是你关联表的属性名等信息(id除外)

后面发现如果这样三张表查询的话就需要将第二张表取一个别名,再将第三张表取别名进行联合查询。查看源码还是是使用的inner join

源码:

@Override
public Criteria createAlias(String associationPath, String alias) {
return createAlias( associationPath, alias, JoinType.INNER_JOIN );
}
@Override
public Criteria createAlias(String associationPath, String alias, JoinType joinType) throws HibernateException {
new Subcriteria( this, associationPath, alias, joinType );
return this;
}


如果是N张表,我想大家应该不会用这样的方式,当然这样以此类推取别名我想应该也行得通,具体还没实验

如果不取别名,只能匹配类型的id,就像这样:criteria.add(Restrictions.eq("airlineCompany.id", airlineCompanyId));

2017-10-12 补充:

如果是进行id匹配查询,建议不取别名。如果取别名会将别名那张表的那个id那行数据一起带出来。导致不是我们想要的结果集。也会形成一个数组,但是里面包含了2个对象,一个我们想要查询的对象和一个关联表行映射的对象。

如果是非id关联条件查询,比如匹配另外一张表的name属性查询,取别名是可以的。这样没有条件查询的id,就不会带出来关联表那行数据。

今天遇到了,匹配id取别名查询,hibernate将关联表id那行数据也查询出来了,不是我们想要的结果。

记录记录,希望对大家有用!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: