仅基于天使用不同日期值的 Hibernate 标准

Hibernate criteria to use distinct date values on the basis of day only

我正在使用 Hibernate Criteria API 并对我的结果使用投影,如下所示:

projList.add(Projections.property("router"), "router");
projList.add(Projections.property("date"), "date");

criteria.setProjection(Projections.distinct(projList));

输出:

2017-01-10 19:47:33.0   Router1
2017-01-11 20:45:59.0   Router1
2017-01-10 21:58:49.0   Router2
2017-01-10 21:59:00.0   Router2

此代码按预期工作,但我想 运行 基于唯一日期记录的不同函数,这意味着不同函数不应该考虑时间值而只考虑日期值。所以输出应该是这样的:

2017-01-10  Router1
2017-01-11  Router1
2017-01-10  Router2

知道怎么做吗?

我找到了一个解决方案,虽然不是很干净..

a) 创建一个 POJO class 来存储投影结果

public class Proj{

   private Date date;
   private String router;

   // .. getters / setters
}

b) 在您的标准 API 中使用 'sqlProjections' 作为日期 属性(此处为原生 sql ..我在 MySql):

projList.add(Projections.sqlProjection("DATE_FORMAT(date, '%Y-%m-%d') as date", new String[]{"date"},new Type[] {new StringType()}));

这足以获得您正在寻找的不同值,尽管日期将采用字符串格式,如果您想将其转换为日期,则:

c) 将 ResultTransformer 添加到条件 api:

.setResultTransformer(new ResultTransformer() {
      public Object transformTuple(Object[] tuple, String[] aliases) {
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
         java.util.Date parsed = null;
         try {
              parsed = format.parse((String) tuple[1]);
         } catch (ParseException e) {}

         Proj p = new Proj();
         p.setDate(parsed);
         p.setRouter((String)tuple[0]);
         return p;  
      }
)

就像我说的,这不是最漂亮的解决方案,但它对我有用。 条件现在调用 returns 一个封装了您要查找的结果的对象。

我找到了一种方法:

而不是

projList.add(Projections.property("date"), "date");

使用

projList.add(Projections.sqlProjection( "date(date) as date", new String[] {"date"}, new Type[] {StandardBasicTypes.STRING} ));

其中表达式 "date(date) as date" 第一个 "date" 是 mysql 函数,“(date)”是日期的 HBM 列名称,因为 "as date" 是 return来自 mysql 和类型 "date" 的列名称将是将要填充的 bean 名称。