英次郎の辞書データをOracleのテーブルに挿入する

#始めに
英次郎の辞書データをOracleのテーブルに挿入した時の手順を記載します
今回は辞書データの抽出からOracleDBのJavaからのアクセス周りを記載しています
辞書データからOracleDBにデータを投入する件は、次回の記事で記載します

#英次郎の辞書データをテキスト化する
##辞書データの抽出
[英辞郎からのSVL問題集の作り方](http://qiita.com/drafts/cd6d4e654e9c00de7e42/edit)を参考にテキストファイルを作成しました
ちなみに私は↓のように設定しています
![image.png](https://qiita-image-store.s3.amazonaws.com/0/136860/a4d6e220-45e0-f7b1-0222-34c5feee0d73.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/136860/ebccfd5e-3b35-43df-bcb7-fc35e2493b04.png)

上記のように設定したのは
- PDIC形式で出力すると単語レベルが表示されない
- CSV形式で出力すると行の途中で改行があった場合、プログラムの処理が煩雑になる
- ユーザー定義形式で出力するとHTML形式(XML形式)で出力が可能なので、テキストファイル処理が格段に楽になる。

ちなみに、私はHTMLファイル形式で出力し、Jsoupを使ってテキストファイル解析をしています

##抽出したデータの文字コード変換
抽出したテキストファイルを開くと

![image.png](https://qiita-image-store.s3.amazonaws.com/0/136860/3483521a-bab0-0656-865f-85cb0fea2667.png)

のように文字化けしています。
このままだと、Jsoupでうまく扱えない(いや、本当はあるのだろうけれど、面倒くさいから)ので、Javaで文字コードを変換するプログラムを作りました

```FileReadTest2.java
package file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class FileReadTest2 {

	private static String FILE_PATH ="C:/Users/***/Desktop/puisan_101.txt";
	private static String FILE_OUT_PATH ="C:/Users/***/Desktop/puisan_102.txt";
	
	public static void main(String args[]) throws Exception{
		BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream(FILE_PATH),"UTF-8"));
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FILE_OUT_PATH),"UTF-8"));
		reader.lines().forEach(s->fileWriter(s,writer));
		reader.close();
		writer.close();
	}
	
	public static void fileWriter(String s,BufferedWriter writer){
		try{
			writer.write(s);
			writer.newLine();
		}catch(IOException e){
			e.printStackTrace();
			throw new RuntimeException("ファイルの入出力でエラーが発生しました");
		}
	}
}
```

上記のプログラムを実行すると
![image.png](https://qiita-image-store.s3.amazonaws.com/0/136860/dcdaa4d7-af6e-deb1-3e07-95d1a868610b.png)
のように文字化けせず、HTMLファイルが作成されています

#DBのテーブル定義
orace12cにWORD_DICTIONARYというテーブルを作成し、以下の用な属性を定義しています

| 名前             |型              |説明      
|:-----------------|----------------|----------------
 WORD              |VARCHAR2(200)   |単語
 MEANING           |CLOB            |単語の和訳
 SHORT_VER         |VARCHAR2(2000)  |MEANINGの一部(2000バイト)を格納する 
 WORD_LEVEL        |VARCHAR2(20)    |単語レベル  
 WORD_INDEX        |UMBER(10)       |単語ごとに一意に割り振られる数字
 SEARCH_WORD       |VARCHAR2(200)   |検索用にwordを小文字変換したもの

#DBを操作するプログラム
Connection周りの処理を共通化したり、低レベルなinsert文の実装を行ったり、いまいち使いにくいQueryRunnerのbatchメソッドを拡張したりしています

```OperateDB.java
package word;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;

public class OperateDB {
    public static ThreadLocal<Connection> THREAD_LOCAL = new ThreadLocal<Connection>();

	//oracle12c からはSIDではなく、サービス名からつなぐ必要があるので、tns定義を全量書く必要がある		
	private static final String URL ="jdbc:oracle:thin:"		
			+ "@(DESCRIPTION=(ADDRESS = (PROTOCOL = TCP)"
			+ "(HOST = localhost)(PORT = 1521))"
			+ "(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME "
			+ "= triple_pb.co.jp)))";
	private static final String UID = "admin"; 
	private static final String PASS_WORD = "admin"; 
    
    
    public static void createConnection(){
    	try{
    		if(THREAD_LOCAL.get()==null){
    			Connection con = DriverManager.getConnection(URL, UID, PASS_WORD);
    			con.setAutoCommit(false);
    			THREAD_LOCAL.set(con);
    		}
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    }
    
    public static void closeConnection(){
    	try{
    		if(THREAD_LOCAL.get()!=null){
    			THREAD_LOCAL.get().close();
    		}
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    }
    
    public static void insert(List<Object[]> list,String sql){
    	try{
            new MyQueryRunner()			
            .batch(THREAD_LOCAL.get(), //コネクションの取得
            		sql, //実行するクエリ
            		list  //クエリに渡すパラメタ
      	     );    			
            THREAD_LOCAL.get().commit();
    	}catch(Exception e){
    		e.printStackTrace();
    		try{
           		THREAD_LOCAL.get().rollback();
    		}catch(SQLException ex){
    			ex.printStackTrace();
    		}
    	}
    }
    
     public static class MyQueryRunner extends QueryRunner{
    	 public int[] batch(Connection con,String sql,List<Object[]> list)throws SQLException{
    	    Object[][]params = new Object[list.size()][];
    	    for(int i=0; i<list.size();i++){
    	    	params[i] = list.get(i);
    	    }
    	    return super.batch(con,sql,params);
    	  }
      }
}