0

私は次のようなエンティティを持っています

public class CommissionSummary {    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column(length = 100)
    private String advisorCode;
    @Column(length = 100)
    private String advisorName;
    private String advisorCodeParent;
    @Column(length = 100)
    private String advisorNameParent;
    @Column(length = 100)
    private String advisorPost;
    @Column
    private Double percentage;
    @Column
    private Double diffPercentage;
    @Column
    private Double saleAmount;
    @Column
    private Long saleCount;
    @Column
    **private Double commissionAmount;
    @Column
    private Integer month;
    @Column
    private Integer year;**
    //Getter Setter
}

画面上で、ユーザーは2つの日付の間の日付をフェッチするための基準を入力しています。

元。2012年1月1日から2012年7月30日まで。

CommissionSummaryエンティティには日付列はありませんが、月と年の2つの別々の列があります。

月と年の列に基づいて、ユーザーが指定した日付から日付までの期間のCommissionSummaryレコードを取得したいと思います。

では、Hibernateの基準/制限を使用してこれを達成するにはどうすればよいですか?

注:[日]フィールドは、ユーザーが入力した日付と日付には意味がありません。

4

4 に答える 4

3

基準を3つの小さな基準の論理和に分解できます。

  1. 委員会の年はクエリの開始年と等しく、その月はクエリの開始月以上です
  2. 委員会の年はクエリの開始年よりも大きく、終了年よりも小さい
  3. 委員会の年はクエリの終了年と等しく、その月はクエリの終了月以下です

これらのそれぞれを、2つの単純な比較の接続詞として記述できます。これは次のようになります(テストされていません!):

int fromYear, fromMonth, toYear, toMonth;
Property year = Property.forName("year");
Property month = Property.forName("month");
session.createCriteria(CommissionSummary.class).add(Restrictions.disjunction()
    .add(Restrictions.and(year.eq(fromYear), month.ge(fromMonth))
    .add(Restrictions.and(year.gt(fromYear), year.lt(toYear))
    .add(Restrictions.and(year.eq(toYear), month.le(toMonth))
);
于 2012-07-16T19:14:08.033 に答える
0

それを行うために利用できる制限はありません。適切なSQLを生成する独自のCriterionサブクラスを作成するか、を使用する必要がありますRestrictions.sqlRestriction()

SQLでは、Oracleでは、SQLの制限は次のようになります。

to_date(c.year || '-' || c.month || '-01', 'YYYY-MM-DD') between :startDate and :endDate)
于 2012-07-16T09:21:38.457 に答える
-1

HQLを使用して、必要なものを選択できます。

session.beginTransaction();
session.clear();

Query query = session.createSQLQuery(" from CommissionSummary CS  where  to_date(CS.year || '-' || CS.month || '-01', 'YYYY-MM-DD') between :startDate and :endDate)"

List result = query.list();
于 2012-07-16T09:20:58.710 に答える
-1

すべての回答に感謝します@JBNizetは正しいアプローチを教えてくれましたが、これはネイティブSQLからのものです。私は成功して以下を試しました....

public List<CommissionSummary> getCommissionSummary(AdvisorReportForm advisorReportForm) {
        Criteria criteria = getSession().createCriteria(CommissionSummary.class);
        if (advisorReportForm.getAdvisorId() != null && advisorReportForm.getAdvisorId() > 0) {
            criteria.add(Restrictions.eq("advisorCode", advisorReportForm.getAdvisorId().toString()));
        }

        if (advisorReportForm.getFromDate() != null && advisorReportForm.getToDate() != null) {
            Calendar calFrom = Calendar.getInstance();
            calFrom.setTime(advisorReportForm.getFromDate());

            Calendar calTo = Calendar.getInstance();
            calTo.setTime(advisorReportForm.getToDate());

            Criterion crit1 = Restrictions.eq("month", calFrom.get(Calendar.MONTH) + 1);
            Criterion crit2 = Restrictions.eq("year", calFrom.get(Calendar.YEAR));
            Criterion critMonthYear1 = Restrictions.and(crit1, crit2);
            calFrom.add(Calendar.MONTH, 1); // increment loop by month

            Criterion critAll = critMonthYear1;
            while (calFrom.getTimeInMillis() < calTo.getTimeInMillis()) {
                Criterion crit1Loop = Restrictions.eq("month", calFrom.get(Calendar.MONTH) + 1);
                Criterion crit2Loop = Restrictions.eq("year", calFrom.get(Calendar.YEAR));
                Criterion critMonthYearLoop = Restrictions.and(crit1Loop, crit2Loop);
                critAll = Restrictions.or(critAll, critMonthYearLoop);
                calFrom.add(Calendar.MONTH, 1); // increment loop by month
            }
            criteria.add(critAll);

        }

        return criteria.list();
    }

日付から日付までの差は最大6か月まで検証されます。パフォーマンスの問題はあまり見られません。だからこれを使用しました。

参考までに、ここで生成されたSQLが生成されます

SELECT * FROM CommissionSummary this_ 
WHERE this_.advisorCode=1 
AND (((((this_.month=11 AND this_.year=2011) OR (this_.month=12 AND this_.year=2011)) OR (this_.month=1 AND this_.year=2012)) 
OR (this_.month=2 AND this_.year=2012)) OR (this_.month=3 AND this_.year=2012))
于 2012-07-16T10:19:51.140 に答える