1. 程式人生 > >JDBC學習(七、批處理操作)

JDBC學習(七、批處理操作)

一、批量操作(batch)

    當需要成批插入或者更新記錄時,可以採用Java的批量更新機制,這一機制允許多條語句一次性提交給資料庫批量處理。通常情況下比單獨提交處理更有效率.


JDBC的批量處理語句包括下面兩個方法:
addBatch(String sql):新增需要批量處理的SQL語句或是引數;
executeBatch();執行批量處理語句;

通常我們會遇到兩種批量執行SQL語句的情況:
多條SQL語句的批量處理; :Statement
一個SQL語句的批量傳參; :PreparedStatement


需求:同時向t_student表,插入1000條資料,在JDBC中,MySQL不支援批量操作。
-------------------------------------------------------------------------
Statement 批處理 : 一次性可以執行多條sql語句,需要編譯多次。
應用場景:系統初始化 (建立表,建立資料等)
新增sql語句,st.addBatch(sql)   --新增sql語句
批量處理sql語句,int[] st.executeBatch()
清除快取: st.clearBatch();
-------------------------------------------------------------------------
PreparedStatement 批處理 : 執行一條sql語句,編譯一次,執行sql語句的引數不同。
應用場景:表資料初始化
新增批量引數:psmt.addBatch()    --新增實際引數,執行之前,需要執行psmt.setXxx()設定實際引數
執行批處理:int[] psmt.executeBatch()
清除快取:pstm.clearBatch();

1.使用Statement完成,沒有批處理


程式碼演示:

