仅基于天使用不同日期值的 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 名称。
我正在使用 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 名称。