始めに
英次郎の辞書データをOracleのテーブルに挿入した時の手順を記載します
今回は辞書データの抽出からOracleDBのJavaからのアクセス周りを記載しています
辞書データからOracleDBにデータを投入する件は、次回の記事で記載します
英次郎の辞書データをテキスト化する
辞書データの抽出
英辞郎からのSVL問題集の作り方を参考にテキストファイルを作成しました
ちなみに私は↓のように設定しています


上記のように設定したのは
- PDIC形式で出力すると単語レベルが表示されない
 - CSV形式で出力すると行の途中で改行があった場合、プログラムの処理が煩雑になる
 - ユーザー定義形式で出力するとHTML形式(XML形式)で出力が可能なので、テキストファイル処理が格段に楽になる。
 
ちなみに、私はHTMLファイル形式で出力し、Jsoupを使ってテキストファイル解析をしています
抽出したデータの文字コード変換
抽出したテキストファイルを開くと
のように文字化けしています。
このままだと、Jsoupでうまく扱えない(いや、本当はあるのだろうけれど、面倒くさいから)ので、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("ファイルの入出力でエラーが発生しました");
		}
	}
}
上記のプログラムを実行すると

のように文字化けせず、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メソッドを拡張したりしています
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);
    	  }
      }
}
