当前位置: 首页 > news >正文

JDBC连接数据库:单线程、多线程、批处理插入数据的对比

 

一、单线程(单条循环)插入50000条记录:

每执行一次就要访问一次数据库

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


public class Test {

    public static void main(String[] args) {
        
         Connection conn;
         Statement stmt;
         ResultSet rs = null;
         String url = "jdbc:sqlserver://localhost:1433;DatabaseName=test;";
         String sql = "insert into student(name,age) values('wang',12)";
         try {
             // 连接数据库
             conn = DriverManager.getConnection(url, "sa", "123456");
             // 建立Statement对象
             stmt = conn.createStatement();
             /**
              * Statement createStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。
              */
             // 执行数据库查询语句
             long starttime=System.currentTimeMillis();
             for(int i=0; i<50000;i++){
                 stmt.executeUpdate(sql);
             }
             long spendtime=System.currentTimeMillis()-starttime;
             System.out.println( "单线程批处理花费时间:"+spendtime);
             /**
              * ResultSet executeQuery(String sql) throws SQLException 执行给定的 SQL
              * 语句,该语句返回单个 ResultSet 对象
              */
             if (rs != null) {
                 rs.close();
                 rs = null;
             }
             if (stmt != null) {
                 stmt.close();
                 stmt = null;
             }
             if (conn != null) {
                 conn.close();
                 conn = null;
             }
         } catch (SQLException e) {
             e.printStackTrace();
             System.out.println("数据库连接失败");
         }        
    }    
}

  

 

二、单线程(批处理)插入50000条记录:

stmt.addBatch():把要执行的多条sql语句放在一起,通过stmt.executeBatch()只访问一次数据库,就前面的多条sql语句一起插入

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Test {

    public static void main(String[] args) {
        
         Connection conn;
         Statement stmt;
         ResultSet rs = null;
         String url = "jdbc:sqlserver://localhost:1433;DatabaseName=test;";
         String sql = "insert into student(name,age) values('wang',12)";
         try {
             // 连接数据库
             conn = DriverManager.getConnection(url, "sa", "123456");
             // 建立Statement对象
             stmt = conn.createStatement();
             /**
              * Statement createStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。
              */
             // 执行数据库查询语句
             long starttime=System.currentTimeMillis();
             for(int i=0; i<50000;i++){
                 stmt.addBatch("insert into student(name,age) values('wang',12)"); 
             }
             stmt.executeBatch();
             long spendtime=System.currentTimeMillis()-starttime;
             System.out.println( "单线程批处理花费时间:"+spendtime);
             /**
              * ResultSet executeQuery(String sql) throws SQLException 执行给定的 SQL
              * 语句,该语句返回单个 ResultSet 对象
              */
             if (rs != null) {
                 rs.close();
                 rs = null;
             }
             if (stmt != null) {
                 stmt.close();
                 stmt = null;
             }
             if (conn != null) {
                 conn.close();
                 conn = null;
             }
         } catch (SQLException e) {
             e.printStackTrace();
             System.out.println("数据库连接失败");
         }  
    }    
}

 

执行后会发现:时间缩短很多

 

三、多线程(单条循环)插入50000条记录:

启动5个线程,每个线程插入10000条记录

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;


public class InsertTest {

