Java将文件中的内容转换为sql语句(和并发定时读取文件)

版权声明:编写不易,可看不可转,请知悉! https://blog.csdn.net/zha6476003/article/details/85110074

数据文件内容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();
		}
	}

}

class MyTask extends TimerTask{
	
	@Override
	public void run() {
		//long startTime = System.currentTimeMillis();//获取开始时间(毫秒)
		Date day = new Date();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String today = df.format(day); //当日日期
		String str_path = "D:\\xuexi\\data.txt";//需要格式化的文件存放路径
		String result_sql_path = "D:\\xuexi\\"+ today + "-A.sql"; //格式化后sql存放的路径
		String tanle_name = "TableName"; //需要插入的表名称
		SQL_FORMAT format = new SQL_FORMAT(); //创建对象
		format.ReadFile(str_path,result_sql_path,tanle_name); //开始工作
		System.out.println("A文件格式并写入完成,等待下次执行...");
		//long endTime = System.currentTimeMillis();//获取结束时间(毫秒)

	}
}

class MyTask2 extends TimerTask{
	
	@Override
	public void run() {
		//long startTime = System.currentTimeMillis();//获取开始时间(毫秒)
		Date day = new Date();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String today = df.format(day); //当日日期
		String str_path = "D:\\xuexi\\data2.txt";//需要格式化的文件存放路径
		String result_sql_path = "D:\\xuexi\\"+ today + "-B.sql"; //格式化后sql存放的路径
		String tanle_name = "TableName"; //需要插入的表名称
		SQL_FORMAT format = new SQL_FORMAT(); //创建对象
		format.ReadFile(str_path,result_sql_path,tanle_name); //开始工作
		System.out.println("B文件格式并写入完成,等待下次执行...");
		//long endTime = System.currentTimeMillis();//获取结束时间(毫秒)

	}
}

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');

到此就完成了,每天只会生成一个sql文件,文件中包含当天的所有sql内容,后添加了新数据源也不影响,多条数据会自动换行

猜你喜欢

转载自blog.csdn.net/zha6476003/article/details/85110074