Hibernate中用criteria builder处理日期与时间分开的字段
Hibernate中用criteria builder处理日期与时间分开的字段
December 6, 2018
现有系统中原先在设计数据库字段的时候,把日期与时间分别存入两个不同的字段,但是这两个字段在数据库中都是以timestamp类型来保存。这样的话,如果需要在where条件中把这两个字段与某个特定的时间做比较,则需要分别截取有效的信息。对于日期字段仅仅取出日期的值,把时间舍弃;对于时间字段仅仅取出时间的值,把日期舍弃。
举个例子,假设数据库中有两个字段:returnSlaDate存的是物品归还截止日期,returnSlaTime存的是物品归还截止时间。实际在保存的时候,数据库中returnSlaDate字段的值可能会是 2018-12-31 00:00:00 ,其中 00:00:00 是没有用的,在与特定时间做比较的时候,需要舍弃;returnSlaTime字段的值可能会是 1970-01-01 17:59:59 ,其中 1970-01-01 是没有用的,在与特定时间做比较的时候,需要舍弃。
假设数据库中有另外一个字段actualReturnDate,它表示物品实际归还时间(仅仅一个字段表示,包含有效的日期与时间)。如果现在有个需求,要在系统中查出来物品未按时归还的记录,需要怎么处理呢?直接用SQL写会相对简单,如果用hibernate的criteria builder则需要用as关键字做一下转换。下面是示例代码:
// 转换截止日期字段成java.sql.Date类型,这样可以仅取出日期的值
Expression returnSlaDate = pTimeSchedule.get("returnSlaDate").as(java.sql.Date.class);
// 转换截止时间字段成java.sql.Time类型,这样可以仅取出时间的值
Expression returnSlaTime = pTimeSchedule.get("returnSlaTime").as(java.sql.Time.class);
// 对实际归还时间做与上面一样的处理
Expression actualReturnDate = pTimeSchedule.get("actualReturnDate").as(java.sql.Date.class);
Expression actualReturnTime = pTimeSchedule.get("actualReturnDate").as(java.sql.Time.class);
// 在where语句中,筛选出实际归还日期大于截止日期,或者实际归还日期等于截止日期且归还时间大于截止时间
orFilter.add(builder.or(
builder.greaterThan(actualReturnDate, returnSlaDate),
builder.and(
builder.equal(actualReturnDate, returnSlaDate),
builder.greaterThan(actualReturnTime, returnSlaTime)
)
));
打出hibernate的日志,可以看到转换之后的SQL语句
(
cast(generatedAlias0.actualReturnDate as date)>cast(generatedAlias0.timeSchedule.returnSlaDate as date)
)
or (
(
cast(generatedAlias0.actualReturnDate as date)=cast(generatedAlias0.timeSchedule.returnSlaDate as date)
)
and (
cast(generatedAlias0.actualReturnDate as time)>cast(generatedAlias0.returnSlaTime as time)
)
)
最后更新于