1. 程式人生 > >Java將檔案中的內容轉換為sql語句(和併發定時讀取檔案)

Java將檔案中的內容轉換為sql語句(和併發定時讀取檔案)

資料檔案內容data.txt

{USER_TYPE=1,CREATE_USER=ZHANG,UPDATE_USER=li,OPER_NUM=D001,SRC=2,UPDATE_TIME=2018-11-11 18:08:08.0,TABLE_NUM=T17,OPTIONS=FIND,PRIMARY_Key=dfewew7e-6hs3-j2j3-de9232jh,PHONE=1818111888,STATUS=1,MODES=1,VERSION=1,CREATE_TIME=2018-11-11 18:08:08,remark=null}

單次讀取示例程式碼:

package java_demo;
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class SQL_FORMAT { public static void main(String[] args) { /** * 單行資料格式(類似),欄位數量不固定,約10萬條 * {USER_TYPE=1,CREATE_USER=ZHANG,UPDATE_USER=li,OPER_NUM=D001,SRC=2,UPDATE_TIME=2018-11-11 18:08:08.0,TABLE_NUM=T17,OPTIONS=FIND,PRIMARY_Key=dfewew7e-6hs3-j2j3-de9232jh,PHONE=1818111888,STATUS=1,MODES=1,VERSION=1,CREATE_TIME=2018-11-11 18:08:08,remark=null} * * 執行順序: * 1、main → ReadFile * 2、ReadFile(讀取檔案中的資料) → Format(將ReadFile傳入的字串格式化為sql並返回) → fileWrite(將格式化後的sql寫入檔案) * */
//long startTime =System.currentTimeMillis(); //獲取開始時間 String str_path = "D:\\xuexi\\data.txt";//需要格式化的檔案存放路徑 String result_sql_path = "D:\\xuexi\\format.sql"; String tanle_name = "TableName"; //需要插入的表名稱 ReadFile(str_path,result_sql_path,tanle_name); } public static int CountStr(String str, String sToFind)
{ /** * 查詢字元在一個字串中出現的次數 * str 需要查詢的字串 * sToFind 要查詢的字串 * return 出現的次數 * */ int num = 0; while (str.contains(sToFind)) { //判斷字串中是否包含sToFind只要包含就一直查詢 str = str.substring(str.indexOf(sToFind) + sToFind.length()); num++; } return num; } public static String Format(String str, String table_name) { /** * str 需要格式化成sql的原字串 * table_name 格式化後sql需要插入的表名稱 * return 格式化完成的sql * */ String[] str2 = str.split(","); //對字串首次進行逗號切片 String[] NewStr; String head = "insert into"; StringBuffer sql_key = new StringBuffer("("); //原始預設放一個括號 StringBuffer sql_value = new StringBuffer("("); String date_str = "UPDATE_TIME,CREATE_TIME,DELETE_TIME"; //用於判斷是否為時間欄位 int count; count = CountStr(str,"="); for (int i=0;i<count;i++) { NewStr = str2[i].split("="); //對字串二次切片(得到的原始值格式為{A=B},切片後的到A,B) for (int j=0;j<2;j++) { //只有左右兩個值所以只需要迴圈兩次 String key = NewStr[0]; //用於判斷是否為時間欄位 key = key.replace(" ",""); //去空格 if(j == 0) { //等號左邊的值 //拼接欄位名稱 sql_key.append(NewStr[j]); if (i != (count -1)) { //不是字串結尾 sql_key.append(","); //為每個欄位新增空格 }else { sql_key.append(")"); //是字串結尾則新增括號 } }else if (date_str.contains(key)){ //如果key是時間欄位 sql_value.append("sysdate"); //如果是時間欄位則插入sysdate,執行sql語句時Oracle會自動將sysdate轉為當前時間 if (i != (count -1)) { //不是字串結尾 sql_value.append(","); //為每個欄位新增空格 }else { sql_value.append(")"); //是字串結尾則新增括號 } }else { sql_value.append("'" + NewStr[j] + "'"); //如果是時間欄位則插入sysdate,執行sql語句時Oracle會自動將sysdate轉為當前時間 if (i != (count -1)) { //不是字串結尾 sql_value.append(","); //為每個欄位新增空格 }else { sql_value.append(")"); //是字串結尾則新增括號 } } } } //也可以將sql_key(StringBuffer)轉為String後再進行替換 sql_key.replace(1, 2,""); //將sql開頭的{替換為空 int sql_VL = sql_value.length(); //判斷字串長度 sql_value.replace(sql_VL-3,sql_VL-2,""); //將sql結尾的 }替換為空 String str3 = sql_key.toString(); //將StringBuffer轉為String String str4 = sql_value.toString(); //將StringBuffer轉為String //將sql中的空格替換為空 str3 = str3.replace(" ", ""); //str4 = str4.replace(" ", ""); //欄位值中有空格但是有需要暫不去除 //System.out.println(head + " " + table_name + str3 + "values" + str4 + ";"); //需要插入的整個sql String result_sql = head + " " + table_name + str3 + "values" + str4 + ";"; //拼接sql return result_sql; //返回sql結果 } public static void ReadFile(String StrPath,String ResultPath,String table_name) { /** * 傳入一個檔案路徑讀取該檔案內容 * StrPath 需要讀取的檔案路徑 * ResultPath sql格式化後存放的路徑 * table_name sql需要插入的表名(insert into 後面的表名) * */ try { FileReader fr = new FileReader(StrPath); //建立FileReader物件 BufferedReader bufr = new BufferedReader(fr); //建立BufferedReader物件 String str = null; //int i = 0; while ((str = bufr.readLine()) != null) { //i++; //System.out.println("第" + i "行:" + str); //將檔案中讀取的元素字串傳入Format進行格式化 //String s = {USER_TYPE=1,CREATE_USER=ZHANG,UPDATE_USER=li,OPER_NUM=D001,SRC=2,UPDATE_TIME=2018-11-11 18:08:08.0,TABLE_NUM=T17,OPTIONS=FIND,PRIMARY_Key=dfewew7e-6hs3-j2j3-de9232jh,PHONE=1818111888,STATUS=1,MODES=1,VERSION=1,CREATE_TIME=2018-11-11 18:08:08,remark=null} String result = Format(str,table_name); //傳入原始字串並獲得返回的sql //System.out.println(result); //將格式化後的結果寫入檔案 fileWrite(result,ResultPath); //呼叫fileWrite將結果寫入檔案 } bufr.close(); //將BufferedReader流關閉 fr.close(); //將FileReader流關閉 System.out.println("sql寫入完成..."); }catch(IOException e) { //異常處理 e.printStackTrace(); } } public static void fileWrite(String content,String path) { /** * 將傳入的一段內容寫入檔案 * content 需要寫入的內容 * path 檔案存放路徑 * */ FileWriter fw = null; try { //如果檔案存在則追加寫入,檔案不存在則建立 File f = new File(path); fw = new FileWriter(f,true); //追加的方式 //fw = new FileWriter(f,false); //覆蓋的方式 }catch(IOException e) { e.printStackTrace(); } PrintWriter pw = new PrintWriter(fw); pw.write(content + "\r\n");//內容 pw.flush(); try { fw.flush(); pw.close(); fw.close(); }catch(IOException e){ e.printStackTrace(); } } } eclipse中執行結果: insert into TableName(USER_TYPE,CREATE_USER,UPDATE_USER,OPER_NUM,SRC,UPDATE_TIME,TABLE_NUM,OPTIONS,PRIMARY_Key,PHONE,STATUS,MODES,VERSION,CREATE_TIME,remark)values('1','ZHANG','li','D001','2',sysdate,'T17','FIND','dfewew7e-6hs3-j2j3-de9232jh','1818111888','1','1','1',sysdate,'null');

優化併發讀取示例程式碼:

package java_demo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class SQL_FORMAT {
	public static void main(String[] args) {
		/**
		 *   單行資料格式(類似),欄位數量不固定
		 * {USER_TYPE=1,CREATE_USER=ZHANG,UPDATE_USER=li,OPER_NUM=D001,SRC=2,UPDATE_TIME=2018-11-11 18:08:08.0,TABLE_NUM=T17,OPTIONS=FIND,PRIMARY_Key=dfewew7e-6hs3-j2j3-de9232jh,PHONE=1818111888,STATUS=1,MODES=1,VERSION=1,CREATE_TIME=2018-11-11 18:08:08.0}
		 * 
		 *    執行順序:
		 *    1、main → timer(定時) → ReadFile
		 *    2、ReadFile(讀取檔案中的資料) → Format(將ReadFile傳入的字串格式化為sql並返回) → fileWrite(將格式化後的sql寫入檔案)
		 * 二次優化:
		 * 併發讀取多個檔案
		 * 將原來的追加內容改為覆蓋內容,因為會多次跑避免重複(如果一天跑一次不受影響)
		 * */
		Timer timer = new Timer(); //建立物件
		//timer.schedule(new MyTask(),2018-12-12,3*60*1000); //2018-12-12每3分鐘跑一次
		timer.schedule(new MyTask(),0,1000); //0表示立即呼叫timer的run,1000代表間隔時間
		timer.schedule(new MyTask2(),0,1000); //1000也可替換為類似格式60*60*1000(1小時),3*60*1000(3分鐘)
	}
	
	public int CountStr(String str, String sToFind) {
		/**
		 * 查詢字元在一個字串中出現的次數
		 * str 需要查詢的字串
		 * sToFind 要查詢的字串
		 * return 出現的次數
		 * */
		
		int num = 0;
		while (str.contains(sToFind)) { //判斷字串中是否包含sToFind只要包含就一直查詢
			str = str.substring(str.indexOf(sToFind) + sToFind.length());
			num++;
		}
		return num;
	}
	
	public String Format(String str, String table_name) {
		/**
		 * str 需要格式化成sql的原字串
		 * table_name 格式化後sql需要插入的表名稱
		 * return 格式化完成的sql
		 * */
		
		String[] str2 = str.split(","); //對字串首次進行逗號切片
		String[] NewStr;
		String head = "insert into";
		StringBuffer sql_key = new StringBuffer("("); //原始預設放一個括號
		StringBuffer sql_value = new StringBuffer("(");
		String date_str = "UPDATE_TIME,CREATE_TIME,DELETE_TIME"; //用於判斷是否為時間欄位
		
		int count;
		
		count = CountStr(str,"=");
		for (int i=0;i<count;i++) {
			NewStr = str2[i].split("="); //對字串二次切片(得到的原始值格式為{A=B},切片後的到A,B)
			for (int j=0;j<2;j++) { //只有左右兩個值所以只需要迴圈兩次
				String key = NewStr[0]; //用於判斷是否為時間欄位
				key = key.replace(" ",""); //去空格
				if(j == 0) { //等號左邊的值
					//拼接欄位名稱
					sql_key.append(NewStr[j]);
					if (i != (count -1)) { //不是字串結尾
						sql_key.append(","); //為每個欄位新增空格
					}else {
						sql_key.append(")"); //是字串結尾則新增括號
					}
				}else if (date_str.contains(key)){ //如果key是時間欄位
					sql_value.append("sysdate"); //如果是時間欄位則插入sysdate,執行sql語句時Oracle會自動將sysdate轉為當前時間
					if (i != (count -1)) { //不是字串結尾
						sql_value.append(","); //為每個欄位新增空格
					}else {
						sql_value.append(")"); //是字串結尾則新增括號
					}
				}else {
					sql_value.append("'" + NewStr[j] + "'"); //如果是時間欄位則插入sysdate,執行sql語句時Oracle會自動將sysdate轉為當前時間
					if (i != (count -1)) { //不是字串結尾
						sql_value.append(","); //為每個欄位新增空格
					}else {
						sql_value.append(")"); //是字串結尾則新增括號
					}
				}
			}
		}
		//也可以將sql_key(StringBuffer)轉為String後再進行替換
		sql_key.replace(1, 2,""); //將sql開頭的{替換為空
		int sql_VL = sql_value.length(); //判斷字串長度
		sql_value.replace(sql_VL-3,sql_VL-2,""); //將sql結尾的 }替換為空
		
		String str3 = sql_key.toString(); //將StringBuffer轉為String
		String str4 = sql_value.toString(); //將StringBuffer轉為String
		
		//將sql中的空格替換為空
		str3 = str3.replace(" ", "");
		//str4 = str4.replace(" ", ""); //欄位值中有空格但是有需要暫不去除
		//System.out.println(head + " " + table_name + str3 + "values" + str4 + ";"); //需要插入的整個sql
		String result_sql = head + " " + table_name + str3 + "values" + str4 + ";\n"; //拼接sql,新加換行符號否則所有sql會在一行展示
		return result_sql; //返回sql結果
		
	}
	
	public void ReadFile(String StrPath,String ResultPath,String table_name) {
		/**
		 *  傳入一個檔案路徑讀取該檔案內容
		 * StrPath 需要讀取的檔案路徑
		 * ResultPath sql格式化後存放的路徑
		 * table_name sql需要插入的表名(insert into 後面的表名)
		 * */
		
		StringBuffer sql_str = new StringBuffer(); //用於存放sql結果,等待格式化完成所有內容再一次寫入檔案
		String result = null;
		try {
			FileReader fr = new FileReader(StrPath); //建立FileReader物件
			BufferedReader bufr = new BufferedReader(fr); //建立BufferedReader物件
			String str = null; //建立字串物件
			//int i = 0;
			
			while ((str = bufr.readLine()) != null) { //每次從檔案讀取一行資料
				//i++;
				//System.out.println("第" + i "行:" + str);
				
				//將檔案中讀取的元素字串傳入Format進行格式化
				//String s = {USER_TYPE=1,CREATE_USER=ZHANG,UPDATE_USER=li,OPER_NUM=D001,SRC=2,UPDATE_TIME=2018-11-11 18:08:08.0,TABLE_NUM=T17,OPTIONS=FIND,PRIMARY_Key=dfewew7e-6hs3-j2j3-de9232jh,PHONE=1818111888,STATUS=1,MODES=1,VERSION=1,CREATE_TIME=2018-11-11 18:08:08.0}
				result = Format(str,table_name); //傳入原始字串並獲得返回的sql
				//System.out.println(result);
				
				
				//將每次得到的sql結果放入sql_str
				sql_str.append(result);
				
			}
			String str5 = sql_str.toString(); //StringBuffer轉String
			//將格式化後的結果寫入檔案
			fileWrite(str5,ResultPath); //呼叫fileWrite將結果寫入檔案
			
			bufr.close(); //將BufferedReader流關閉
			fr.close(); //將FileReader流關閉
			//System.out.println("sql寫入完成...");
		}catch(IOException e) { //異常處理
			e.printStackTrace();
		}
	}
	
	public void fileWrite(String content,String path) {
		/**
		 * 將傳入的一段內容寫入檔案
		 * content 需要寫入的內容
		 * path 檔案存放路徑
		 * */
		FileWriter fw = null;
		try {
			//如果檔案存在則追加寫入,檔案不存在則建立
			File f = new File(path);
			//fw = new FileWriter(f,true); //追加的方式
			fw = new FileWriter(f,false); //覆蓋的方式
		}catch(IOException e) {
			e.printStackTrace();
		}
		PrintWriter pw = new PrintWriter(fw);
		pw.write(content + "\r\n");//內容
		pw.flush();
		
		try {
			fw.flush();
			pw.close();
			fw.close();
		}catch(IOException e){
			e.printStackTrace();
		}
	}