我正在使用CriteriaQuery和CriteriaBuilder来挂载一个动态where。我有一些过滤值,用户选择,可以通知或不。但是使用合取 predicate 并不能返回正确的where子句。这是我的代码:
// Create CriteriaBuilder
CriteriaBuilder builder = session.getCriteriaBuilder();
// Create CriteriaQuery
CriteriaQuery<Tarea> criteria = builder.createQuery(Tarea.class);
// Set root
Root<Tarea> root = criteria.from(Tarea.class);
criteria.select(root);
if(getSortColumn()!= null && !getSortColumn().equals("")) {
criteria.orderBy(builder.asc(root.get(getSortColumn())));
}
Predicate predFinal = builder.conjunction();
if(filtro.getClasificacionTarea() != null && filtro.getClasificacionTarea().size()>0) {
Predicate predClasificacion = builder.disjunction();
for(Clasificacion clas : filtro.getClasificacionTarea()) {
predClasificacion.getExpressions().add(builder.equal(root.get("clasificacion").get("id"), clas.getId()));
}
predFinal.getExpressions().add(predClasificacion);
}
if(filtro.getProyecto() != null) {
Predicate predicateProyecto;
predicateProyecto = builder.and(builder.equal(root.get("OT").get("proyecto"), filtro.getProyecto()));
predFinal.getExpressions().add(predicateProyecto);
}
if(filtro.getCliente() != null) {
Predicate predicateCliente;
predicateCliente = builder.and(builder.equal(root.get("ot").get("cliente").get("id"), filtro.getCliente().getId()));
predFinal.getExpressions().add(predicateCliente);
}
if(filtro.getProvincia() != null) {
Predicate predicateProvincia;
predicateProvincia = builder.and(builder.equal(root.get("ot").get("provincia").get("id"), filtro.getProvincia().getId()));
predFinal.getExpressions().add(predicateProvincia);
}
if(filtro.getPais() != null) {
Predicate predicatePais;
predicatePais = builder.and(builder.equal(root.get("ot").get("pais").get("id"), filtro.getPais().getId()));
predFinal.getExpressions().add(predicatePais);
}
predFinal.getExpressions().add(builder.and(builder.isNull(root.get("fechaBaja"))));
criteria.where(predFinal);
// Query execution
Query<Tarea> query = session.createQuery(criteria);
以及按任何字段过滤时得到的查询:
Hibernate:
select
t1_0.id,
t1_0.fk_idPedidoVenta,
t1_0.fk_idClasificacionTarea,
t1_0.confirmado,
t1_0.fk_idUsuarioCreacion,
t1_0.fechaCreacion,
t1_0.fechaBaja,
t1_0.fechaInicio,
t1_0.fechaFin,
t1_0.finalizado,
t1_0.horaInicio,
t1_0.horaFin,
t1_0.observaciones,
t1_0.fk_idTipoTarea
from
Tarea t1_0
where
1=1
order by
t1_0.fechaInicio
Where子句总是1=1,所以它返回所有记录。
这是我第一次使用CriteriaBuilder,所以也许我用错了?谢谢你的帮助
2条答案
按热度按时间9rnv2umw1#
您不能更新
Predicate
的表达式。从Predicate.getExpressions()(强调是添加的):返回 predicate 的顶级合取词或析取词。如果 predicate 没有顶级合取词或析取词,则返回空列表。修改列表不影响查询。
conj()似乎不是一个好方法:
创建一个合取(零合取)。合取为零的合取为真。
因此,不要使用
conjuction()
,而是创建一个List<Predicate>
,添加到它,然后使用它:或者,我认为这就是
conjuction()
存在的原因,不要添加到它的表达式中,而是替换 predicate 本身:wqnecbli2#
这可能是因为您使用
Predicate.getExpressions
来收集 predicate 。根据文档,将 predicate 直接添加到这个列表不会影响查询,也就是说,该方法很可能返回 predicate 列表的防御副本。为了解决这个问题,我会手动创建一个Predicate
s的列表:将各个 predicate 添加到它(基于
if
条件),然后使用CriteriaBuilder.and
获得合取: