深入Sqlite多線程入庫(kù)的問題
更新時(shí)間:2013年05月16日 09:45:01 作者:
本篇文章是對(duì)Sqlite多線程入庫(kù)的問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
今天經(jīng)理給了我一個(gè)三十多M的sql文件,讓我測(cè)試數(shù)據(jù)定位的問題。按照慣例,我使用navicat for sqlite創(chuàng)建一個(gè)表,然后將sql文件導(dǎo)入。我然后去干其他事兒了,大約過了一個(gè)多小時(shí),我想數(shù)據(jù)應(yīng)該導(dǎo)入的差不多了吧。我打開一看,汗,死在那兒了。我關(guān)掉軟件又重新導(dǎo)入一遍,還是那個(gè)德行。又得知經(jīng)理曾經(jīng)自己也導(dǎo)過,沒有成功??磥恚霉ぞ邔?dǎo)入的方法行不通了。
但是,想想就十多萬條數(shù)據(jù),就是十多萬條insert sql語(yǔ)句,有那么難嗎?于是,我想還是自己寫一個(gè)程序?qū)氚伞km然中間也遇到一些小插曲,但是還是成功地把數(shù)據(jù)導(dǎo)進(jìn)去了。
程序的代碼如下:
package com.geoway.pad.common.tool;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @author likehua
* @note SQLite建庫(kù)以及批量入庫(kù)
* */
public class BatchTool{
//ddl
private static String ddl="CREATE TABLE IF NOT EXISTS pbeijing_point (OBJECTID INTEGER,NAME TEXT,ADDRESS TEXT,PHONE TEXT,FAX TEXT,TYPE TEXT,CITYCODE TEXT,URL TEXT,EMAIL TEXT,NAME2 TEXT,X INTEGER,Y INTEGER)";
Connection jCon=null;
//get connection
public synchronized Connection getConnection(){
if(jCon==null){
// json=
Statement state=null;
try {
Class.forName("org.sqlite.JDBC");
jCon=DriverManager.getConnection("jdbc:sqlite:c:\\newD.db");
state=jCon.createStatement();
state.executeUpdate(ddl);
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return jCon;
}
//創(chuàng)建500個(gè)線程
ExecutorService service=Executors.newFixedThreadPool(500);
//讀取sql文件 每五百個(gè)insert 語(yǔ)句由一個(gè)線程批量操作
public void readBatchSQL(InputStream is) throws IOException{
BufferedReader bufferReader=new BufferedReader(new InputStreamReader(is,"UTF-8"));
String line;
String one="";
int tag=0;
String batchSql="";
while((line=bufferReader.readLine())!=null){
one+=line;
if(one.indexOf(";")!=-1){
batchSql+=one;
one="";//reset
tag++;
};
//符合條件 開辟一個(gè)線程
if(tag!=0&&tag/500!=0){
service.execute(new SQLiteBatchHandler(batchSql));
batchSql="";//reset
tag=0;//reset
}
}
//最后執(zhí)行 剩余的sql
if(batchSql.length()>0){
System.out.println("finalSQL:"+batchSql);
Runnable r=new SQLiteBatchHandler(batchSql);
service.execute(r);
};
try {
//關(guān)閉線程池
this.service.shutdown();
this.service.awaitTermination(1, TimeUnit.HOURS);<BR> getConnection().close();<BR> } catch (InterruptedException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
};
/**
* @note 分割sql
* */
private static String[] splitSQL(String batchSQl){
if(batchSQl!=null){
return batchSQl.split(";");
};
return null;
}
/**
* @note 執(zhí)行批量更新操作
* 由于connection.comit 操作時(shí) 如果存在 statement沒有close 就會(huì)報(bào)錯(cuò) 因此將此方法加上同步 。
* */
private synchronized void exucteUpdate(String batch){
Statement ste=null;
Connection con=null;
try{
con=getConnection();
con.setAutoCommit(false);
ste=con.createStatement();
String[] sqls=this.splitSQL(batch);
for(String sql:sqls){
if(sql!=null){
ste.addBatch(sql);
};
};
ste.executeBatch();<BR> ste.close();
con.commit();//提交
}catch(Exception e){
e.printStackTrace();
System.out.println("執(zhí)行失敗:"+batch);
try {
con.rollback();//回滾
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
if(ste!=null){
try {
ste.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* @author likehua
* @note 入庫(kù)線程
* */
private class SQLiteBatchHandler implements Runnable{
private String batch;
public SQLiteBatchHandler(String sql){
this.batch=sql;
};
@SuppressWarnings("static-access")
@Override
public void run() {
try {
Thread.currentThread().sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(this.batch.length()>0){
exucteUpdate(batch);
};
}
}
/**
* @author likehua
* @note 主函數(shù)入口
* */
public static void main(String[] args) throws FileNotFoundException, IOException{
BatchTool s=new BatchTool();
s.readBatchSQL(new FileInputStream(new File("c:\\poi.sql")));
}
}
但是,想想就十多萬條數(shù)據(jù),就是十多萬條insert sql語(yǔ)句,有那么難嗎?于是,我想還是自己寫一個(gè)程序?qū)氚伞km然中間也遇到一些小插曲,但是還是成功地把數(shù)據(jù)導(dǎo)進(jìn)去了。
程序的代碼如下:
復(fù)制代碼 代碼如下:
package com.geoway.pad.common.tool;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @author likehua
* @note SQLite建庫(kù)以及批量入庫(kù)
* */
public class BatchTool{
//ddl
private static String ddl="CREATE TABLE IF NOT EXISTS pbeijing_point (OBJECTID INTEGER,NAME TEXT,ADDRESS TEXT,PHONE TEXT,FAX TEXT,TYPE TEXT,CITYCODE TEXT,URL TEXT,EMAIL TEXT,NAME2 TEXT,X INTEGER,Y INTEGER)";
Connection jCon=null;
//get connection
public synchronized Connection getConnection(){
if(jCon==null){
// json=
Statement state=null;
try {
Class.forName("org.sqlite.JDBC");
jCon=DriverManager.getConnection("jdbc:sqlite:c:\\newD.db");
state=jCon.createStatement();
state.executeUpdate(ddl);
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return jCon;
}
//創(chuàng)建500個(gè)線程
ExecutorService service=Executors.newFixedThreadPool(500);
//讀取sql文件 每五百個(gè)insert 語(yǔ)句由一個(gè)線程批量操作
public void readBatchSQL(InputStream is) throws IOException{
BufferedReader bufferReader=new BufferedReader(new InputStreamReader(is,"UTF-8"));
String line;
String one="";
int tag=0;
String batchSql="";
while((line=bufferReader.readLine())!=null){
one+=line;
if(one.indexOf(";")!=-1){
batchSql+=one;
one="";//reset
tag++;
};
//符合條件 開辟一個(gè)線程
if(tag!=0&&tag/500!=0){
service.execute(new SQLiteBatchHandler(batchSql));
batchSql="";//reset
tag=0;//reset
}
}
//最后執(zhí)行 剩余的sql
if(batchSql.length()>0){
System.out.println("finalSQL:"+batchSql);
Runnable r=new SQLiteBatchHandler(batchSql);
service.execute(r);
};
try {
//關(guān)閉線程池
this.service.shutdown();
this.service.awaitTermination(1, TimeUnit.HOURS);<BR> getConnection().close();<BR> } catch (InterruptedException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
};
/**
* @note 分割sql
* */
private static String[] splitSQL(String batchSQl){
if(batchSQl!=null){
return batchSQl.split(";");
};
return null;
}
/**
* @note 執(zhí)行批量更新操作
* 由于connection.comit 操作時(shí) 如果存在 statement沒有close 就會(huì)報(bào)錯(cuò) 因此將此方法加上同步 。
* */
private synchronized void exucteUpdate(String batch){
Statement ste=null;
Connection con=null;
try{
con=getConnection();
con.setAutoCommit(false);
ste=con.createStatement();
String[] sqls=this.splitSQL(batch);
for(String sql:sqls){
if(sql!=null){
ste.addBatch(sql);
};
};
ste.executeBatch();<BR> ste.close();
con.commit();//提交
}catch(Exception e){
e.printStackTrace();
System.out.println("執(zhí)行失敗:"+batch);
try {
con.rollback();//回滾
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
if(ste!=null){
try {
ste.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* @author likehua
* @note 入庫(kù)線程
* */
private class SQLiteBatchHandler implements Runnable{
private String batch;
public SQLiteBatchHandler(String sql){
this.batch=sql;
};
@SuppressWarnings("static-access")
@Override
public void run() {
try {
Thread.currentThread().sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(this.batch.length()>0){
exucteUpdate(batch);
};
}
}
/**
* @author likehua
* @note 主函數(shù)入口
* */
public static void main(String[] args) throws FileNotFoundException, IOException{
BatchTool s=new BatchTool();
s.readBatchSQL(new FileInputStream(new File("c:\\poi.sql")));
}
}
相關(guān)文章
org.slf4j.Logger中info()方法的使用詳解
這篇文章主要介紹了org.slf4j.Logger中info()方法的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
2021-12-12
詳解Spring的autowire-candidate設(shè)計(jì)
現(xiàn)在的Spring應(yīng)用通常都是基于注解開發(fā),但是對(duì)Spring感興趣的同學(xué)可以借助Spring早期基于Xml配置的各種運(yùn)用來加深對(duì)Spring框架內(nèi)部的理解和體會(huì)Spring框架的設(shè)計(jì)之妙。這篇文章我們就來談?wù)刋ml配置之default-autowire-candidates
2021-06-06
Java實(shí)例項(xiàng)目零錢通的實(shí)現(xiàn)流程
本篇文章為你帶來Java的一個(gè)新手實(shí)戰(zhàn)項(xiàng)目,是一個(gè)零錢通系統(tǒng),項(xiàng)目來自于B站韓順平老師,非常適合新手入門練習(xí),感興趣的朋友快來看看吧
2022-03-03 
