なみひらブログ

学んだことを日々記録する。~ since 2012/06/24 ~

MySQL Connector/JがJava8で追加された日付型をサポートしていた話

背景

JavaからMySQLを使う際にJava8で追加された日付型が使えるか試した結果をメモっときます。
Java8で追加された日付型というのは"LocalDateTime"とか。

結論

Java8で追加された日付型がMySQL Connector/Jのバージョン5.1.37でサポートされたので、それ以降のバージョンなら普通に使える。

Support for JDBC 4.2


Connector/J now provides implementations for pretty much all new JDBC 4.2 methods, namely for large update counts and max rows support.


The other big change is the support for the new temporal classes from java.time package. LocalDate, LocalDateTime, LocalTime are fully supported and can now be used in the multiple versions of setObject(...) and getObject(...) methods. (以下、略)

試す

前提

  • MySQLのテーブルのカラムの型はDATETIME型
    • 簡単なユーザテーブル
CREATE TABLE Users
(
	id int NOT NULL AUTO_INCREMENT,
	createdAt datetime NOT NULL,
	PRIMARY KEY (id),
	UNIQUE (id)
);
@Data
public class UserDto {
    private int id;
    private LocalDateTime createdAt;
}
  • DAOは以下のような感じ
    • SpringFrameworkベース
public class UserDao {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    public int insert(final UserDto dto){
        return jdbcTemplate.update("INSERT INTO Users (createdAt) VALUES (:createdAt)",
                                   new BeanPropertySqlParameterSource(dto));
    }
  • テストコード
    • userDaoはspringでDI初期化
public class UserDaoTest {

    @Autowired
    private UserDao userDao;

    @Test
    public void test_insert(){
        // setup
        final UserDto dto = new UserDto();
        dto.setCreatedAt(LocalDateTime.now());

        // action
        userDao.insert(dto);

        // check
        // - no Exception
    }

サポートされていないバージョン(5.1.36)で実行してみる

例外発生した。

org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO Events (createdAt) VALUES (?) ]; Data truncation: Incorrect datetime value: '\xAC\xED\x00\x05sr\x00\x0Djava.time.Ser\x95]\x84\xBA\x1B"H\xB2\x0C\x00\x00xpw\x0E\x05\x00\x00\x07\xDF\x0C\x14\x0A\x107\x19E\xBA\' for column 'createdAt' at row 1; nested exception is com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '\xAC\xED\x00\x05sr\x00\x0Djava.time.Ser\x95]\x84\xBA\x1B"H\xB2\x0C\x00\x00xpw\x0E\x05\x00\x00\x07\xDF\x0C\x14\x0A\x107\x19E\xBA\' for column 'createdAt' at row 1
	at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:102)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:645)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:866)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:890)
	at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:287)
	(中略)
Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '\xAC\xED\x00\x05sr\x00\x0Djava.time.Ser\x95]\x84\xBA\x1B"H\xB2\x0C\x00\x00xpw\x0E\x05\x00\x00\x07\xDF\x0C\x14\x0A\x107\x19E\xBA\' for column 'createdAt' at row 1
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3845)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2447)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2594)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1901)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2113)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2049)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2034)
	at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:873)
	at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:866)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629)
	... 34 more

サポートされていないバージョン(5.1.37)で実行してみる

例外も発生せず、正しくデータ登録できた。

まとめ

知らない/気付かないところで使いやすくなっている(´Д`)
changelogの"It is also the first release of MySQL Connector/J to support the Java Database Connectivity (JDBC) 4.2 API."だけでは気づかない(;´Д`)