Может ли эксперт по Java 8 + JDBC сказать мне, если что-то не так в следующих рассуждениях? И, если в тайнах богов, почему это не было сделано?
java.sql.Date
в настоящее время является типом, используемым JDBC для сопоставления с типом DATE SQL, который представляет дату без времени и без часового пояса. Но этот класс разработан ужасно, поскольку на самом деле он является подклассом java.util.Date
, который хранит точный момент времени, вплоть до миллисекунды.
Чтобы представить дату 2015-09-13 в базе данных, мы вынуждены выбрать часовой пояс, проанализировав строку "2015-09-13T00: 00: 00.000" в этом часовом поясе как java.util.Date, чтобы получить миллисекунду. значение, затем создайте java.sql.Date
из этого значения в миллисекундах и, наконец, вызовите setDate()
для подготовленного оператора, передавая Calendar, содержащий часовой пояс, выбранный для того, чтобы драйвер JDBC мог правильно пересчитать дату 2015-09-13 из этого значения в миллисекундах. Этот процесс немного упрощается благодаря повсеместному использованию часового пояса по умолчанию и отсутствию календаря.
Java 8 представляет класс LocalDate, который намного лучше подходит для типа базы данных DATE, поскольку он не является точным моментом времени и, следовательно, не зависит от часового пояса. В Java 8 также представлены методы по умолчанию, которые позволяют вносить обратно совместимые изменения в интерфейсы PreparedStatement и ResultSet.
Итак, не упустили ли мы огромную возможность навести порядок в JDBC при сохранении обратной совместимости? Java 8 могла бы просто добавить эти методы по умолчанию в PreparedStatement и ResultSet:
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();
}
Конечно, то же самое относится и к поддержке Instant для типа TIMESTAMP, и к поддержке LocalTime для типа TIME.