怎么利用JAVA导入大数据量的文本文件数据到Oracle数据库 首先从文件中读取数据,每当读完一条纪录是,把它转换成oracle的插入语句。你可以执行,也可以存在一个大字符串里,最后一起执行 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 用字符串拆分split()方法把名称过滤掉。并且根据判断来生成SQL语句 我现在就是按照两位所说的那样做,可是在导入过程当中,大概需要一个多小时,结果JSP页面因为等待时间过长而超时.一个是看大家有什么成功的经验,或者是有好的处理方法,能够不超时,或者是加快导入的时间? http://www.builder.com.cn/2002/0806/57323.shtmlkankanasdf 不知道Spring+Hibernate+Struts这方面有什么思路吗? 我以前寫過的可參考修改一下應該可以湊合著用package com.XXX;import com.my.db.myDb;import com.my.file.*;import com.my.schedule..myOperaEdiRec;import com.my.schedule..myXa;import com.my.util.myDate;import com.my.util.myUtil;import org.apache.log4j.Logger;import javax.servlet.ServletContext;import java.io.BufferedReader;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.ArrayList;public class myXBPersocards { private PreparedStatement psmtInsPersocard; private myDb oDb; private myFile oFile; private myXBlog oLoger; private BufferedReader oReader; private Logger oLogger; private int iAllRecNum;//所有的記錄 private int iOkRecNum;//成功的記錄 private final int iChkBegin = 3; private final int iChkEnd = 10; private final int iChkLen = 418; //字段總長度 private String sFields[]; private final int iFieldsLen[] = {8, 16, 8, 11}; private ServletContext Application; //Context對象 /** * 定義相慶欄位* */ private String FILE_NO; private String INF_DATE; private String LINK_NO_N; private String END_DATE; private int ERR_NO;//錯語代碼 private String RTN_MSG;//處理訊息 private int iCount=0; public myXBPersocards(myFile file, myDb db, myXBlog loger, ServletContext application, Logger logger_) throws Exception { oReader = null; this.oDb = db; this.oFile = file; this.oLoger = loger; this.oLogger = logger_; this.Application = application; iAllRecNum = 0; iOkRecNum = 0; initSql(); try { oReader = oFile.getReader(); readFile(oReader); oDb.commit(); } catch (Exception e) { oLoger.error("讀取文件時出錯:" + e.getMessage()); oLogger.error("讀取文件時出錯:" + e.getMessage()); throw new Exception("讀取文件時出錯:" + e.getMessage()); } finally { if (oReader != null) oReader.close(); if (psmtInsPersocard != null) oDb.closePrepareStmt(psmtInsPersocard); } } /** * 初如化sql. * * @throws Exception */ private void initSql() throws Exception { String sqlInsPersocard = "insert into Persocard \n" + "(FILE_NO,INF_DATE,LINK_NO_N,END_DATE \n" + "values \n " + "(?,?,?,?)"; psmtInsPersocard = oDb.prepareStmt(sqlInsPersocard); } /** * 切分fields的字段長度 * * @param line * @return * @throws Exception */ protected String[] tokenizerLine(String line) throws Exception { int iBegin = 0; String str[] = new String[iFieldsLen.length]; byte[] buf = line.getBytes(); for (int i = 0; i < iFieldsLen.length; i++) { str[i] = new String(buf, iBegin, iFieldsLen[i]); iBegin += iFieldsLen[i]; } return str; } /** * 讀文件 * * @param oReader * @throws Exception */ private boolean readFile(BufferedReader oReader) throws Exception { int curNum = 0; //該檔案的總行數 int readLineTot = 0; //首行的第3~10碼為資料筆數(E) ArrayList oList = null; boolean isBadLen = false; //首行的長度是否OK String sLine; String sEDI_NO = myOperaEdiRec.getEdiNO(this.oDb); //轉檔記錄編號 while ((sLine = oReader.readLine()) != null) { if (curNum == 0) { oLogger.info(oFile.getFileName() + "序號" + sEDI_NO); readLineTot = Integer.parseInt(sLine.substring(iChkBegin - 1, iChkEnd).trim()); if (sLine.getBytes().length != iChkLen) {//如果記錄的長度不對,不處理. isBadLen = true; oLoger.error("文檔資料長度不對"); break; } } else { if (oList == null) oList = new ArrayList(); oList.add(curNum - 1, sLine); } curNum++; } if (isBadLen) return false; if (readLineTot > 0) { if ((curNum - 1) != readLineTot || oList == null) { return false; } else { iAllRecNum = readLineTot;//處理的總筆數 } } else { return false; } //處理可以用的資料 try { for (int i = 0; i < oList.size(); i++) { try { processLine((String) oList.get(i)); iOkRecNum++; } catch (Exception e) { oLoger.error("處理一行記錄時出錯:" + e.getMessage()); oLogger.error("處理一行記錄時出錯:" + e.getMessage()); e.printStackTrace(); } } } catch (Exception e) { oLogger.error("轉檔錯誤:" + e.getMessage()); } oLogger.info("轉檔處理結束"); return true; } /** * 處理一行記錄. * * @param sLine * @throws Exception */ private void processLine(String sLine) throws Exception { sFields = tokenizerLine(sLine); iCount++; oLoger.info("第幾筆資料"+iCount); System.out.println("第幾筆資料"+iCount); setLineField();//設定欄位 insertPersocard();//新增記錄 } /** * 新增資料 * * @throws Exception */ private void insertPersocard() throws Exception { try { oDb.setCurrentPrepareStmt(psmtInsPersocard); psmtInsPersocard.clearParameters(); psmtInsPersocard.setString(1, FILE_NO); psmtInsPersocard.setString(2, INF_DATE); psmtInsPersocard.setString(3, LINK_NO_N); psmtInsPersocard.setString(4, END_DATE); oDb.prepareUpdate(); } catch (Exception e) { oLoger.error("新增資料檔時出錯:" + e.getMessage()); oLogger.error("新增資料檔時出錯:" + e.getMessage()); e.printStackTrace(); throw e; } } /** * 設定欄位的記錄. * * @throws Exception */ private void setLineField() throws Exception { FILE_NO = oFile.getFileExt(); INF_DATE = sFields[1].trim(); LINK_NO_N = sFields[2].trim(); END_DATE = sFields[3].trim(); }} 用一个随服务器自动启动的servlet每隔一段时间去读取servletContext中的Vector();Vector里放上我们的语句。然后在这个servlet里执行。不知道能不能行得通 倒个数据跟JSP有什么关系?这也要用SSH架构? 寒。。 用 sqlldr 吧,很简单的。 除了数据量大,没别的瓶颈了吧,也就是:1.读文件2.拼sql3.写数据库但是我觉得,要实现的比较合理,还是要仔细定义些东西的:首先定义一个bean,包括所有字段RTC 07|CHG D|SPL 0RBN1|MFR 81205|PNR AAM7319-1RTC 07|CHG D|SPL 0RBN1|MFR 81205|PNR AAM7323-501RTC 07|CHG D|SPL 0RBN1|MFR 81205从数据看,关键是拼sql以下是我的思路:public class Test{ private String template = "insert into xxxTable (RTC,CHG,SPL,MFR,PNR) values " + "('value_RTC','value_CHG','value_SPL','value_MFR','value_PNR');"; private Connection conn = null; private PreparedStatement pstmt = null; public static void main(String[] args) { try { Test t = new Test(); t.parseFile(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void parseFile() throws SQLException { String sss = "RTC 07|CHG D|SPL 0RBN1|MFR 81205"; Scanner scanner = new Scanner(sss); String token = null; token = scanner.findInLine("RTC\\s+\\w+\\|?"); if (token != null) { template = template.replaceAll("value_RTC", token.replaceAll( "RTC\\s+", "").replaceAll("\\|", "")); } token = scanner.findInLine("CHG\\s+\\w*\\|?"); if (token != null) { template = template.replaceAll("value_CHG", token.replaceAll( "CHG\\s+", "").replaceAll("\\|", "")); } token = scanner.findInLine("SPL\\s+\\w*\\|?"); if (token != null) { template = template.replaceAll("value_SPL", token.replaceAll( "SPL\\s+", "").replaceAll("\\|", "")); } token = scanner.findInLine("MFR\\s+\\w*\\|?"); if (token != null) { template = template.replaceAll("value_MFR", token.replaceAll( "MFR\\s+", "").replaceAll("\\|", "")); } token = scanner.findInLine("PNR\\s+[\\w-]*\\|?"); if (token != null) { template = template.replaceAll("value_PNR", token.replaceAll( "PNR\\s+", "").replaceAll("\\|", "")); } template = template.replaceAll("value_\\w+", ""); pstmt.addBatch(template); }}象这种比较短的sql,addBatch上3、5万次,再pstmt.executeBatch();一次应该就可以当然更好的办法应该是:用ultraedit之类的工具将文本文件弄成规范的格式,然后改改文件扩展名,直接用数据库导入功能,呵呵 汗~~~~~~~导数据不需要用SSH吧,直接用写个Java类运行就可以啦~ 如果你非要用JSP,那么请单独启动一个线程来导入,或者写一个存储过程供Java调用,或者如楼上所说写个Java类单独运行,在JSP中直接写这种逻辑,嗯,应该是比较业余的做法。 用消息驱动Bean异步执行,然后jsp不停刷新好了 关注下,记得 pl/sql developer 有个倒文本的工具的不知道用不用的上 按照我的经验,JSP提交时间过长的问题应该这样解决:页面仅提供上传功能,将该文本上传到服务器,然后由后台完成导入。 以前我做過這樣的程序,用正則表達式拆分一行的數據,拆分成一組值,然后拼湊出SQL,可以每讀取200行拼湊出一個SQL,再執行(因為sql過長會執行失敗的):比如:insert into tablename (col1,col2,col3,col4)select values1,value2,value3,value4unionselect value1,value2,value3,value4unionselect value1,value2,value3,value4...然后execute struts如何让一个jsp页面自动调用action QQ校友历史访问记录 JSP页面如何将接收到的参数转化为int型 数据库后台管理系统 java如何取得存储过程的OUT参数? j2ee安装包 请问大家,哪里有Freemind的源码下载? 关于Integer类型的相加问题 实体bean问题100分(高手请进) system.getproperty( user.dir )获取当前工作目录到底是哪个目录 用myEclipse写了点程序机子声音巨卡是怎么回事? 请教一个HQL查询语句的写法
kankanasdf
可參考修改一下
應該可以湊合著用package com.XXX;import com.my.db.myDb;
import com.my.file.*;
import com.my.schedule..myOperaEdiRec;
import com.my.schedule..myXa;
import com.my.util.myDate;
import com.my.util.myUtil;
import org.apache.log4j.Logger;import javax.servlet.ServletContext;
import java.io.BufferedReader;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;public class myXBPersocards {
private PreparedStatement psmtInsPersocard;
private myDb oDb;
private myFile oFile;
private myXBlog oLoger;
private BufferedReader oReader;
private Logger oLogger; private int iAllRecNum;//所有的記錄
private int iOkRecNum;//成功的記錄 private final int iChkBegin = 3;
private final int iChkEnd = 10;
private final int iChkLen = 418;
//字段總長度
private String sFields[];
private final int iFieldsLen[] = {8, 16, 8, 11}; private ServletContext Application; //Context對象
/**
* 定義相慶欄位*
*/
private String FILE_NO;
private String INF_DATE;
private String LINK_NO_N;
private String END_DATE;
private int ERR_NO;//錯語代碼
private String RTN_MSG;//處理訊息 private int iCount=0; public myXBPersocards(myFile file, myDb db, myXBlog loger, ServletContext application, Logger logger_)
throws Exception {
oReader = null;
this.oDb = db;
this.oFile = file;
this.oLoger = loger;
this.oLogger = logger_;
this.Application = application;
iAllRecNum = 0;
iOkRecNum = 0;
initSql();
try {
oReader = oFile.getReader();
readFile(oReader);
oDb.commit();
} catch (Exception e) {
oLoger.error("讀取文件時出錯:" + e.getMessage());
oLogger.error("讀取文件時出錯:" + e.getMessage());
throw new Exception("讀取文件時出錯:" + e.getMessage());
} finally {
if (oReader != null) oReader.close();
if (psmtInsPersocard != null) oDb.closePrepareStmt(psmtInsPersocard); }
} /**
* 初如化sql.
*
* @throws Exception
*/
private void initSql() throws Exception {
String sqlInsPersocard = "insert into Persocard \n" +
"(FILE_NO,INF_DATE,LINK_NO_N,END_DATE \n" +
"values \n " +
"(?,?,?,?)";
psmtInsPersocard = oDb.prepareStmt(sqlInsPersocard);
} /**
* 切分fields的字段長度
*
* @param line
* @return
* @throws Exception
*/
protected String[] tokenizerLine(String line) throws Exception {
int iBegin = 0;
String str[] = new String[iFieldsLen.length];
byte[] buf = line.getBytes(); for (int i = 0; i < iFieldsLen.length; i++) {
str[i] = new String(buf, iBegin, iFieldsLen[i]);
iBegin += iFieldsLen[i];
}
return str;
} /**
* 讀文件
*
* @param oReader
* @throws Exception
*/
private boolean readFile(BufferedReader oReader) throws Exception {
int curNum = 0; //該檔案的總行數
int readLineTot = 0; //首行的第3~10碼為資料筆數(E)
ArrayList oList = null;
boolean isBadLen = false; //首行的長度是否OK
String sLine;
String sEDI_NO = myOperaEdiRec.getEdiNO(this.oDb);
//轉檔記錄編號
while ((sLine = oReader.readLine()) != null) {
if (curNum == 0) {
oLogger.info(oFile.getFileName() + "序號" + sEDI_NO);
readLineTot = Integer.parseInt(sLine.substring(iChkBegin - 1, iChkEnd).trim());
if (sLine.getBytes().length != iChkLen) {//如果記錄的長度不對,不處理.
isBadLen = true;
oLoger.error("文檔資料長度不對");
break;
} } else {
if (oList == null) oList = new ArrayList();
oList.add(curNum - 1, sLine);
}
curNum++;
}
if (isBadLen) return false;
if (readLineTot > 0) {
if ((curNum - 1) != readLineTot || oList == null) {
return false;
} else {
iAllRecNum = readLineTot;//處理的總筆數
}
} else {
return false;
}
//處理可以用的資料
try {
for (int i = 0; i < oList.size(); i++) {
try {
processLine((String) oList.get(i));
iOkRecNum++;
} catch (Exception e) {
oLoger.error("處理一行記錄時出錯:" + e.getMessage());
oLogger.error("處理一行記錄時出錯:" + e.getMessage());
e.printStackTrace();
}
}
} catch (Exception e) {
oLogger.error("轉檔錯誤:" + e.getMessage());
}
oLogger.info("轉檔處理結束");
return true;
} /**
* 處理一行記錄.
*
* @param sLine
* @throws Exception
*/
private void processLine(String sLine) throws Exception {
sFields = tokenizerLine(sLine);
iCount++;
oLoger.info("第幾筆資料"+iCount);
System.out.println("第幾筆資料"+iCount);
setLineField();//設定欄位
insertPersocard();//新增記錄
} /**
* 新增資料
*
* @throws Exception
*/
private void insertPersocard() throws Exception {
try {
oDb.setCurrentPrepareStmt(psmtInsPersocard);
psmtInsPersocard.clearParameters();
psmtInsPersocard.setString(1, FILE_NO);
psmtInsPersocard.setString(2, INF_DATE);
psmtInsPersocard.setString(3, LINK_NO_N);
psmtInsPersocard.setString(4, END_DATE); oDb.prepareUpdate();
} catch (Exception e) {
oLoger.error("新增資料檔時出錯:" + e.getMessage());
oLogger.error("新增資料檔時出錯:" + e.getMessage());
e.printStackTrace();
throw e;
}
} /**
* 設定欄位的記錄.
*
* @throws Exception
*/
private void setLineField() throws Exception {
FILE_NO = oFile.getFileExt();
INF_DATE = sFields[1].trim();
LINK_NO_N = sFields[2].trim();
END_DATE = sFields[3].trim();
}
}
Vector里放上我们的语句。然后在这个servlet里执行。不知道能不能行得通
这也要用SSH架构? 寒。。
1.读文件
2.拼sql
3.写数据库但是我觉得,要实现的比较合理,还是要仔细定义些东西的:
首先定义一个bean,包括所有字段
RTC 07|CHG D|SPL 0RBN1|MFR 81205|PNR AAM7319-1
RTC 07|CHG D|SPL 0RBN1|MFR 81205|PNR AAM7323-501
RTC 07|CHG D|SPL 0RBN1|MFR 81205从数据看,关键是拼sql
以下是我的思路:
public class Test
{
private String template = "insert into xxxTable (RTC,CHG,SPL,MFR,PNR) values "
+ "('value_RTC','value_CHG','value_SPL','value_MFR','value_PNR');"; private Connection conn = null;
private PreparedStatement pstmt = null; public static void main(String[] args)
{
try
{
Test t = new Test();
t.parseFile();
}
catch (SQLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void parseFile() throws SQLException
{
String sss = "RTC 07|CHG D|SPL 0RBN1|MFR 81205";
Scanner scanner = new Scanner(sss);
String token = null; token = scanner.findInLine("RTC\\s+\\w+\\|?");
if (token != null)
{
template = template.replaceAll("value_RTC", token.replaceAll(
"RTC\\s+", "").replaceAll("\\|", ""));
}
token = scanner.findInLine("CHG\\s+\\w*\\|?");
if (token != null)
{
template = template.replaceAll("value_CHG", token.replaceAll(
"CHG\\s+", "").replaceAll("\\|", ""));
}
token = scanner.findInLine("SPL\\s+\\w*\\|?");
if (token != null)
{
template = template.replaceAll("value_SPL", token.replaceAll(
"SPL\\s+", "").replaceAll("\\|", ""));
}
token = scanner.findInLine("MFR\\s+\\w*\\|?");
if (token != null)
{
template = template.replaceAll("value_MFR", token.replaceAll(
"MFR\\s+", "").replaceAll("\\|", ""));
}
token = scanner.findInLine("PNR\\s+[\\w-]*\\|?");
if (token != null)
{
template = template.replaceAll("value_PNR", token.replaceAll(
"PNR\\s+", "").replaceAll("\\|", ""));
}
template = template.replaceAll("value_\\w+", ""); pstmt.addBatch(template);
}
}象这种比较短的sql,addBatch上3、5万次,再pstmt.executeBatch();一次应该就可以当然更好的办法应该是:用ultraedit之类的工具将文本文件弄成规范的格式,然后改改文件扩展名,直接用数据库导入功能,呵呵
比如:
insert into tablename (col1,col2,col3,col4)
select values1,value2,value3,value4
union
select value1,value2,value3,value4
union
select value1,value2,value3,value4
...
然后execute