hibernate OneToOne hql多表查询
昨日运营同学提了个问题,table的模糊查询只支持当前页,查询时需要一页一页的翻,用户体验度有待提高。
技术层面是因为查询调用公共的public Pagination pageQuery(final Criterion[] criterions, final Integer startLine, final Integer pageSize, final String orderBy, final boolean isAsc){}方法,该方法对单表查询支持比较不错,把查询条件添加到Criterion数组,执行pageQuery便可以进行各种组合查询,但对多表查询无过多说明。
用jd-gui反编译工具,我找到了public Pagination pageQuery(final String hql, final Integer startLine, final Integer pageSize){}方法,可以动态组装hql查询语句,虽然麻烦,但灵活性比较好。因此我对原有代码进行重构,用hql实现多表查询。
我们有一个主表App,它有id、name两个字段;一个从表AppExtend,它有id、appId、phoneUrl三个字段。我们要实现的是AppExtend通过appId字段关联App表,模糊查询App的name字段,并且AppExtend的phoneUrl字段不为空。
首先我们在AppExtend用OneToOne声明和App的关系:
@Entity(name = "v4_app_extend")
@Data
public class AppExtend extends BasePojo {
@Id
@GeneratedValue(generator="Ididentity")
@GenericGenerator(name="Ididentity",strategy="identity")
private Integer id;
@Column(name = "app_id")
private Integer appId;
@Column(name = "phone_url")
private String phoneUrl;
@OneToOne
@JoinColumn(name = "app_id", referencedColumnName = "id", nullable = true, insertable = false, updatable = false)
private App app;
}
JoinColumn的name指AppExtend的外键,referencedColumnName指关联到App的主键。
下面我们通过代码演示如何拼装hql,代码如下:
@RequestMapping(value = "/getAppExtend", produces = "text/plain;charset=UTF-8")
@ResponseBody
public String getAppExtend(HttpServletRequest request) throws Exception {
int recordsTotal = 0;
PagRequestInfo info = PagInfoUtil.getPagInfo1(request);
String hql = null;
if (StringUtils.isNotBlank(info.getKeyword())) {
hql = "from com.letv.gc.opman.mutilplatform.pojo.AppExtend extend left join extend.app app where app.name like '%"
+ info.getKeyword() + "%' and extend.phoneUrl != ''";
} else {
hql = "from com.letv.gc.opman.mutilplatform.pojo.AppExtend extend left join extend.app app where extend.phoneUrl != ''";
}
Pagination p = appExtendManager.pageQuery(hql, Integer.parseInt(info.getStart()),
Integer.parseInt(info.getLength()));
recordsTotal = p.getTotalCount();
JSONArray jsonArray = new JSONArray();
for (int index = 0; index < p.getRecords().size(); index++) {
Object[] objects = (Object[]) p.getRecords().get(index);
AppExtend appExtend = (AppExtend) objects[0];
App app = appManager.findUniqueBy("id", appExtend.getAppId());
jsonArray.add(JSONObject.fromObject(app));
}
return PagInfoUtil.returnPageResult(jsonArray, recordsTotal, info.getFlag());
}
由于p.getRecords().get(index);的返回值包含AppExtend和App两个对象,因此我们用Object[]数组强转,然后获得AppExtend。
在上述讲解中,我们用注解OneToOne和JoinColumn声明关联字段,根据业务需要动态拼装hql,实现了多表查询功能,提高了用户体验度。
希望分享可以帮助到大家。