Top Banner
Java 8 Date Time API mit PostgreSQL Swiss PGDay 2016
47

Java8 date-time-api-mit-postgre sql

Jan 07, 2017

Download

Technology

Netcetera
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Java8 date-time-api-mit-postgre sql

Java 8 Date Time API mit PostgreSQL

Swiss PGDay 2016

Page 2: Java8 date-time-api-mit-postgre sql

Philippe Marschall

• Netcetera

• Java Entwickler seit 2007

• viel Backend (JDBC)

• Java 8 Date Time Unterstützung in pgjdbc

Page 3: Java8 date-time-api-mit-postgre sql

Agenda• alte JDBC Date API

• neue Java 8 Date Time API

• JDBC

• Spring JdbcTemplate

• JPA

• (pgjdbc)

Page 4: Java8 date-time-api-mit-postgre sql

Publikum

• Architekten

• Java-Entwickler

• (DBAs)

Page 5: Java8 date-time-api-mit-postgre sql

alte Date API

• Warum brauchen wir eine neue API?

Page 6: Java8 date-time-api-mit-postgre sql

alte JDBC Date API

DATE TIMESTAMPTIME

java.sql.Time

java.util.Date

java.sql.Timestampjava.sql.Date

Page 7: Java8 date-time-api-mit-postgre sql

java.util.Date

• kein Datum, Zeitpunkt

• Anzahl Millisekunden seit 1.1.1970 00:00 GMT

• praktisch alle Methoden deprecated

Page 8: Java8 date-time-api-mit-postgre sql

java.sql.Date

• kein Subtyp

• Anzahl Millisekunden zwischen 1.1.1970 00:00 GMT bis 00:00 von Datum in JVM Zeitzone

• 24.6.2016

• Anzahl Millisekunden zwischen 1.1.1970 00:00 GMT und 24.6.2016 00:00 CEST

Page 9: Java8 date-time-api-mit-postgre sql

Liskovsches Substitutionsprinzip

• Operationen die auf einem Supertyp funktionieren müssen auch auf einem Subtyp funktionieren

• https://de.wikipedia.org/wiki/Liskovsches_Substitutionsprinzip

Page 10: Java8 date-time-api-mit-postgre sql

JVM Zeitzone

• Betriebssystem-User Zeitzone

• kann beim JVM-Start überschrieben werden mit -Duser.timezone

• kann zur Laufzeit geändert werden mit java.util.TimeZone.setDefault

Page 11: Java8 date-time-api-mit-postgre sql

java.sql.Time

• kein Subtyp

• Anzahl Millisekunden zwischen 1.1.1970 00:00 GMT bis Zeit am 1.1.1970 in JVM Zeitzone

• 15:10

• Anzahl Millisekunden zwischen 1.1.1970 00:00 GMT bis 1.1.1970 15:10 CEST

Page 12: Java8 date-time-api-mit-postgre sql

java.sql.Timestamp• kein Subtyp

• #equals nicht symmetrisch

• Nanosekunden-Auflösung

• Anzahl Millisekunden seit 1.1.1970 00:00 GMT und Zeitpunk in JVM Zeitzone

• plus Nanosekunden

• 24.6.2016 15:10

• Anzahl Millisekunden seit 1.1.1970 00:00 GMT und 24.6.2016 15:10 CEST

Page 13: Java8 date-time-api-mit-postgre sql

Vor Java 8 nicht unterstützt

• (TIME WITH TIME ZONE)

• TIMESTAMP WITH TIME ZONE

Page 14: Java8 date-time-api-mit-postgre sql

TIME WITH TIME ZONE

• Postgres Dokumentation rät ab

Page 15: Java8 date-time-api-mit-postgre sql

TIMESTAMP WITH TIME ZONE

• einziger SQL Datentyp der eindeutig einen Zeitpunkt identifiziert

Page 16: Java8 date-time-api-mit-postgre sql

kein Zeitpunk

• 1. Mondlandung

• 1969-07-20 20:18:04

Page 17: Java8 date-time-api-mit-postgre sql

Zeitpunk

• 1969-07-20 20:18:04 Z

• 1969-07-20 21:18:04 Europe/Zurich

• 1969-07-20 23:18:04 Europe/Moscow

• 1969-07-20 16:18:04 America/New_York

• 1969-07-21 06:18:04 Australia/Sydney

Page 18: Java8 date-time-api-mit-postgre sql

Zeitpunkt• alte JDBC API braucht Zeitpunkte für Sachen die

keine Zeitpunkte sind

• DATE

• TIME

• TIMESTAMP

• nur TIMESTAMP WITH TIME ZONE ist ein Zeitpunkt

Page 19: Java8 date-time-api-mit-postgre sql

TIMESTAMP WITH TIME ZONE

• “brauchen wir nicht”

• “wir haben nur eine Zeitzone”

Page 20: Java8 date-time-api-mit-postgre sql

Stille Datenabschneidung

• mit TIMESTAMP [ WITHOUT TIME ZONE ] können Daten beim speichern verändert werden wenn eine andere Zeitzone als UTC verwendet wird

• Sommer-Winterzeitumstellung

• Schweiz hat zwei Zeitzonen: CET und CEST

Page 21: Java8 date-time-api-mit-postgre sql

Stille Datenabschneidung

• 2016-10-30 03:00 → 2016-10-30 02:00

• 2016-10-30T02:55+02:00[Europe/Zurich]

• 2016-10-30T02:00+01:00[Europe/Zurich]

• 2016-10-30T02:05+01:00[Europe/Zurich]

Page 22: Java8 date-time-api-mit-postgre sql

