【问题标题】:JPQL Group By TimeStamp as a DateJPQL 分组按时间戳作为日期
【发布时间】:2014-10-20 04:09:23
【问题描述】:

在 JPA 应用程序中,Bill 实体有一个名为 createAt 的属性,带有一个 TimeStamp 注释。

我只想按日期对账单进行分组,而不是按时间戳。

在查询中,虽然我将 TemporalType 作为 Date 传递,但仍然将账单分组为 Time。

如何使用 createdAt 属性按日期对账单进行分组。

我将 JPA 与 EclipseLink 2.5 一起使用。

账单实体

@Entity
public class Bill implements Serializable {
    ....
    ....

    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    Date createdAt;

    ....
    ....
}

这是用于列出账单的方法。

public String listProfitBillsDailySummery() {
    System.out.println("list profit bills");
    String jpql = "SELECT new com.divudi.data.DailySummeryRow(b.createdAt, b.freeValue, b.netTotal, b.discount) "
            + " FROM Bill b "
            + " WHERE (type(b)=:bc1 or type(b)=:bc2 or type(b)=:bc3 ) "
            + " and b.retired=false "
            + " and (b.billType=:bt1 or b.billType=:bt2 or b.billType=:bt3) "
            + " and b.createdAt between :fromDate and :toDate ";

    Map temMap = new HashMap();

    if (department != null) {
        jpql += " and b.department=:d ";
        temMap.put("d", department);
    }

    jpql += " group by b.createdAt "
            + "order by b.deptId  ";

    temMap.put("bc1", BilledBill.class);
    temMap.put("bc2", RefundBill.class);
    temMap.put("bc3", CancelledBill.class);

    temMap.put("bt1", BillType.PharmacyPurchaseBill);
    temMap.put("bt2", BillType.PharmacyGrnBill);
    temMap.put("bt3", BillType.PharmacySale);

    temMap.put("fromDate", getFromDate());
    temMap.put("toDate", getToDate());

    List<Object[]> dsso = getBillFacade().findAggregates(jpql, temMap, TemporalType.DATE);
    profitTotal = 0.0;
    discountTotal = 0.0;
    freeTotal =0.0;
    dailySummeryRows = new ArrayList<>();
    for (Object b : dsso) {
        DailySummeryRow dsr = (DailySummeryRow) b;
        profitTotal += dsr.getProfit();
        discountTotal += dsr.getDiscounts();
        freeTotal += dsr.getFreeAmounts();
        dailySummeryRows.add(dsr);
    }
    return "pharmacy_report_gross_profit_by_bills_ds";
}

这是Session Bean中的方法

public List<Object[]> findAggregates(String temSQL, Map<String, Object> parameters, TemporalType tt) {
        TypedQuery<Object[]> qry = getEntityManager().createQuery(temSQL, Object[].class);
        Set s = parameters.entrySet();
        Iterator it = s.iterator();
        while (it.hasNext()) {
            Map.Entry m = (Map.Entry) it.next();
            Object pVal =  m.getValue();
            String pPara = (String) m.getKey();
            if(pVal instanceof Date){
                Date pDate = (Date) pVal;
                qry.setParameter(pPara, pDate, TemporalType.DATE);
            }else{
                qry.setParameter(pPara, pVal);
            }
        }
        try {
            return qry.getResultList();
        } catch (Exception e) {
            System.out.println("e = " + e);
            return null;
        }
    }

【问题讨论】:

  • timestamp 和date 的区别并不是你想的那样。在这里查看:stackoverflow.com/questions/2305973/…
  • 谢谢。我用创建时间记录账单。但我想获取按日期分组的账单详细信息,例如总额或折扣。这就是我要解决的问题。
  • 那么你需要在group by时从列中提取日期

标签: jpa jpql


【解决方案1】:

我使用 FUNC('Date',b.createdAt) 按日期分组。

public String listProfitBillsDailySummery() {
    System.out.println("list profit bills");
    String jpql;
     jpql = "SELECT new com.divudi.data.DailySummeryRow(FUNC('DATE',b.createdAt), b.freeValue, b.netTotal, b.discount) "
            + " FROM Bill b "
            + " WHERE (type(b)=:bc1 or type(b)=:bc2 or type(b)=:bc3 ) "
            + " and b.retired=false "
            + " and (b.billType=:bt1 or b.billType=:bt2 or b.billType=:bt3) "
            + " and FUNC('DATE',b.createdAt) between :fromDate and :toDate ";

    Map temMap = new HashMap();

    if (department != null) {
        jpql += " and b.department=:d ";
        temMap.put("d", department);
    }

    jpql += " group by FUNC('DATE',b.createdAt) "
            + "order by FUNC('DATE',b.createdAt)  ";

    temMap.put("bc1", BilledBill.class);
    temMap.put("bc2", RefundBill.class);
    temMap.put("bc3", CancelledBill.class);

    temMap.put("bt1", BillType.PharmacyPurchaseBill);
    temMap.put("bt2", BillType.PharmacyGrnBill);
    temMap.put("bt3", BillType.PharmacySale);

    temMap.put("fromDate", getFromDate());
    temMap.put("toDate", getToDate());

    List<Object[]> dsso = getBillFacade().findAggregates(jpql, temMap, TemporalType.DATE);
    profitTotal = 0.0;
    discountTotal = 0.0;
    freeTotal =0.0;
    dailySummeryRows = new ArrayList<>();
    if(dsso==null){
        dsso = new ArrayList<>();
        System.out.println("new list as null");
    }
    for (Object b : dsso) {
        DailySummeryRow dsr = (DailySummeryRow) b;
        profitTotal += dsr.getProfit();
        discountTotal += dsr.getDiscounts();
        freeTotal += dsr.getFreeAmounts();
        dailySummeryRows.add(dsr);
    }
    return "pharmacy_report_gross_profit_by_bills_ds";
}

【讨论】:

  • 这很酷。但请记住 Func 是特定于供应商 (EclipseLink) 的,而不是来自纯 JPA。因此,如果您更改 ORM,您可能也需要更改查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多