m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

JavaでクラスをシリアライズしてDBへ保存

まあ、なんかの役に立つかもしれない

クラスをデータ化して保存する

環境

MySQL
Java8

テーブル定義

mysql> create table obj_data(
    ->   id integer not null auto_increment,
    ->   data blob,
    ->   create_at datetime,
    ->   update_at datetime,
    ->   primary key(id)
    -> );
Query OK, 0 rows affected (0.02 sec)

対象オブジェクト

package sample_mysql03;

import java.io.Serializable;

public class Item implements Serializable{
	
	private static final long serialVersionUID = 1L;
	private String name;
	private String price;
	private String remarks;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPrice() {
		return price;
	}
	public void setPrice(String price) {
		this.price = price;
	}
	public String getRemarks() {
		return remarks;
	}
	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}
}

※Serializableが必要です。

追加処理

package sample_mysql03;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;

public class Sample01 {

	// 接続情報
	private static final String URL = "jdbc:mysql://192.168.33.10/myapp?useSSL=false";
	private static final String USER = "app";
	private static final String PASS = "Password123@";
	
	public static void main(String[] args) throws IOException {
		
		System.out.println("start");
		
		try (
				Connection con = DriverManager.getConnection(URL, USER, PASS);
				Statement st = con.createStatement();
				){
			
			// オブジェクト生成
			Item item = new Item();
			item.setName("hoge");
			item.setPrice("hoge");
			item.setName("bikoaaaaaaaa");
			
			String sql = null;
			PreparedStatement pstmt = null;
			int result;
			
			// プリペアードステートメント
			sql = "insert into obj_data(data, create_at) values(?, ?);";
			pstmt = con.prepareStatement(sql);
			
			// オブジェクトを出力するストリームをくみ上げる
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(item);
			
			ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		    
			// ステートメントにパラメータを入れる
			pstmt.setBinaryStream(1, bais, baos.toByteArray().length);
			pstmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
			result = pstmt.executeUpdate();
			System.out.println("処理結果=" + result);
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("end");

	}

}

mysql> select * from obj_data;                                                                                        +----+-------------------------------------------------------------------------------------------------------------------------+---------------------+-----------+
| id | data                                                                                                                    | create_at           | update_at |
+----+-------------------------------------------------------------------------------------------------------------------------+---------------------+-----------+
|  1 | �� sr sample_mysql03.Item        L namet Ljava/lang/String;L priceq ~ L remarksq ~ xpt
                                                                                              bikoaaaaaaaat hogep   | 2016-12-04 16:27:06 | NULL      |
+----+-------------------------------------------------------------------------------------------------------------------------+---------------------+-----------+
1 row in set (0.00 sec)

mysql>

なんかそれっぽいデータが入っている。

読み込み

package sample_mysql04;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import sample_mysql03.Item;

public class Sample02 {

	// 接続情報
	private static final String URL = "jdbc:mysql://192.168.33.10/myapp?useSSL=false";
	private static final String USER = "app";
	private static final String PASS = "Password123@";
	
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		
		System.out.println("start");
		
		try (
				Connection con = DriverManager.getConnection(URL, USER, PASS);
				Statement st = con.createStatement();
				){
			
			
			String sql = null;
			PreparedStatement pstmt = null;
			
			// プリペアードステートメント
			sql = "select * from obj_data where id = ?";
			pstmt = con.prepareStatement(sql);
			
			// パラメータ指定
			pstmt.setInt(1 , 2);
			
			Item item;
			
			// 実行
			ResultSet rs = pstmt.executeQuery();
			while(rs.next()){
				InputStream is = rs.getBinaryStream("data");
				ObjectInputStream obis = new ObjectInputStream(is);
				item = (Item) obis.readObject();
				
				System.out.println(item.getName() + "" + item.getPrice() + "" + item.getRemarks());
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("end");

	}

}

start
name1price222bikobikobiko
end

できました(^^)

わかったこと

  • 対象のクラス(オブジェクト)にはSerializableを指定する必要がある。
  • パッケージ名も保存されるので他のパッケージの同じ名前のクラスはエラーとなる
  • 結構めんどくさい(´・ω・`)

です