repository层
@Query(nativeQuery = true, value = "select * from alarms where id = :id and alarmtime = to_date(:alarmtime)")
Optional<Alarm> findByKey(@Param("id") Long id, @Param("alarmtime") String alarmtime);
注意,可能会有人用to_number(alarmtime) = :alarmtime(alarmtime传时间戳)来比较,这样是不正确。这种方法是先将整个alarmtime这一列做转换,然后再比较,如果数据量太大,速度会急速下降。所以sql语句最好不要整个列加方法,而是应该对要比较的条件处理和列的原始值比较。
service层
public Alarm getByIdAndAlarmtime(Long id, Long alarmtime) {
if (id == null || alarmtime == null) {
throw new ServiceException(400, "确认警报失败:警报id为null");
}
TimeZone tz = TimeZone.getDefault();
int offset = tz.getOffset(System.currentTimeMillis());
Date alarmdate = new Date(alarmtime - offset);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String format = simpleDateFormat.format(alarmdate);
Optional<Alarm> optionalAlarm = alarmRepository.findByKey(id, format);
if (!optionalAlarm.isPresent()) {
throw new ServiceException(404, "Object not found");
}
return optionalAlarm.get();
}
这里需要注意两点:1、时间精确到毫秒的格式正则。2、在Phoenix中to_date是有时差的,所以调用之前要先获取系统当前时区,调整alarmtime。
网友评论