TIMESTAMP WITH TIME ZONE

• PostgreSQL speichert als UTC

• originale Zeitzone nicht mehr verfügbar

Page 23: Java8 date-time-api-mit-postgre sql

neue Java Date Time API• seit Java SE 8

• inspiriert von Joda-Time

• viele Klassen, “Framework”

• Domain-driven Design

• keine spezifischen Typen für JDBC

• aka JSR-310

Page 24: Java8 date-time-api-mit-postgre sql

Java 8 API Date Time API

• relevant für ANSI SQL/JDBC

• LocalDate

• LocalTime

• LocalDateTime

• OffsetDateTime

Page 25: Java8 date-time-api-mit-postgre sql

LocalDate

• Datum ohne Zeit

• Jahr

• Monat

• Tag

• keine Zeit, keine Zeitzone → kein Zeitpunkt

Page 26: Java8 date-time-api-mit-postgre sql

LocalTime• Zeit ohne Datum

• Stunde

• Minute

• Sekunde

• Nanosekunde

• kein Datum, keine Zeitzone → kein Zeitpunkt

Page 27: Java8 date-time-api-mit-postgre sql

LocalDateTime

• Datum und Zeit

• Datum: LocalDate

• Zeit: LocalTime

• keine Zeitzone → kein Zeitpunkt

Page 28: Java8 date-time-api-mit-postgre sql

OffsetDateTime

• Zeitpunk

• LocalDateTime mit fixem Abstand zu GMT

• Datum: LocalDate

• Zeit: LocalTime

• Abstand

Page 29: Java8 date-time-api-mit-postgre sql

JDBC 4.2ANSI SQL Java SE 8

DATE LocalDate

TIME LocalTime

TIMESTAMP LocalDateTime

TIME WITH TIMEZONE OffsetTime

TIMESTAMP WITH TIMEZONE OffsetDateTime

Page 30: Java8 date-time-api-mit-postgre sql

Interval

• keine Entsprechung in Java 8 Date Time API

Page 31: Java8 date-time-api-mit-postgre sql

JDBC 4.2

• PreparedStatement#setObject(int, Object)

• ResultSet#getObject(int, Class)

• ResultSet#getObject(String, Class)

• keine Typenkonvertierung

Page 32: Java8 date-time-api-mit-postgre sql

#[sg]etObject• in JDBC spezifizierte Datentypen

• Postgres-Erweiterungen:

• PGobject: PGbox, PGcircle, PGinterval, PGline, PGlseg, PGmoney, PGpath, PGpoint, PGpolygon

• UUID

• InetAddress

Page 33: Java8 date-time-api-mit-postgre sql

CallableStatement

• Postgres Implementation von #getObject unterstützt nicht Java 8 Date Time API Typen

Page 34: Java8 date-time-api-mit-postgre sql

<<Beispiel>>

Page 35: Java8 date-time-api-mit-postgre sql

JdbcTemplate

• Spring ≥ 4.1

• Java 8 Datentypen für

• Bind-Parameter

• Rückgabe-Typen

• keine Typenkonvertierung

Page 36: Java8 date-time-api-mit-postgre sql

<<Beispiel>>

Page 37: Java8 date-time-api-mit-postgre sql

JPA

Java SE Java EE JDBC JPA

7 7 4.1 2.1

8 (8) 4.2 (2.2)

Page 38: Java8 date-time-api-mit-postgre sql

JPA 2.2

• Java 8 Date Time API Unterstützung geplant (JPA_SPEC-63)

• Fahrplan unklar

Page 39: Java8 date-time-api-mit-postgre sql

AttributeConverter

• erlauben Konvertierung von Basistypen auf beliebige Typen

• AttributeConverter haben keinen Zugriff auf ResultSet oder PreparedStatement

• OffsetDateTime nicht möglich

Page 40: Java8 date-time-api-mit-postgre sql

AttributeConverter

• Konvertierung über alte Datentypen

• selber schreiben

• diverse Open-source libraries

• com.github.marschall:threeten-jpa

• org.jadira.usertype:usertype.extended

Page 41: Java8 date-time-api-mit-postgre sql

Konvertierung über alte Datentypen

• kann aufgrund von Konvertierung über die lokale Zeitzone zu Problemen führen

• Zeit existiert in lokaler Zeitzone nicht

Page 42: Java8 date-time-api-mit-postgre sql

Hibernate

• 5.0.0: hibernate-java8 Modul

• 5.2.0: von Haus aus

• konvertiert über alte Datentypen (wie AttributeConverter)

Page 43: Java8 date-time-api-mit-postgre sql

Hibernate

• direkter Zugriff auf Java 8 Typen

• com.github.marschall:threeten-jpa-jdbc42-hibernate

• bringt auch OffsetDateTime Unterstützung

Page 44: Java8 date-time-api-mit-postgre sql

<<Beispiel>>

Page 45: Java8 date-time-api-mit-postgre sql

JPA Fazit

• proprietäre Hibernate API für beste Resultate

• OffsetDateTime nur mit Hibernate

• schlimmster Fall: gleiche Probleme wie bisher

• JVM in UTC kann helfen

Page 46: Java8 date-time-api-mit-postgre sql

Treiber-Version• ≥ 9.4.1208 / “JDBC42”

• nicht “jre7” oder “jre6”

• kein Zusammenhang zur Datenbank-Version

• https://jdbc.postgresql.org/download.html

• org.postgresql:postgresql

• nicht von Linux-Distribution

Page 47: Java8 date-time-api-mit-postgre sql

Code

https://github.com/marschall/pgday2016