2012-07-16 163 views
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个日期之间的日期。

Ex。 2012年1月1日至2012年7月30日

在CommissionSummary实体中没有日期列,但它有月份和年份2个单独的列。

我想根据月份和年份栏获取用户给出的从日期到日期的CommissionSummary记录。

那么如何使用Hibernate Criteria/Restrictions来实现这个?

注意:日期字段对于从当前输入的用户没有任何意义。

回答

3

可以打破标准分解成三个较小的标准脱节:

  1. 该委员会的年度等于查询的开始年份,其月份大于或等于查询的起始月份
  2. 佣金的年份大于查询的开始年份并且小于其结束年份
  3. 该委员会的年度等于查询的NEND年,其每月小于或等于查询的月末

你可以写的每一个作为两个简单比较的结合的。这看起来像(未测试!):

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)) 
); 
+0

它的工作原理,只需很少的Syntaxchanges是必需的。这里是生成的SQL:SELECT this _。* FROM Commissionsummary this_ WHERE((this_.year = 2011 AND this_.month> = 11)OR(this_.year> 2011 AND this_.year <2012)OR(this_.year = 2012 AND this_.month <= 2)) – 2012-07-17 04:51:06

-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(); 
+0

-1:那不回答问题。 OP要求从一个日期到另一个日期的所有记录。 – 2012-07-16 09:22:56

+0

我在仔细阅读问题后纠正了我之前的回答。谢谢你的提示 – user1512999 2012-07-16 09:37:26

+0

它仍然没有回答问题 - 他想用**标准**或**限制**解决这个问题,而不是HQL。话虽如此,但他为什么说这个限制并不明显,因为他不打算以妨碍HQL查询的方式来使用这些标准。您的解决方案比他的解决方案更简洁,更高效,更易于阅读和维护。 – Kkkev 2012-07-16 18:22:07

0

没有任何可这样做限制。您必须创建自己的Criterion子类,它可以生成适当的SQL,或使用Restrictions.sqlRestriction()

在SQL,在Oracle中,SQL限制可能看起来像以下:

to_date(c.year || '-' || c.month || '-01', 'YYYY-MM-DD') between :startDate and :endDate) 
-1

感谢您的答案@JB Nizet告诉正确的做法,但它是从本地的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))