By Takayuki Kobayashi 2011年12月8日 Leave a Comment

opencsv

大量データのテストを行うために、データの登録を行う必要がある。だいたい、そういうツールを作ってサーバ側でシェルで起動して実行する、というのがこれまでのケース。
これをもっと簡単にできないかと常々考えていたところ、簡単で気軽なライブラリであるOpenCsvがあったので使ってみた。


実は Play! Advent Calendar 12/13 で使うネタの一部です。全部紹介しきれないので、部分的に切り出しました。

環境

・MacOSX 10.7
・java 6
・Play! 1.2.3
・opencsv 2.3 <download>

処理の流れ

1.モデルの定義
2.データの準備
3.データ取り込み用のプログラム作成
4.実行テスト

ではやってみよう。

  1. モデルの定義
    大量データは「なんちゃって個人情報」のデータを登録できるようにするため、このモデルを作成する。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    package models;
     
    import javax.persistence.Entity;
    import play.db.jpa.Model;
     
    @Entity
    public class Customer extends Model {
    	public	String	name;    // 名前
    	public	String	kana;    // ふりがな
    	public	String	address;    // あどれす
    	public	String	sex;    // 性別
    	public	String	age;    // 年齢
    	public	String	birth;    // 誕生日
    	public	String	married;    // 結婚
    	public	String	bloodtype;    // 血液型
    	public	String	pref;    // 都道府県
    	public	String	tel;    // 電話番号
    	public	String	mobile;    // 携帯番号
    	public	String	carrer;    // キャリア
    }

    なぜフィールドがpublicなのか?と言う突っ込みはスルーです。

  2. データの準備
    なんちゃって個人情報」で、

    • 出力形式: csv
    • 出力数: 5000件(最大)
    • オプション: すべて選択

    として、「なんちゃって生成」ボタンを押します。そうしますとCSVファイルがダウンロードされます。
    内容はこんな感じ。名前に「サンタマリア」とかあり、どうも有名人の名前を使っているようです。^^

    1
    2
    3
    4
    5
    6
    
    名前,ふりがな,アドレス,性別,年齢,誕生日,婚姻,血液型,都道府県,電話番号,携帯,キャリア,カレーの食べ方
    中井 咲,なかい さき,nakai_saki@example.com,女,54,1957/10/24,既婚,A型,千葉県,053-846-7134,080-2654-2943,au,ぶっかけ・ルー攻め派
    本山 ケンイチ,ほんやま けんいち,honnyama_kenichi@example.com,男,51,1960/4/13,既婚,A型,埼玉県,072-565-2645,080-6246-2056,ドコモ,左ルー・せき止め派
    平林 俊二,ひらばやし しゅんじ,hirabayashi_shunji@example.com,男,59,1951/12/24,既婚,B型,愛知県,071-128-6201,090-5791-4311,au,ぶっかけ・別口派
    菊田 小百合,きくた さゆり,kikuta_sayuri@example.com,女,28,1983/4/18,未婚,A型,群馬県,067-842-2826,080-4329-1012,ソフトバンク,左ルー・別口派
    ...

    また、データベースを UTF-8 で作成しているため、テキストエディタなどで Shift_JIS で作成している物を UTF-8 へ変換します。これでデータの準備できました。

  3. データ取り込み用のプログラム作成
    少しコード量が多いかな。これでCSVファイルを読み込んだ後、データベースへ1件ずつ保存しています。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    public static void loadCsv() throws Exception {
    	CSVReader reader = new CSVReader(new FileReader("./test/dummy.csv"), ',', '"', 	2);
    	ColumnPositionMappingStrategy strat = new ColumnPositionMappingStrategy();
    	strat.setType(Customer.class);
     
    	Field[]		fs = Customer.class.getFields();
    	String[]	columns = new String[fs.length];
    	int	i=0;
    	for(Field f : fs) {
    		if("id".equals(f.getName())||"willBeSaved".equals(f.getName()))	continue;
        		columns[i++] = f.getName();
        		Logger.info("colmun : "+columns[i-1]);
        	}
        	strat.setColumnMapping(columns);
     
    		CsvToBean csv = new CsvToBean();
        	List list = csv.parse(strat, reader);
        	for(Customer c : list) {
        		c.save();
        		Logger.info("Customer : " + c);
        	}
     
    	render();
    }

    実は CsvToBeanクラスがあまり賢くなく、String,int しか対応していません。java.lang.Date とかあると、エラーとなってしまいます。ここはしっかりと実装されている Play! の bind を使う方がよいかもしれませんね。

  4. 実行テスト
    実行速度はデータベースに依存しますが、取り急ぎ正常に取り込まれることを確認できました。
    まぁ、フィールドはすべて文字列型なので誤って取り込まれたり、エラーになることは想定しませんでした。

参考サイト

まとめ

取り込みデータ件数が多い場合は RDBMS のツールで取り込んだ方が圧倒的に早い。
ただし、SQL文を作る必要があるので、ここはトレードオフ。
Play! で async があるので、CPU がいっぱいある場合は、並列処理しても面白いかもしれませんね。




Sorry, the comment form is closed at this time.

Sorry, the comment form is closed at this time.