RM-BLOG

IT系技術職のおっさんがIT技術とかライブとか日常とか雑多に語るブログです。* 本ブログに書かれている内容は個人の意見・感想であり、特定の組織に属するものではありません。/All opinions are my own.*

【java】Serializableについて2(改行を含むデータを出力する)

DBからデータを取得する(SELECTして結果をResultSetで受け取る)のは比較的簡単なので、 受け取った結果をStringにしてしまえばあとはBufferedWriter使って出力するのはそれほど難しくはない。
ただ、DBのほうに改行が入っているような場合、 CSVやTSV等、テキストファイルにしてしまうとその項目で1行ずれてしまって、結果的に出力状態が不正になる。
DBのデータをそのまま別DBに移植する場合等、 区分値や数値だけで構成された簡単なテーブル構造であればCSVやTSVにしてSQLLoaderするのが手軽なのだが こういうデータに関してはいちいちexpやexpdpを使って(いわゆるバイナリファイルにして)取り扱わないと別DBへの移植がしづらいという難点がある。
これを、JDBCを使った接続方式によるデータ取得の結果としてSerializableを併用することで自前のexpdpを実現する方法をメモとして残す。

 


Serializable実装クラスにおけるオブジェクト出力と読み込みの方式はここに書いてある通りである。
今回はSELECT結果の内部的な格納先としてjava.util.Listを使う。
このクラスはSerializableを実装しているのでソース冒頭でimportするだけでSerializableクラスとして使用できる。
ただしあまり詳細な情報の出力をするやり方ではない。
SELECT結果のデータ内容をただ単にバイナリ化(オブジェクトファイルに)して出力するという目的を実現しているだけに過ぎないからだ。
このやり方でもメタデータ等の情報を格納することもできるが、同じ考え方で対応する場合はjava.util.Mapのほうが柔軟な動きに対応できる。(ただその分出力容量は増えるだろう)

このプログラムは、

①「sql」フォルダ内のsqlを読み込んで実行し、ResultSetを取り出す

②結果の各項目をStringにしながらList<String>に格納(index=0にカラム名を格納)

③List<String>をオブジェクトファイルとして「sql_result」フォルダに出力

④上記③のファイルを読み込んで正しく出力できているか確認(標準出力)する

⑤上記③のファイルを読み込みつつ、insert用のクエリを用意する(※)

という動きを実現する。
(※)これはテスト的なロジックである。
 その理由は以下にある。
 1)insert先のテーブルが固定("TEST_LINE_CONTAINS_TABLE")である。
  SELECTの内容からいってもデータの取得先のテーブルが1つとは限らないし、
  当然そのテーブル名がTEST_LINE_CONTAINS_TABLEで固定であるわけもない。
  実際にはResultSetMetaData#getTableNameを使って
  ”テーブルが1種類なら” というような考慮が必要だろう。
  ③が”自作のexpdp”であるのに対し、⑤を”自前のimpdp”にしたかたった
   という程度の軽い気持ちから始めたロジックに過ぎない。
 2)あくまで「INSERT文を作るだけ(標準出力するだけ)であり、
  実際にinsert処理を実行するわけではない。
  なお、改行コードの変換(CRLF→chr(13)||chr(10)、LF→chr(10)、という具合のもの)については
  意識した実装を行っている。
  ただしそれ以外の部分はすべて文字列として扱うようにしており、
  日付形式の項目など、書式の整形は何も意識していないため、数値や文字以外のデータがある場合
  うまく動作する保証はない(実際、テストもしていない)

ちなみにコンパイルには「ojdbc.jar」が必要である。(筆者はojdbc5.jarにてコンパイル) このプログラムのテスト用に作ったテーブル「TEST_LINE_CONTAINS_TABLE」は以下のようなデータを保持する。

No STR
1 あいうえお
2 かきくけこ
3 さしすせそ たちつてと
4 なにぬねの はひふへほ まみめも

No3、およびNo4には「STR」項目に改行を含んでおり、 このデータをそのままテキストとして出力すると、ここで改行を起こしてしまうため出力結果がよろしくない状態になる。
これをオブジェクトファイルとして改善している。
実際の実行結果は以下の通りになる↓ Serializable2_Test.jpg