Java time types sql

JDBC — Data Types

The JDBC driver converts the Java data type to the appropriate JDBC type, before sending it to the database. It uses a default mapping for most data types. For example, a Java int is converted to an SQL INTEGER. Default mappings were created to provide consistency between drivers.

The following table summarizes the default JDBC data type that the Java data type is converted to, when you call the setXXX() method of the PreparedStatement or CallableStatement object or the ResultSet.updateXXX() method.

SQL JDBC/Java setXXX updateXXX
VARCHAR java.lang.String setString updateString
CHAR java.lang.String setString updateString
LONGVARCHAR java.lang.String setString updateString
BIT boolean setBoolean updateBoolean
NUMERIC java.math.BigDecimal setBigDecimal updateBigDecimal
TINYINT byte setByte updateByte
SMALLINT short setShort updateShort
INTEGER int setInt updateInt
BIGINT long setLong updateLong
REAL float setFloat updateFloat
FLOAT float setFloat updateFloat
DOUBLE double setDouble updateDouble
VARBINARY byte[ ] setBytes updateBytes
BINARY byte[ ] setBytes updateBytes
DATE java.sql.Date setDate updateDate
TIME java.sql.Time setTime updateTime
TIMESTAMP java.sql.Timestamp setTimestamp updateTimestamp
CLOB java.sql.Clob setClob updateClob
BLOB java.sql.Blob setBlob updateBlob
ARRAY java.sql.Array setARRAY updateARRAY
REF java.sql.Ref SetRef updateRef
STRUCT java.sql.Struct SetStruct updateStruct

JDBC 3.0 has enhanced support for BLOB, CLOB, ARRAY, and REF data types. The ResultSet object now has updateBLOB(), updateCLOB(), updateArray(), and updateRef() methods that enable you to directly manipulate the respective data on the server.

The setXXX() and updateXXX() methods enable you to convert specific Java types to specific JDBC data types. The methods, setObject() and updateObject(), enable you to map almost any Java type to a JDBC data type.

ResultSet object provides corresponding getXXX() method for each data type to retrieve column value. Each method can be used with column name or by its ordinal position.

SQL JDBC/Java setXXX getXXX
VARCHAR java.lang.String setString getString
CHAR java.lang.String setString getString
LONGVARCHAR java.lang.String setString getString
BIT boolean setBoolean getBoolean
NUMERIC java.math.BigDecimal setBigDecimal getBigDecimal
TINYINT byte setByte getByte
SMALLINT short setShort getShort
INTEGER int setInt getInt
BIGINT long setLong getLong
REAL float setFloat getFloat
FLOAT float setFloat getFloat
DOUBLE double setDouble getDouble
VARBINARY byte[ ] setBytes getBytes
BINARY byte[ ] setBytes getBytes
DATE java.sql.Date setDate getDate
TIME java.sql.Time setTime getTime
TIMESTAMP java.sql.Timestamp setTimestamp getTimestamp
CLOB java.sql.Clob setClob getClob
BLOB java.sql.Blob setBlob getBlob
ARRAY java.sql.Array setARRAY getARRAY
REF java.sql.Ref SetRef getRef
STRUCT java.sql.Struct SetStruct getStruct
Читайте также:  Javascript create use element

Date & Time Data Types

The java.sql.Date class maps to the SQL DATE type, and the java.sql.Time and java.sql.Timestamp classes map to the SQL TIME and SQL TIMESTAMP data types, respectively.

Following example shows how the Date and Time classes format the standard Java date and time values to match the SQL data type requirements.

import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; import java.util.*; public class SqlDateTime < public static void main(String[] args) < //Get standard date and time java.util.Date javaDate = new java.util.Date(); long javaTime = javaDate.getTime(); System.out.println("The Java Date is:" + javaDate.toString()); //Get and display SQL DATE java.sql.Date sqlDate = new java.sql.Date(javaTime); System.out.println("The SQL DATE is: " + sqlDate.toString()); //Get and display SQL TIME java.sql.Time sqlTime = new java.sql.Time(javaTime); System.out.println("The SQL TIME is: " + sqlTime.toString()); //Get and display SQL TIMESTAMP java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(javaTime); System.out.println("The SQL TIMESTAMP is: " + sqlTimestamp.toString()); >//end main >//end SqlDateTime

