Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
jooq转换器:从java.sql.Date到java.time.LocalDate_Java_Sql_Jdbc_Jooq_Java Time - Fatal编程技术网

jooq转换器:从java.sql.Date到java.time.LocalDate

jooq转换器:从java.sql.Date到java.time.LocalDate,java,sql,jdbc,jooq,java-time,Java,Sql,Jdbc,Jooq,Java Time,我曾尝试编写一个转换器,但无法使其与所有时区设置一起工作 这个想法: 如果客户机代码具有LocalDate,例如2014年8月20日,并将其保存到数据库中,则无论客户机时区是什么,它在数据库中都应显示为2014年8月20日 如果DB包含2014年8月20日的日期,则客户应收到2014年8月20日的本地日期,无论客户时区是什么 我的测试: @Test public void dateConverter() { for (int offset = -12; offset <= 12;

我曾尝试编写一个
转换器
,但无法使其与所有时区设置一起工作

这个想法:

  • 如果客户机代码具有
    LocalDate
    ,例如2014年8月20日,并将其保存到数据库中,则无论客户机时区是什么,它在数据库中都应显示为2014年8月20日
  • 如果DB包含2014年8月20日的日期,则客户应收到2014年8月20日的本地日期,无论客户时区是什么
我的测试:

@Test public void dateConverter() {
  for (int offset = -12; offset <= 12; offset++) {
    TimeZone localTz = TimeZone.getTimeZone(ZoneOffset.ofHours(offset));
    TimeZone.setDefault(localTz);
    LocalDate ld = LocalDate.now();

    sql.insertInto(DATE_TEST).set(new DateTestRecord(ld)).execute();
    LocalDate savedLd = sql.selectFrom(DATE_TEST).fetchOne(DATE_TEST.DATE_);
    assertEquals(savedLd, ld, "offset=" + offset);
    sql.delete(DATE_TEST).execute();
  }
}
@Test public void dateConverter(){

对于(int offset=-12;offset问题实际上在测试中!JDBC驱动程序在创建时区时将其缓存,而测试循环中的时区更新未被考虑。每次测试中时区发生更改时,都使用新连接使其通过

因此,问题中的代码适用于Date-to-LocalDate转换器(除了它应该接受null之外)。最终版本:

public class DateConverter implements Converter<Date, LocalDate> {
  @Override public LocalDate from(Date date) { return date == null ? null : date.toLocalDate(); }
  @Override public Date to(LocalDate ld) { return ld == null ? null : Date.valueOf(ld); }
  @Override public Class<Date> fromType() { return Date.class; }
  @Override public Class<LocalDate> toType() { return LocalDate.class; }
}
公共类DateConverter实现转换器{
@重写公共LocalDate from(Date-Date){return Date==null?null:Date.toLocalDate();}
@将公共日期重写为(LocalDate ld){return ld==null?null:Date.valueOf(ld);}
@重写公共类fromType(){return Date.Class;}
@重写公共类toType(){return LocalDate.Class;}
}
时区到偏移时间转换器的时间可以采用类似的方式进行:

public class TimeConverter implements Converter<Time, OffsetTime> {
  @Override public OffsetTime from(Time time) {
    return time == null ? null : OffsetTime.ofInstant(Instant.ofEpochMilli(time.getTime()), ZoneOffset.systemDefault());
  }
  @Override public Time to(OffsetTime offsetTime) {
    return offsetTime == null ? null : new Time(offsetTime.atDate(LocalDate.ofEpochDay(0)).toInstant().toEpochMilli());
  }
  @Override public Class<Time> fromType() { return Time.class; }
  @Override public Class<OffsetTime> toType() { return OffsetTime.class; }
}
公共类TimeConverter实现转换器{
@覆盖公共偏移时间自(时间){
返回时间==null?null:OffsetTime.ofInstant(Instant.ofEpochMilli(time.getTime()),ZoneOffset.systemDefault());
}
@将公共时间覆盖到(OffsetTime OffsetTime){
return offsetTime==null?null:新时间(offsetTime.atDate(LocalDate.ofEpochDay(0)).toInstant().toEpochMilli());
}
@重写公共类fromType(){return Time.Class;}
@重写公共类toType(){return OffsetTime.Class;}
}

“JDBC驱动程序缓存时区”:嗯,什么JDBC驱动程序会这样做?注意,在上有一个关于带时区的
时间戳的
数据类型的持续讨论。我无法获得一个类似的转换器,与时间戳工作-可能相关?(这是postgres最新的驱动程序)是的,这肯定是相关的。你确定JDBC驱动程序真的缓存了时区吗?我希望驱动程序在建立连接时使用当前默认时区,并为连接设置该时区。在连接客户端使用SET TIME ZONE等更改时区之前,此时区设置保持有效。在这种情况下,仅更改JRE的默认时区不会影响到与DB的已建立连接和会话,但该时区根本不会被缓存。只是在建立会话期间,驱动程序会与当前时区通信,然后由连接客户端根据需要更改时区。否则e驱动程序只会以一种不可预测的方式使用您的会话进行“东西”通信和发送命令。我想如果您也使用数据库客户端的命令更改会话时区,您的测试就会成功。
public class TimeConverter implements Converter<Time, OffsetTime> {
  @Override public OffsetTime from(Time time) {
    return time == null ? null : OffsetTime.ofInstant(Instant.ofEpochMilli(time.getTime()), ZoneOffset.systemDefault());
  }
  @Override public Time to(OffsetTime offsetTime) {
    return offsetTime == null ? null : new Time(offsetTime.atDate(LocalDate.ofEpochDay(0)).toInstant().toEpochMilli());
  }
  @Override public Class<Time> fromType() { return Time.class; }
  @Override public Class<OffsetTime> toType() { return OffsetTime.class; }
}