一、單線程(單條循環)插入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();