Spring data jpa 复杂动态查询方式总结
前略...
四.继承JpaSpecificationExecutor接口进行复杂查询
使用 这个接口
public Predicate toPredicate(Root<Equipment> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder)
需要了解: CriteriaBuilder 接口的使用
CriteriaBuilder 用于构建 查询,计算选择,表达式,条件, 排序等
用到了: 相等条件, and, or
Predicate equal(Expression<?> x, Object y);
Predicate and(Predicate... restrictions);
Predicate or(Expression<Boolean> x, Expression<Boolean> y);
这里 Expression 对象通过 root 获取, 在查询的时候 expression 会转成 hql
public Predicate toPredicate(Root<Equipment> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
Expression expression = root.get("equipmentId").as(String.class)
criteriaBuilder.equal(expression, "123")
query.where(expression);
return query.getRestriction();
}
生成的 hql
SELECT
generatedAlias0
FROM
Equipment AS generatedAlias0
WHERE
( generatedAlias0.equipmentId=: param0 )
遇到 org.hibernate.QueryException: Expression to CAST cannot be an entity : emequipmen0_.type
如何查询关联对象的条件, 答案是使用 root.get("type").get("typeId")
root 可以当做是一个被查询的对象,root.get 取出指定的属性, 就像取出对象的属性一样, 返回值也是root,也可以用get取属性, 就能得到需要做比较的值了
另外, 使用反射获取对象的属性值,不用一个个调用get
Field field = Equipment.class.getDeclaredField("equipmentId");
// 设置 accessible 访问私有变量
field.setAccessible(true);
field.get(queryParam);
参考: