Kann mir irgendein Java 8 + JDBC-Experte sagen, ob etwas in der folgenden Argumentation falsch ist? Und wenn dies in den Geheimnissen der Götter geschieht, warum wurde das nicht getan?Verpasste Gelegenheit, JDBC-Datumsverarbeitung in Java 8 zu beheben?
Ein java.sql.Date
ist derzeit der Typ, der von JDBC verwendet wird, um dem DATE-SQL-Typ zuzuordnen, der ein Datum ohne Zeit und ohne Zeitzone darstellt. Aber diese Klasse ist schrecklich entworfen, da es in der Tat eine Unterklasse von java.util.Date
ist, die einen genauen Zeitpunkt in der Millisekunde speichert.
Um das Datum 2015.09.13 in der Datenbank zu repräsentieren, sind wir somit gezwungen, eine Zeitzone zu wählen, analysieren die Zeichenfolge „2015-09-13T00: 00: 00.000“ in dieser Zeitzone als java.util.Date Um einen Millisekunden-Wert zu erhalten, konstruiere dann einen java.sql.Date
von diesem Millisekunden-Wert und rufe schließlich setDate()
auf der vorbereiteten Anweisung an und übergibt einen Kalender mit der gewählten Zeitzone, damit der JDBC-Treiber das Datum 2015-09-13 korrekt neu berechnen kann von diesem Millisekundenwert. Dieser Prozess wird durch die Verwendung der Standardzeitzone überall und das Übergeben eines Kalenders vereinfacht.
Java 8 führt eine LocalDate-Klasse ein, die viel besser zum DATE-Datenbanktyp passt, da es sich nicht um einen genauen Zeitpunkt handelt und somit nicht von der Zeitzone abhängig ist. Und Java 8 führt auch Standardmethoden ein, die es ermöglichen, abwärtskompatible Änderungen an den Interfaces PreparedStatement und ResultSet vorzunehmen.
Also, haben wir nicht eine riesige Gelegenheit verpasst, die Unordnung in JDBC zu bereinigen, während wir immer noch Abwärtskompatibilität beibehalten?
default public void setLocalDate(int parameterIndex, LocalDate localDate) {
if (localDate == null) {
setDate(parameterIndex, null);
}
else {
ZoneId utc = ZoneId.of("UTC");
java.util.Date utilDate = java.util.Date.from(localDate.atStartOfDay(utc).toInstant());
Date sqlDate = new Date(utilDate.getTime());
setDate(parameterIndex, sqlDate, Calendar.getInstance(TimeZone.getTimeZone(utc)));
}
}
default LocalDate getLocalDate(int parameterIndex) {
ZoneId utc = ZoneId.of("UTC");
Date sqlDate = getDate(parameterIndex, Calendar.getInstance(TimeZone.getTimeZone(utc)));
if (sqlDate == null) {
return null;
}
java.util.Date utilDate = new java.util.Date(sqlDate.getTime());
return utilDate.toInstant().atZone(utc).toLocalDate();
}
Natürlich ist die gleiche Argumentation gilt für die Unterstützung von Sofort für den Zeitstempel-Typen, und die Unterstützung von Localtime für den TIME-Typen: Java 8 einfach haben könnte, um diese Standardmethoden PreparedStatement und ResultSet hinzugefügt.
Statt das zu tun, sagen Sie sich einfach die 'setObject' Methode zu verwenden. Wenn das Objekt ein 'LocalDate 'ist, sollten aktuelle JDBC-Treiber wissen, was damit zu tun ist. – RealSkeptic
Ich habe das gesehen. Aber es ist schade, weil wir auf aktuelle Treiber warten müssen, und Bibliotheken können nie sicher sein, dass der JDBC-Treiber tatsächlich LocalDate unterstützt, also implementieren sie diese Funktionalität neu, anstatt sich auf eine Standardimplementierung zu verlassen. Und wir müssen getDate(). ToLocalDate() auf einem ResultSet ausführen, um ein LocalDate zu erhalten. –
Oder verwenden Sie ein 'getObject (int, Class)' und verlassen Sie sich auf den JDBC-Treiber, um damit umgehen zu können. Wie auch immer, das ist ihre Politik für jetzt. Die Frage ist, welche Art von Antworten erwarten Sie von SO zu diesem Thema? – RealSkeptic