public void saveByStatement() {
	// 宣告資源物件
	Connection conn = null;
	Statement stmt = null;
	// 賈璉欲執事
	try {
		// 1.載入註冊驅動
		Class.forName("com.mysql.jdbc.Driver");
		// 2.獲取連線物件
		conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "rootroot");
		// 3.獲取語句物件
		stmt = conn.createStatement();
		// 迴圈5000次
		long begin = System.currentTimeMillis();
		for (int i = 0; i < 1000; i++) {
			String sql = "insert into t_student (name,age) values('a'," + i + ")";
			stmt.executeUpdate(sql);
		}
		long end = System.currentTimeMillis();
		System.out.println(end - begin);
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 5.釋放資源
		try {
			if (stmt != null) {
				stmt.close();
			}
			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

程式碼執行結果:

// InnoDB:2263ms
// MyISAM:300ms

2.使用Statement完成,使用批處理

程式碼演示:

        @Test
	public void BatchsaveByStatement() {
		// 宣告資源物件
		Connection conn = null;
		Statement stmt = null;
		// 賈璉欲執事
		try {
			// 1.載入註冊驅動
			Class.forName("com.mysql.jdbc.Driver");
			// 2.獲取連線物件
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "rootroot");
			// 3.獲取語句物件
			stmt = conn.createStatement();
			// 迴圈5000次
			long begin = System.currentTimeMillis();
			for (int i = 0; i < 1000; i++) {
				String sql = "insert into t_student (name,age) values('a'," + i + ")";
				// 將SQL新增到批處理中
				stmt.addBatch(sql);
				if (i % 200 == 0) {
					stmt.executeBatch();// 執行批量操作
					stmt.clearBatch();// 清除批處理
				}
			}
			long end = System.currentTimeMillis();
			System.out.println(end - begin);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 5.釋放資源
			try {
				if (stmt != null) {
					stmt.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

程式碼執行結果:

// InnoDB:1990ms
// MyISAM:387ms

3.使用PreparedStatement完成,沒有批處理

程式碼演示:

	public void saveByPreparedStatement() {
		// 宣告資源物件
		Connection conn = null;
		PreparedStatement ps = null;
		// 賈璉欲執事
		try {
			// 1.載入註冊驅動
			Class.forName("com.mysql.jdbc.Driver");
			// 2.獲取連線物件
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "rootroot");
			// 3.獲取語句物件
			String sql = "insert into t_student (name,age) values('a',?)";
			ps = conn.prepareStatement(sql);
			// 迴圈5000次
			long begin = System.currentTimeMillis();
			for (int i = 0; i < 1000; i++) {
				ps.setInt(1, i);
				ps.executeUpdate();
			}
			long end = System.currentTimeMillis();
			System.out.println(end - begin);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 5.釋放資源
			try {
				if (ps != null) {
					ps.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}	

程式碼執行結果:

// InnoDB:1793ms
// MyISAM:277ms

4.使用PreparedStatement完成,使用批處理

程式碼演示:

public void BatchsaveByByPreparedStatement() {
        // 宣告資源物件
        Connection conn = null;
        PreparedStatement ps = null;
        // 賈璉欲執事
        try {
            // 1.載入註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            // 2.獲取連線物件
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "rootroot");
            // 3.獲取語句物件
            String sql = "insert into t_student (name,age) values('a',?)";
            ps = conn.prepareStatement(sql);
            // 迴圈5000次
            long begin = System.currentTimeMillis();
            for (int i = 0; i < 1000; i++) {
                ps.setInt(1, i);
                ps.addBatch();
                if (i % 200 == 0) {
                    ps.executeBatch();
                    ps.clearBatch();
                    ps.clearParameters(); // 清除佔位符操作
                }

            }
            long end = System.currentTimeMillis();
            System.out.println(end - begin);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5.釋放資源
            try {
                if (ps != null) {
                    ps.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

程式碼執行結果:

// InnoDB:1793ms
// MyISAM:277ms

二、結論

  MySQL伺服器既不支援PreparedStatement的效能優化,也不支援JDBC中的批量操作.但是,在新的JDBC驅動中,我們可以通過設定引數來優化。

url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true

5.使用PreparedStatement完成,使用批處理,rewriteBatchedStatements=true

程式碼演示:

public void BatchsaveByByPreparedStatement2() {
        // 宣告資源物件
        Connection conn = null;
        PreparedStatement ps = null;
        // 賈璉欲執事
        try {
            // 1.載入註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            // 2.獲取連線物件
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true", "root", "rootroot");
            // 3.獲取語句物件
            String sql = "insert into t_student (name,age) values('a',?)";
            ps = conn.prepareStatement(sql);
            // 迴圈5000次
            long begin = System.currentTimeMillis();
            for (int i = 0; i < 1000; i++) {
                ps.setInt(1, i);
                ps.addBatch();
                if (i % 200 == 0) {
                    ps.executeBatch();
                    ps.clearBatch();
                    ps.clearParameters(); // 清除佔位符操作
                }

            }
            long end = System.currentTimeMillis();
            System.out.println(end - begin);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5.釋放資源
            try {
                if (ps != null) {
                    ps.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

程式碼執行結果:

// InnoDB:51ms
// MyISAM:29ms


相關推薦

JDBC學習處理操作

一、批量操作(batch)    當需要成批插入或者更新記錄時,可以採用Java的批量更新機制,這一機制允許多條語句一次性提交給資料庫批量處理。通常情況下比單獨提交處理更有效率.JDBC的批量處理語句包括下面兩個方法:addBatch(String sql):新增需要批量處理

JDBC學習事務處理操作

案例:銀行轉賬:從張無忌賬戶上給趙敏轉1000塊。準備:account(賬戶表):---------------------------------------------------------------id            name(賬號,唯一)         

Zookeeper學習zookeeper命令操作

1.zookeeper的四字命令 [[email protected] ~]# zkServer.sh start zoo1.cfg JMX enabled by default Using config: /usr/local/zk/bin/../conf/zoo1.cfg S

Hadoop學習記錄hadoop IO操作

1.壓縮從標準輸入讀取的資料,然後將其寫到標準輸出 通過GzipCodec的StreamCompressor物件對字串“Text”進行壓縮,再使用gunzip從標準輸出中對它進行讀取並解壓縮 public class StreamCompressor { public static

【Python+OpenCV入門學習軌跡條操作

本篇文章,將學習如何進行軌跡條操作。主要學習函式getTrackbarPos()和createTrackbar()使用。 環境:Windows 7(64)   python 3.6    opencv 3.4.2 一、瞭解函式 軌跡條使用起來非常的方便,通過滑鼠滑動軌跡

Spark基礎-scala學習型別引數

型別引數是什麼 類似於java泛型,泛型類 泛型函式 上邊界Bounds 下邊界 View Bounds Context Bounds Manifest Context Bounds 協變和逆變 Existential Type 泛型類 scala> :p

Python視訊學習Python高階

重點回顧: GIL鎖是CPython直譯器的問題 copy模組的deepcopy和copy方法對於tuple拷貝的區別 私有屬性的繼承問題和重整 Python物件的__mro__ ,以及導致的 sup

前端視訊學習JQuery

目錄 1. 第一個jquery 2. jQuery版本問題 3. jQuery入口函式 3.1 寫法 3.2 和js入口函式的區別 4. ★jsDom物件和JQ物件 4.1 JS偽陣列 4.2

JDBC學習DDLDML和DQL

 一、DDL操作    我們來建立一張學生表,欄位我們給id,name,age,要求id主鍵,自增程式碼演示:package sql; import java.sql.Connection; import java.sql.DriverManager; import jav

JDBC學習DAO思想和重構設計上

一、DAO設計思想什麼是DAO:主要就包括CRUD(增刪改查操作)    DAO(Data Access Object)是一個數據訪問介面,資料訪問:顧名思義就是與資料庫打交道。夾在業務邏輯與資料庫資源中間。    在核心J2EE模式中是這樣介紹DAO模式的:為了建立一個健壯

JDBC學習預編譯語句物件

一、PreparedStatement介面的常用方法是Statement的子介面,表示預編譯的 SQL 語句的物件.設定佔位符引數(告訴SQL中的?到底表示哪一個值): void  setXxx(int parameterIndex, Xxx value): xxx表示資料型

node.js學習express框架建立api介面

根據官方文件,用如下方式構造請求: app.get("/login/:username/:password",function (req, res) { console.log(req); res.send("get it");

Java編程思想復用類

ces java編程 語法 現在 運行 加載 沒有 調用 實例變量    復用代碼是Java眾多引人註目的功能之一。    復用類有兩個方法。第一種:只需在新的類中產生現有類的對象。由於新的類是由現有類的對象所組成,所以這種方法稱為組合。第二種:按照現有類的類型來創建新類。

JPA學習JPA_基本註解

自增 簡化 留言 uniq 產生 規範 pri blob 時間 框架學習之JPA(二) JPA是Java Persistence API的簡稱,中文名Java持久層API,是JDK 5.0註解或XML描述對象-關系表的映射關系,並將運行期的實體對象持久化到數據庫中。 Sun

spring cloud鏈路追蹤

Spring Cloud Sleuth 主要功能就是在分散式系統中提供追蹤解決方案,並且相容支援了 zipkin,zipkin為分散式鏈路呼叫監控系統,聚合各業務系統呼叫延遲資料,達到鏈路呼叫監控跟蹤。 隨著微服務數量不斷增長,它們之間的關係會越來越複雜,如果鏈路上任何一個服務出現問題或者網路超

Zookeeper學習Linux搭建zookeeper

1.zookeeper單機搭建 下載:wget http://mirrors.shu.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz 解壓:tar -zxvf zookeeper-3.4.12.tar.gz 配置檔案

Dubbo原始碼學習服務暴露ServiceBean

堅持一下,把原始碼看完,勤奮一點,不要在懶惰了,你已經落下別人很多了 環境配置: jdk  1.7.0.17 dubbo 2.5.x myeclipse 2014 idea 2017 ServiceBean  是針對<dubbo:service />標籤解析

操作系統學習 保護機制概述

長度 發的 之間 軟件開發 軟件 內存空間 工作 尋找 超級用戶 保護機制是可靠運行多任務環境所必須的。它可以用於保護各個任務免受互相之間的幹擾。在軟件開發的任何階段都可以使用段級和頁級保護來協助尋找和檢測設計問題和錯誤。當程序對錯誤內存空間執行了一次非期望的引用,保護機制

第一篇隨記:學習WAMP中最基礎的JDBC連線操作記錄 StatementPreparedStatement和CallableStatement

用Statement實現資料庫連線: <%@ page contentType="text/html" pageEncoding="UTF-8" %> <%@ page import="java.sql.*" %> <html>   <

JAVA學習:方法重載與方法重寫thiskeyword和superkeyword

格式 hello new 初始 per 而且 方法重寫 學習 方式 方法重載與方法重寫、thiskeyword和superkeyword 1、方法重載 重載可以使具有同樣名稱但不同數目和類型參數的類傳遞給方法。 註: 一是重載方法的參數列表必須與被重載的方法不同