java千万级数据txt文件导入数据库

  最近在做项目的时候,有要把txt文件导入到数据库,txt文件有千万级,如果使用传统的读文件,写数据库,效率很慢。自己按照这种方式使用100万条数据的txt文件导入到oracle数据库,花费了二十多分钟。针对这种情况,可使用sqlLoader方式加载。
数据说明:
文件名:abc.txt
文件格式如下:
1111111|1|20171025|100|1|2|3|
1111111|2|20171025|100|1|2|3|
1111111|3|20171025|100|1|2|3|
一、导入oracle数据库
shell如下:
String str="sqlldr "+用户名+"/"+密码+" control="+ctl文件路径+"import_clientinfo.ctl"+" log=log.log bad=bad.log errors=100000 rows=100000";
import_clientinfo.ctl文件内容如下:
load data
infile ' abc.txt'
append into table tbclientcrmbranchno
fields terminated by '|'
(
IN_CLIENT_NO,
CLIENT_NO,
TRANS_DATE,
BRANCH_NO,
RESERVE1,
RESERVE2,
RESERVE3
)
解释说明:
infile ' abc.txt' 表示要导入的文本文件名为 abc.txt
append into table 后接要导入的表名
此处用append表示追加到表中,若用
Insert 表示导入空表,有数据则停止;
Replace表示原来表中如果有数据,则会被删除(用delete from table语句)
Truncate表示原来表中如果有数据,则会被清除(用truncate table语句)
fields terminated by '|'  数据中每行记录用”|”分隔

java程序调用shell:Process pro = Runtime.getRuntime().exec(str);
pro.waitFor();
如果数据量大,此时会发生阻塞,导致数据不能全部插入到oracle数据库,但是程序还在运行,如果关掉服务器,这时候,文件中的数据会全部导入到oracle数据库。
此时处理缓冲区中的信息,开两个线程分别去处理标准输出流和错误输出流。
程序如下:
package com.hundsun.base.database;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

public class ManyNumImport {
	public static void main(String[] args) {
		String str="sqlldr 用户名/密码 controlctl文件路径import_clientinfo.ctl"
				+" log=log.log bad=bad.log errors=100000 rows=100000";
		Process pro = null;
		try {
			pro = Runtime.getRuntime().exec(str);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		printMessage(pro .getInputStream());
		printMessage(pro .getErrorStream());
		try {
			pro.waitFor();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static void printMessage(InputStream inputStream) {
		new Thread(new Runnable() {
			public void run() {
				Reader reader = new InputStreamReader(inputStream);
				BufferedReader bf = new BufferedReader(reader);
				String line = null;
				try {
					while((line=bf.readLine())!=null) {
						System.out.println(line);
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}).start();
		
	}

}
二、导入db2数据库
data_finalasset.sh如下:
#shell脚本传入参数校验
if [ $# -ne 3 ] ; then
echo "data_finalasset.sh 脚本传入参数错误"
echo "Usage: data_finalasset.sh 数据库用户 用户密码 数据文件存放路径"
exit 1
fi

#数据库实例名根据现场情况配置
echo "导入数据准备开始"
db2 connect to ifm30as user $1 using $2;

db2 "import from $3 of del modified by coldel| nodoubledel replace into tbargfinalasset(client_no,trans_date,month,final_assets)"
db2 connect reset
db2 quit
echo "导入数据准备完成"
说明:
ifm30as 表述数据库名称;
$1:用户名
$2:密码
$3:文件名称
coldel|:表示使用"|"分割
java程序如下:
String shellDir = 路径+ "data_finalasset.sh " +用户名 + " " + 密码+ " " + 'abc.txt';
			Process pro = ScriptExec.exec1("sh "+shellDir);
			String line = "";
			input = new BufferedReader(new InputStreamReader(pro
					.getInputStream()));
			errorInput = new BufferedReader(new InputStreamReader(pro
					.getErrorStream()));
			while ((line = errorInput.readLine()) != null) {// 判断执行脚本时有没有发生错误。
				LcptLog.getTransLogNoCache().fatal(line);
			}
			while ((line = input.readLine()) != null) {
				BatchLog.writeLog(context, line); // shell脚本执行结果输出到备份日志文件中
			}
			pro.waitFor();



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值