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();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM