深入Sqlite多线程入库的问题

 更新时间:2013年05月16日 09:45:01   作者:  
本篇文章是对Sqlite多线程入库的问题进行了详细的分析介绍,需要的朋友参考下
今天经理给了我一个三十多M的sql文件,让我测试数据定位的问题。按照惯例,我使用navicat for sqlite创建一个表,然后将sql文件导入。我然后去干其他事儿了,大约过了一个多小时,我想数据应该导入的差不多了吧。我打开一看,汗,死在那儿了。我关掉软件又重新导入一遍,还是那个德行。又得知经理曾经自己也导过,没有成功。看来,用工具导入的方法行不通了。

但是,想想就十多万条数据,就是十多万条insert sql语句,有那么难吗?于是,我想还是自己写一个程序导入吧。虽然中间也遇到一些小插曲,但是还是成功地把数据导进去了。
程序的代码如下:
复制代码 代码如下:

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;
    }
    //创建500个线程
    ExecutorService  service=Executors.newFixedThreadPool(500);
    //读取sql文件     每五百个insert 语句由一个线程批量操作  
    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++;
            };
            //符合条件   开辟一个线程
            if(tag!=0&&tag/500!=0){
                service.execute(new SQLiteBatchHandler(batchSql));
                batchSql="";//reset
                tag=0;//reset
            }           
        }
        //最后执行 剩余的sql
        if(batchSql.length()>0){
            System.out.println("finalSQL:"+batchSql);
            Runnable r=new SQLiteBatchHandler(batchSql);
            service.execute(r);
        };
        try {
            //关闭线程池
            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  执行批量更新操作
     *        由于connection.comit 操作时   如果存在 statement没有close  就会报错   因此将此方法加上同步    。
     * */
    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("执行失败:"+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   主函数入口
     * */
    public  static  void main(String[] args) throws FileNotFoundException, IOException{
        BatchTool s=new BatchTool();
        s.readBatchSQL(new FileInputStream(new File("c:\\poi.sql")));
    }
}

相关文章

  • 将15位身份证补全为18位身份证的算法示例详解

    将15位身份证补全为18位身份证的算法示例详解

    这篇文章主要给大家介绍了关于将15位身份证补全为18位身份证算法的相关资料,文中通过示例代码给大家介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
    2017-06-06
  • Java 入门图形用户界面设计之单选按钮

    Java 入门图形用户界面设计之单选按钮

    图形界面(简称GUI)是指采用图形方式显示的计算机操作用户界面。与早期计算机使用的命令行界面相比,图形界面对于用户来说在视觉上更易于接受,本篇精讲Java语言中关于图形用户界面的单选按钮
    2022-02-02
  • java中sdk与jdk的区别详细解析

    java中sdk与jdk的区别详细解析

    以下是对java中sdk与jdk的区别进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-08-08
  • 解决dubbo错误ip及ip乱入问题的方法

    解决dubbo错误ip及ip乱入问题的方法

    今天小编就为大家分享一篇关于解决dubbo错误ip及ip乱入问题的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • elk之实现在kibana高效精准查询日志

    elk之实现在kibana高效精准查询日志

    这篇文章主要介绍了elk之实现在kibana高效精准查询日志方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Spring-Boot中如何使用多线程处理任务方法

    Spring-Boot中如何使用多线程处理任务方法

    这篇文章主要介绍了Spring-Boot中如何使用多线程处理任务方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • org.slf4j.Logger中info()方法的使用详解

    org.slf4j.Logger中info()方法的使用详解

    这篇文章主要介绍了org.slf4j.Logger中info()方法的使用详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java RateLimiter的限流详解

    Java RateLimiter的限流详解

    这篇文章主要为大家详细介绍了Java RateLimiter的限流,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 详解Spring的autowire-candidate设计

    详解Spring的autowire-candidate设计

    现在的Spring应用通常都是基于注解开发,但是对Spring感兴趣的同学可以借助Spring早期基于Xml配置的各种运用来加深对Spring框架内部的理解和体会Spring框架的设计之妙。这篇文章我们就来谈谈Xml配置之default-autowire-candidates
    2021-06-06
  • Java实例项目零钱通的实现流程

    Java实例项目零钱通的实现流程

    本篇文章为你带来Java的一个新手实战项目,是一个零钱通系统,项目来自于B站韩顺平老师,非常适合新手入门练习,感兴趣的朋友快来看看吧
    2022-03-03

最新评论