      private String url="jdbc:sqlserver://localhost:1433;DatabaseName=test;";
        private String user="sa";
        private String password="123456";
        public Connection getConnect(){
            Connection con = null;
             try {
                Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                con=DriverManager.getConnection(url, user, password);
            } catch (Exception e) {
                e.printStackTrace();
            }
             return con;
        }
        public void multiThreadImport( final int ThreadNum){
            final CountDownLatch cdl= new CountDownLatch(ThreadNum);
            long starttime=System.currentTimeMillis();
            for(int k=1;k<=ThreadNum;k++){
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Connection con=getConnect();
                        try {
                            Statement st=con.createStatement();
                            for(int i=1;i<=10000;i++){
                                //st.addBatch("insert into student(name,age) values('wang',12)");
                                st.executeUpdate("insert into student(name,age) values('wang',12)");
                            }
                            //st.executeBatch();
                            cdl.countDown();
                        } catch (Exception e) {
                        }finally{
                            try {
                                con.close();
                            } catch (SQLException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
            }
            try {
                cdl.await();
                long spendtime=System.currentTimeMillis()-starttime;
                System.out.println( ThreadNum+"个线程花费时间:"+spendtime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

        public static void main(String[] args) throws Exception {
            InsertTest ti=new InsertTest();
            ti.multiThreadImport(5);
        }
}

 

四、多线程(批处理)插入50000条记录:

启动5个线程

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;


public class InsertTest {

	  private String url="jdbc:sqlserver://localhost:1433;DatabaseName=test;";
	    private String user="sa";
	    private String password="Rfid123456";
	    public Connection getConnect(){
	        Connection con = null;
	         try {
	            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
	            con=DriverManager.getConnection(url, user, password);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	         return con;
	    }
	    public void multiThreadImport( final int ThreadNum){
	        final CountDownLatch cdl= new CountDownLatch(ThreadNum);//定义线程数量
	        long starttime=System.currentTimeMillis();
	        for(int k=1;k<=ThreadNum;k++){
	            new Thread(new Runnable() {
	                @Override
	                public void run() {
	                    Connection con=getConnect();
	                    try {
	                        Statement st=con.createStatement();
	                        for(int i=1;i<=50000/ThreadNum;i++){
	                            st.addBatch("insert into student(name,age) values('wang',12)");
	                            if(i%500 == 0){
	                            	st.executeBatch();
	                            }
	                        }
	                        cdl.countDown();	//执行完一个线程,递减1
	                    } catch (Exception e) {
	                    }finally{
	                        try {
	                            con.close();
	                        } catch (SQLException e) {
	                            e.printStackTrace();
	                        }
	                    }
	                }
	            }).start();
	        }
	        try {
	            cdl.await();	//前面线程没执行完,其他线程等待,不往下执行
	            long spendtime=System.currentTimeMillis()-starttime;
	            System.out.println( ThreadNum+"个线程花费时间:"+spendtime);
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }

	    }

	    public static void main(String[] args) throws Exception {
	    	InsertTest ti=new InsertTest();
	        ti.multiThreadImport(5);
	    }
}

 

 

 

 

 

 

 

CountDownLatch:这个类能够使一个线程等待其他线程完成各自的工作后再执行。

(1)它通过一个计数器来实现的,计数器的初始值为线程的数量。

CountDownLatch cdl= new CountDownLatch(ThreadNum)

 

(2)每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,

cdl.countDown();

 

(3)然后在闭锁上等待的线程就可以恢复执行任务。

cdl.await();

 

转载于:https://www.cnblogs.com/Donnnnnn/p/7514813.html

相关文章:

  • VS2015 +EF6 连接MYSQL数据库生成实体
  • CF 840 D
  • 初识oracle存储过程
  • 大数据竞赛平台Kaggle案例实战
  • 我的Hibernate学习记录(一)
  • Java 读写Properties配置文件
  • 输出斐波那契数列前20项,每输出5个数换行
  • MySQL5.6安装步骤
  • 【转载】max/min函数的用法
  • Linux-Ubuntu下配置telnet环境
  • linux下git常用命令
  • 通过命令行操作MYSQL的方法 以及导入大的SQL备份文件
  • 简单的java socket 示例
  • anu - children
  • 嵌入式开发学习(10)汇编写启动代码之设置栈、调用c语言、开关看门狗和开关iCache...
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • CAP理论的例子讲解
  • ES6系列(二)变量的解构赋值
  • gulp 教程
  • Java,console输出实时的转向GUI textbox
  • Javascripit类型转换比较那点事儿,双等号(==)
  • java中具有继承关系的类及其对象初始化顺序
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • 我与Jetbrains的这些年
  • 延迟脚本的方式
  • ​HTTP与HTTPS:网络通信的安全卫士
  • (13):Silverlight 2 数据与通信之WebRequest
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • .NET delegate 委托 、 Event 事件,接口回调
  • /usr/lib/mysql/plugin权限_给数据库增加密码策略遇到的权限问题
  • @ComponentScan比较
  • @property python知乎_Python3基础之:property
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • [Angular] 笔记 9:list/detail 页面以及@Output
  • [BT]BUUCTF刷题第4天(3.22)
  • [C#]winform部署yolov9的onnx模型
  • [cocos creator]EditBox,editing-return事件,清空输入框
  • [cocos2d-x]关于CC_CALLBACK
  • [Deepin 15] 编译安装 MySQL-5.6.35
  • [Django 0-1] Core.Email 模块
  • [Google Guava] 2.1-不可变集合
  • [IE编程] 如何编程清除IE缓存
  • [Java][Android][Process] 暴力的服务能够解决一切,暴力的方式运行命令行语句
  • [JS]变量
  • [Machine Learning] 领域适应和迁移学习
  • [Open3d]: 知识记录
  • [python]使用pyqt5搭建yolov8 竹签计数一次性筷子计数系统
  • [python3] 装饰器
  • [VC++入门]指针一
  • [ZJCTF 2019]NiZhuanSiWei1
  • [zz]ubuntu 12.04 kvm+qemu 搭建虚拟机
  • [笔记].关于使用fscanf无法录入正确数据的原因分析