こんにちは。ゆうせいです。

今回は、新人エンジニア研修でも大人気のテーマ「JavaのLocalDateTimeとMySQLのDATETIME型を連携させる方法」について、超わかりやすく解説していきます!

「Javaから日時を保存したいんですけど、どう書けばいいの?」
「MySQLで日時のカラムってどうやって作るの?」
…そんな疑問を、丁寧に解決していきましょう!


JavaとMySQLの日時型、何を使えばいいの?

Javaで使う型MySQLで対応する型
LocalDateTimeDATETIME

この組み合わせが最もシンプルかつ実用的です!


MySQLのDATETIME型とは?

特徴まとめ

特性内容
格納する情報年・月・日・時・分・秒
書式'YYYY-MM-DD HH:MM:SS'(例:2023-06-11 15:30:45
対応範囲1000年~9999年まで
タイムゾーンサーバー設定に依存(JSTなど)
よく使うオプションCURRENT_TIMESTAMP で自動挿入・更新可能

テーブル作成例

CREATE TABLE datetime_test (
  id INT PRIMARY KEY AUTO_INCREMENT,
  post VARCHAR(4000),
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

ここでは、データが追加・更新された時点の日時を自動記録しています。


JavaのLocalDateTimeとは?

LocalDateTime は、Java 8以降で導入された日時型のひとつで、日付+時刻の情報を保持できます。

LocalDateTime now = LocalDateTime.now();  // 現在日時の取得

この型を使えば、MySQLのDATETIMEカラムとほぼそのまま対応可能なんです!


実践!JavaからMySQLに日時を保存&取得するコード

import java.sql.*;
import java.time.LocalDateTime;

public class MySQLDatetimeExample {

    public static final String CONNECT_STRING = "jdbc:mysql://localhost:3306/sip_b?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B9";
    public static final String USERID = "newuser";
    public static final String PASSWORD = "0";

    public static void main(String[] args) {
        try (Connection con = DriverManager.getConnection(CONNECT_STRING, USERID, PASSWORD)) {

            LocalDateTime now = LocalDateTime.now();  // 現在日時の取得

            saveDateTime(con, now);  // データベースに保存
            LocalDateTime savedDateTime = getDateTime(con);  // データベースから取得

            System.out.println("保存された日時: " + savedDateTime);

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static void saveDateTime(Connection conn, LocalDateTime dateTime) throws SQLException {
        String query = "INSERT INTO datetime_test (post, created_at) VALUES (?, ?)";
        try (PreparedStatement stmt = conn.prepareStatement(query)) {
            stmt.setString(1, "おはようございます。");
            stmt.setObject(2, dateTime);  // LocalDateTimeを直接セット!
            stmt.executeUpdate();
        }
    }

    private static LocalDateTime getDateTime(Connection conn) throws SQLException {
        String query = "SELECT created_at FROM datetime_test ORDER BY created_at DESC LIMIT 1";
        try (PreparedStatement stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery()) {
            if (rs.next()) {
                return rs.getObject(1, LocalDateTime.class);  // 直接取得!
            }
        }
        return null;
    }
}

解説ポイント

処理使用技術解説
挿入setObject()LocalDateTimeをそのままセットできる
取得getObject(列番号, LocalDateTime.class)そのままJavaの日時型で受け取れる
接続文字列serverTimezone=GMT%2B9JSTで扱うための設定(+9時間)

MySQL側で日時を操作するTips集

1. 日時の加算

UPDATE datetime_test SET updated_at = updated_at + INTERVAL 1 HOUR;

→ 全行のupdated_atを1時間進める


2. 日時の差分

SELECT TIMESTAMPDIFF(SECOND, created_at, updated_at) AS second_diff FROM datetime_test;

→ 2つの日時の秒数差を取得


3. 日付・時間の抽出

SELECT DATE(created_at), TIME(created_at) FROM datetime_test;

→ 日付部分だけ or 時刻部分だけを取り出せます


4. フォーマット変換

SELECT DATE_FORMAT(created_at, '%Y-%m-%d %H') AS formatted FROM datetime_test;

→ 例:2023-06-13 04 のようにカスタム表示


よくあるトラブルと対策

トラブル原因対策
時間がズレるタイムゾーン不一致JDBC URL に serverTimezone=GMT%2B9 を追加
LocalDateTimeが渡せないJDBCドライバ古いJava 8以降 & 対応JDBCドライバを使う
自動で更新されないON UPDATE CURRENT_TIMESTAMPが未指定テーブル定義を見直す

まとめ

  • Javaでは LocalDateTime、MySQLでは DATETIME を使うのが基本!
  • JDBCでは setObject / getObject を使えばシンプルに扱える
  • MySQLのDATETIMEには便利な演算や関数が多数ある
  • タイムゾーンとフォーマットの違いに注意!

今後の学習の指針

  • ZonedDateTime, Timestamp との違いも学ぼう
  • java.time.format.DateTimeFormatter を使って任意の表示形式に変換してみよう
  • MySQLのタイムゾーン設定を確認・変更して、実験してみよう
  • MyBatisやJPAなどフレームワークでの日時の扱い方にも触れてみよう!

日時はアプリ開発で頻出の要素なので、早めに得意分野にしておくと武器になりますよ!
それでは、また次の研修でお会いしましょう!

最後までお読みいただきありがとうございます。