我的更改基于Ish答案:
public List<TopUpRAMSInfo> listadoTOPUP2(Date fechaI, Date fechaF) {
List<TopUpRAMSInfo> lista;
CriteriaQuery<TopUpRAMSInfo> data = cb.createQuery(TopUpRAMSInfo.class);
Root<TopUpRAMS> c = data.from(TopUpRAMS.class);
data.select(cb.construct(TopUpRAMSInfo.class,
c.get("deviceId"),
cb.sum(c.get("rechargeValue"))
)
);
data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI),
cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF)
);
data.groupBy(c.get("deviceId"));
TypedQuery<TopUpRAMSInfo> datos = emDAO.createQuery(data);
lista = datos.getResultList();
return lista;
}
现在我有这个错误: java.lang.IllegalArgumentException:在类上发生异常:使用选择条件类型作为参数的构造函数的类ENTITY.TopUpRAMSInfo。如果此CriteriaQuery不是构造函数查询,请验证选择是否与返回类型匹配。
----- ORIGINAL POST -----
我遇到了一些问题。这是我正在尝试构建的第一个真正的程序,我需要根据另一个来总结一个字段。
到目前为止,这是我的代码(请注意TopUpRAMS
是我的实体,emDAO
是我的实体经理。
public List<TopUpRAMS> listadoTOPUP2(Date fechaI, Date fechaF) {
List<TopUpRAMS> lista;
CriteriaQuery<TopUpRAMS> data = cb.createQuery(TopUpRAMS.class);
Root<TopUpRAMS> c = data.from(TopUpRAMS.class);
data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue")));
data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI));
cb.and(cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF));
data.groupBy(c.get("deviceId"));
TypedQuery<TopUpRAMS> datos = emDAO.createQuery(data);
lista = datos.getResultList();
return lista;
}
答案 0 :(得分:9)
如何构建CriteriaQuery的WHERE部分存在问题。 此表达式是唯一添加到WHERE子句的表达式:
cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI)
但不是这一个:
cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF)
任何ff。可以解决这个问题:
使用cb.and():
data.where(cb.and(
cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI),
cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF)
)
);
CriteriaQuery.where()可以接受可变数量的参数 类型表达式,它们将使用连接(AND 运营商)。所以,我们不需要使用cb.and():
data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI),
cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF)
);
CriteriaQuery中使用的类型也存在问题。您通过2个字段的data.multiselect()进行投影,这将无法转换为TopUpRams实体。
有多种方法可以进行多选/投影:
CriteriaQuery类型将是Object []
CriteriaQuery<Object[]> data = cb.createQuery(Object[].class);
Root<TopUpRAMS> c = data.from(TopUpRAMS.class);
data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue")));
CriteriaQuery类型将是Tuple
CriteriaQuery<Tuple> data = cb.createTupleQuery();
Root<TopUpRAMS> c = data.from(TopUpRAMS.class);
data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue")));
使用构造函数
CriteriaQuery<TopUpRAMSInfo> data = cb.createQuery(TopUpRAMSInfo.class);
Root<TopUpRAMS> c = data.from(TopUpRAMS.class);
data.select(cb.construct(TopUpRAMSInfo.class,
c.get("deviceId"),
cb.sum(c.get("rechargeValue"))
)
);
为此,您需要创建一个单独的类来表示类型 您的查询结果(它不必是实体):
public class TopUpRAMSInfo {
private Long deviceId;
private Double sumRechargeValue;
public TopUpRAMSInfo(Long deviceId, Double sumRechargeValue) {
this.deviceId = deviceId;
this.sumRechargeValue = sumRechargeValue;
}
...
}
所以这是对您的方法的示例修复:
public List<TopUpRAMSInfo> listadoTOPUP2(Date fechaI, Date fechaF) {
List<TopUpRAMSInfo> lista;
CriteriaQuery<TopUpRAMS> data = cb.createQuery(TopUpRAMSInfo.class);
Root<TopUpRAMS> c = data.from(TopUpRAMS.class);
data.select(cb.construct(TopUpRAMSInfo.class,
c.get("deviceId"),
cb.sum(c.get("rechargeValue"))
)
);
data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI),
cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF)
);
data.groupBy(c.get("deviceId"));
TypedQuery<TopUpRAMSInfo> datos = emDAO.createQuery(data);
lista = datos.getResultList();
return lista;
}