深入Sqlite多線程入庫的問題
更新時(shí)間:2013年05月16日 09:45:01 作者:
本篇文章是對Sqlite多線程入庫的問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
今天經(jīng)理給了我一個(gè)三十多M的sql文件,讓我測試數(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語句,有那么難嗎?于是,我想還是自己寫一個(gè)程序?qū)氚?。雖然中間也遇到一些小插曲,但是還是成功地把數(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建庫以及批量入庫
* */
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 語句由一個(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 入庫線程
* */
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語句,有那么難嗎?于是,我想還是自己寫一個(gè)程序?qū)氚?。雖然中間也遇到一些小插曲,但是還是成功地把數(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建庫以及批量入庫
* */
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 語句由一個(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 入庫線程
* */
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)文章
如何解決springcloud feign 首次調(diào)用100%失敗的問題
這篇文章主要介紹了如何解決springcloud feign 首次調(diào)用100%失敗的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06IntelliJ IDEA(2019)安裝破解及HelloWorld案例(圖文)
這篇文章主要介紹了IntelliJ IDEA(2019)安裝破解及HelloWorld案例(圖文),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10Java使用easyExcel批量導(dǎo)入數(shù)據(jù)詳解
這篇文章主要介紹了Java使用easyExcel批量導(dǎo)入數(shù)據(jù)詳解,通常我們會(huì)提供一個(gè)模板,此模塊我們可以使用easyExcel導(dǎo)出數(shù)據(jù)生成的一個(gè)Excel文件當(dāng)作模板,提供下載鏈接,用戶在該文件內(nèi)填入規(guī)定的數(shù)據(jù)格式以后可以批量導(dǎo)入數(shù)據(jù)到數(shù)據(jù)庫中,需要的朋友可以參考下2023-08-08GateWay路由規(guī)則與動(dòng)態(tài)路由詳細(xì)介紹
這篇文章主要介紹了GateWay路由規(guī)則與GateWay動(dòng)態(tài)路由,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09SpringBoot+Mybatis實(shí)現(xiàn)登錄注冊的示例代碼
這篇文章主要介紹了SpringBoot+Mybatis實(shí)現(xiàn)登錄注冊的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03spring?boot微服務(wù)場景下apollo加載過程解析
apollo?是一個(gè)開源的配置中心項(xiàng)目,功能很強(qiáng)大,apollo?本身的配置項(xiàng)并不復(fù)雜,但是因?yàn)榕渲玫穆窂教貏e多,非常容易搞混了,?所以本文試圖聚焦?spring-boot?的場景,在?spring-boot?微服務(wù)場景下,搞清楚?apollo-client的加載過程2022-02-02