JSPでMySQLのデータベースにINSERT文で日付型を追加する時の注意点

Webアプリケーションでユーザーの登録や情報を変更したときの管理を行う場合にはDATETIME型を利用することがあります。
ですがJavaアプリケーションからSQL文のINSERTで追加する場合にJavaでの日時の取得の形式とSQLとで違いがあり少し手こずることがあります。

 
そこで今回はJavaプログラムをHTMLに埋め込むことができるJSPでMySQLのデータベースにINSERT文でDATETIME型を追加する方法をご紹介していきます。

 
サンプルとしてテーブルの構造は以下のようにユーザーの情報を管理するとして自動連番でのidからname、email、そして登録や更新した日時を管理するためcreated、modifiedといった構造でお話ししていきます。

MySQLのデータベースの構造

 
DATETIME型を設定することで日付から時間から秒までを表示します。

データベースのDATETIME型

 
このSQLのDATETIME型にJavaアプリケーション側が合わせてあげて追加する必要があります。

それではどんな感じかみていきましょう。

 

INSERT文でDATETIME型を追加する

入力側をinput.jsp、受け取る側をoutput.jspとしてお話しを進めていきます。

例えばサンプルとして以下のように入力フォームを作っておきます。
入力フォームがあるページは別にJSPファイルではなくHTMLファイルでも良いですが、JSPの話なので一応JSPファイルでいきます。
HTMLのformタグとinputタグを使って入力フォームを構築します。

input.jsp

<div>
  <form method="post" action="output.jsp">
    名前: <input type="text" name="name" size=20><br>
    メールアドレス: <input type="text" name="email" size=30><br>
    <input type="submit" value="OK">
  </form>
</div>

 
formタグにmethod属性でpost送信として、action属性でページの飛び先をoutput.jspとします。
inputタグで名前とメールアドレスを入力する部分をtype属性のtextで用意して、name属性で入力した値をその名前で送信します。
size属性は入力部分のサイズです。名前やメールアドレスがだいたい入る幅のサイズに調整します。
最後のinputタグはtype属性をsubmitとして、フォームの値を送信するボタンを作成します。ボタンに表示させるテキストをvalue属性でOKとしておきます。

 
完成した入力フォームから名前とメールアドレスを入力して、output.jspに値を送信します。

 

そして値を受け取る側で入力した値を受け取り、さらにDATETIME型の日付をデータベースに追加してみます。

まずは1行目のJSPファイルの設定から上部部分で値を受け取ります。

 
output.jsp

<%@ page import="java.sql.*" contentType="text/html; charset=UTF-8" language="java" %>

<%
request.setCharacterEncoding("UTF-8");

// パラメータを取得
String name = request.getParameter("name");
String email = request.getParameter("email");
%>

 
データベース操作を行うのでディレクティブタグで「java.sql.*」とsqlを操作するパッケージをインポートをするのを忘れずに。
request.setCharacterEncodingで文字コードをUTF-8に、request.getParameterでnameとemailのパラメータを受け取り、それぞれ変数に格納しておきます。

 
そして、データベースに接続して受け取った値をSQLのINSERT文でレコードを追加していきます。
接続するデータベース名はprojectでユーザー名とパスワードはrootという流れで説明していきます。

 
output.jsp

<%
try {
  Class.forName("com.mysql.jdbc.Driver"); //JDBCドライバを登録
  Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/project?" +
    "user=root&password=root&useUnicode=true&characterEncoding=utf-8"); //データベース接続

  String query="INSERT INTO first (name, email, created, modified) VALUES (?, ?, ?, ?)";
  PreparedStatement stmt = conn.prepareStatement(query);
  stmt.setString(1, name);
  stmt.setString(2, email);
  stmt.setDate(3, new java.sql.Date(new java.util.Date().getTime()));
  stmt.setDate(4, new java.sql.Date(new java.util.Date().getTime()));
  int inserted = stmt.executeUpdate();

  conn.close();

} catch (Exception e) {
  e.printStackTrace();
}
%>

 
データベースに接続した後、変数queryにSQL文を格納します。
ここでのINSERT文のVALUESは受け取った値を入れるために「?」としておきます。
PreparedStatementオブジェクトを利用してqueryを実行出来るようにして、stmt.setStringstmt.setDateでVALUESの値の数を順番に設定します。
感覚としては「?」に順番に値をはめ込むイメージです。

「stmt.setString(1, name)」のように番号を振って変数を呼び出していくのですが、setDateとして日付型を扱う時は注意が必要でjava.util.Dateオブジェクトで取得する日時の形式がSQLのDATETIME型にうまくはまらないため変換する必要があります。そのままjava.util.Dateで日時を取得して追加しようとしてもエラーがでます。

いろんな変換方法があるのですが、一番シンプルで簡単なのがnew java.util.Date().getTime()でインスタンスを生成しjava.sql.Dateオブジェクトとして変換してあげる方法です。

 

これでうまくデータベースにDATETIME型で追加することができます。
普通に文字列をINSERT文で追加する場合はあまり手こずらないですが、DATETIME型を扱う場合はSQLに対応するように変換する必要がありますのでご注意ください。