Now let us compile the above example as follows −

When you run JDBCExample, it produces the following result −

C:\>java SqlDateTime The Java Date is:Tue Aug 18 13:46:02 GMT+04:00 2009 The SQL DATE is: 2009-08-18 The SQL TIME is: 13:46:02 The SQL TIMESTAMP is: 2009-08-18 13:46:02.828 C:\>

Handling NULL Values

SQL’s use of NULL values and Java’s use of null are different concepts. So, to handle SQL NULL values in Java, there are three tactics you can use −

  • Avoid using getXXX( ) methods that return primitive data types.
  • Use wrapper classes for primitive data types, and use the ResultSet object’s wasNull( ) method to test whether the wrapper class variable that received the value returned by the getXXX( ) method should be set to null.
  • Use primitive data types and the ResultSet object’s wasNull( ) method to test whether the primitive variable that received the value returned by the getXXX( ) method should be set to an acceptable value that you’ve chosen to represent a NULL.

Here is one example to handle a NULL value −

Источник

Работа со временем

Со времен, когда придумали JDBC и стандартизировали его интерфейсы, прошло лет 20, и за это время много чего изменилось.

Во-первых, мир стал глобальным и теперь один сервер может обслуживать пользователей со всего мира. Скорость интернета порешала. Поэтому в SQL был добавлен еще один тип данных для работы со временем. Теперь типы выглядят вот так:

  • DATE – хранит дату: год, месяц, день.
  • TIME – хранит время: часы, минуты, секунды.
  • TIMESTAMP – хранит конкретный момент времени: дата, время и миллисекунды.
  • TIMESTAMP WITH TIME ZONE – TIMESTAMP и временная зона (имя зоны или смещение).
Читайте также:  Css image blending mode

