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
できました(^^)
参考
(・ω・)Serendipity ::: Light in Moment - 14
4. ラージオブジェクト | TECHSCORE(テックスコア)
備忘録的なblog: OracleのBLOBにJavaオブジェクトを保存
わかったこと
- 対象のクラス(オブジェクト)にはSerializableを指定する必要がある。
- パッケージ名も保存されるので他のパッケージの同じ名前のクラスはエラーとなる
- 結構めんどくさい(´・ω・`)
です