在下面的查询中,我只想按日期分组,而不是按时间分组,这就是我使用TO_DATE函数的原因
select TO_DATE(e.created_dt, 'dd-mm-yy'),sum(CURRENT_BAL) from sbill.act_resource_t e group by TO_DATE(e.created_dt, 'dd-mm-yy');所以到目前为止,它在oracle中工作得很好,但是根据我们业务需求,应用程序应该同时支持oracle和mysql,而不需要编写两个不同的查询;
那么,我们有没有什么解决方案可以同时适用于oracle和mysql呢?
注意:-我使用的是hql
下面的代码:
Query query1 = entityManager.createQuery("select TO_DATE(e.createdDt, 'dd-mm-yy'),sum(CURRENT_BAL) from ActT e group by TO_DATE(e.createdDt, 'dd-mm-yy')");
List<Object> result=query1.getResultList();发布于 2019-08-10 06:32:28
由于不同数据库的功能不同,我们需要一个dynamic query。但我们可以通过创建一个自定义的转换方法来有效地完成这项工作,该方法将根据当前的数据库类型选择正确的实现。并且查询本身将保持通用(解决方案使用FluentJPA库):
public static final FormatModel DD_MM_YY = Format.dateModel(Format.DD, Format.MM, Format.YY);
public static boolean isOracle() {
return false; //should return the actual value in runtime
}
@Local
// picks the right implementation
public static Function1<String, Date> AS_DATE() {
if (isOracle())
return s -> TO_DATE(s, DD_MM_YY); //oracle
return s -> STR_TO_DATE(s, "%d-%m-%y"); // mysql
}现在我们可以编写一个通用的实现:
@Entity
@Table(name = "act_resource_t", schema = "sbill")
@Data
public static class ActResource {
@Id
private int id;
private int currentBAL;
private String createdDT;
}
// for the result
@Tuple
@Data
public static class BalanceByDate {
private Date date;
private int balance;
}
...
public BalanceByDate balanceByDate() {
FluentQuery query = FluentJPA.SQL((ActResource e) -> {
// with lambda we inject the right implementation
Date createdDate = alias(AS_DATE().apply(e.getCreatedDT()), BalanceByDate::getDate);
Integer balance = alias(SUM(e.getCurrentBAL()), BalanceByDate::getBalance);
SELECT(createdDate, balance);
FROM(e);
GROUP(BY(createdDate));
});
return query.createQuery(em, BalanceByDate.class).getSingleResult();
}这是为MySQL生成的SQL:
SELECT STR_TO_DATE(t0.created_dt, '%d-%m-%y') AS date, SUM(t0.current_bal) AS balance
FROM sbill.act_resource_t t0
GROUP BY STR_TO_DATE(t0.created_dt, '%d-%m-%y')https://stackoverflow.com/questions/57429484
复制相似问题