Во-вторых, в Java появился DateTime API для глобальной работы со временем. В нем появились такие классы:

  • Дата и время:
    • LocalDate
    • LocalTime
    • java.time.Instant
    • java.time.LocalDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime

    Третий интересный момент состоит в том, что очень многим SQL-клиентам хотелось бы получать время с сервера уже в своей локальное зоне . Преобразовывать время на лету конечно можно, но это не удобно, да и ошибки бывают.

    Например, я хочу получить из базы все задания на сегодня. У SQL-сервера есть функция CURDATE() для этого дела. Только вот сервер находится в США, а я – в Японии. И хотелось бы чтобы он мне вернул все записи за “мое сегодня”, а не “его сегодня”.

    В общем, SQL-сервер тоже должен уметь по-умному работать с клиентами в разных временных зонах.

    Современные проблемы требуют современных решений

    В принципе, новые типы из Java DateTime API и типы из SQL можно удобно сопоставлять. Для того чтобы представить тип DATE в Java нужно использовать класс java.time.LocalDate из JDK 8 DateTime API.

    Тип TIME из базы данных можно представить двумя типами из Java: java.time.LocalTime и java.time.OffsetTime . Тоже ничего сложного.

    Конкретный момент времени, представленный типом TIMESTAMP в базе, в Java можно представить 4 типами:

    • java.time.Instant
    • java.time.LocalDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime

    Ну, и наконец, TIMESTAMP WITH TIME ZONE можно представить двумя типами:

    Так как ты уже знаком с DateTime API, то запомнить это дело тебе труда не составит 🙂

    Запишу в виде таблицы, так будет проще:

    SQL TYPE Java Type
    DATE java.time.LocalDate
    TIME java.time.LocalTime
    java.time.OffsetTime
    TIMESTAMP java.time.Instant
    java.time.LocalDateTime
    java.time.OffsetDateTime
    java.time.ZonedDateTime
    TIMESTAMP WITH TIME ZONE java.time.OffsetDateTime
    java.time.ZonedDateTime

    Получение даты

    У меня для тебя хорошая новость. Первая за долгое время. Мы можем обойти ограничение метода getDate() , который возвращает тип java.sql Date.

    Дело в том, что у объекта ResultSet есть еще один интересный метод — getObject() . Этот метод принимает два параметра: колонку и тип, и возвращает значение колонки, преобразованное к заданному типу. Общий вид метода такой:

     ИмяКласса имя = getObject(column, ИмяКласса);

    И если вы хотите преобразовать тип DATE к типу java.time.LocalDate , то нужно написать что-то типа:

     LocalDate localDate = results.getObject(4, LocalDate.class); 

    А любой TIMESTAMP вообще можно преобразовать к куче типов:

     java.time.Instant instant = results.getObject(9, java.time.Instant.class); java.time.LocalDateTime local = results.getObject(9, java.time. LocalDateTime.class); java.time.OffsetDateTime offset = results.getObject(9, java.time. OffsetDateTime.class); java.time.ZonedDateTime zoned = results.getObject(9, java.time. ZonedDateTime.class); 

    Важно! Этот код не будет работать если у вас устаревший MySQL JDBC Driver . Обрати внимание на версию “mysql-connector-java”, прописанную в твоем pom.xml, или добавленную в Libraries в настройках проекта.

    Кстати, таким же способом можно обойти и невозможность хранить null у примитивных типов. Если колонка таблицы имеет тип INT, то есть пара способов получить из нее null. Смотри пример ниже:

     Integer id1 = results.getObject(8, Integer.class); //так будет работать Integer id2 = results.getObject(8, int.class); //так тоже будет работать int id3 = results.getObject(8, Integer.class); //метод вернет null, JVM кинет NPE int id4 = results.getObject(8, int.class); //метод вернет null, JVM кинет NPE 

    Настройка часового пояса в MySQL

    С MySQL тоже произошло много всего интересного. Как ты знаешь, при создании соединения с MySQL к нему можно добавлять различные параметры:

    mysql://localhost:3306/db_scheme?имя=значение&имя=значение 

    Так вот, для работы с временными зонами в MySQL добавили три параметра. Эти параметры ты можешь передавать, когда устанавливаешь соединение с сервером.

    Ниже я приведу таблицу с ними:

    Параметр Значения Значение по умолчанию
    connectionTimeZone LOCAL | SERVER | user-zone SERVER
    forceConnectionTimeZoneToSession true | false true
    preserveInstants true | false false

    С помощью параметра connectionTimeZone мы выбираем временную зону (часовой пояс), в котором будут выполняться все запросы. С точки зрения клиента, сервер работает в указанной временной зоне.

    Параметр forceConnectionTimeZoneToSession заставляет игнорировать переменную time_zone сессии и заменить ее на connectionTimeZone.

    И наконец параметр preserveInstants управляет преобразование точного-момента-времени между JVM timeZone и connectionTimeZone.

    Самые частые конфигурации такие:

    • connectionTimeZone=LOCAL & forceConnectionTimeZoneToSession=false — соответствует старому MySQL JDBC драйверу версии 5.1 с параметром useLegacyDatetimeCode=true.
    • connectionTimeZone=LOCAL & forceConnectionTimeZoneToSession=true — новый режим, обеспечивающий наиболее естественный способ обработки значений даты и времени.
    • connectionTimeZone=SERVER & preserveInstants=true — соответствует старому MySQL JDBC драйверу версии 5.1 с параметром useLegacyDatetimeCode=false.
    • connectionTimeZone=user_defined & preserveInstants=true — помогает преодолеть ситуацию, когда часовой пояс сервера не может быть распознан коннектором, потому что он установлен как общая аббревиатура, такая как CET/CEST.

    Да, даты — тема интересная и проблем с ними много. Как говорится: это конечно страшно, но и я не сыкло! 🙂

    Источник

Оцените статью