<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      JDBC的基本使用

      1、JDBC和JDBC驅(qū)動的基本概念

      JDBC(Java DataBase Connectivity),指 Java 數(shù)據(jù)庫連接,是一種標準Java應用編程接口(JAVA API),是 Java 語言用來連接和操作數(shù)據(jù)庫的。使用Java程序訪問數(shù)據(jù)庫時,Java代碼并不是直接通過TCP連接去訪問數(shù)據(jù)庫,而是通過JDBC接口來訪問。而JDBC接口則通過JDBC驅(qū)動來實現(xiàn)真正對數(shù)據(jù)庫的訪問。

      實際上,JDBC 就是官方定義的一套操作所有關系型數(shù)據(jù)庫的規(guī)則,也就是接口。而 JDBC 驅(qū)動就是實現(xiàn)了這些接口的實現(xiàn)類,各個數(shù)據(jù)庫廠商去實現(xiàn)這些接口,也就是 JDBC 驅(qū)動,提供數(shù)據(jù)庫驅(qū)動 jar 包,我們可以使用這套接口(JDBC)編程,真正執(zhí)行的代碼是驅(qū)動 jar 包中的實現(xiàn)類。

      JDBC 是一套接口規(guī)范,它在Java的標準庫java.sql里放著,不過這里面大部分都是接口。接口并不能直接實例化,而是必須實例化對應的實現(xiàn)類,然后通過接口引用這個實例。JDBC接口的實現(xiàn)類就是 JDBC 驅(qū)動。JDBC接口并不知道我們要使用哪個數(shù)據(jù)庫,所以,用哪個數(shù)據(jù)庫,我們就去使用哪個數(shù)據(jù)庫的“實現(xiàn)類”,我們把某個數(shù)據(jù)庫實現(xiàn)了JDBC接口的jar包稱為 JDBC 驅(qū)動

      例如,我們在Java代碼中要訪問MySQL,那么必須編寫代碼操作JDBC接口。注意到JDBC接口是Java標準庫自帶的,所以可以直接編譯。而具體的JDBC驅(qū)動是由數(shù)據(jù)庫廠商提供的,例如,MySQL的JDBC驅(qū)動由Oracle提供。因此,訪問某個具體的數(shù)據(jù)庫,我們只需要引入該廠商提供的JDBC驅(qū)動,就可以通過JDBC接口來訪問,這樣保證了Java程序編寫的是一套數(shù)據(jù)庫訪問代碼,卻可以訪問各種不同的數(shù)據(jù)庫,因為他們都提供了JDBC驅(qū)動:

      如果從代碼上來看,Java標準庫自帶的JDBC接口其實就是定義了一組接口,而某個具體的JDBC驅(qū)動其實就是實現(xiàn)了這些接口的類:

      實際上,一個MySQL的JDBC的驅(qū)動就是一個jar包,它本身也是純Java編寫的。我們自己編寫的代碼只需要引用Java標準庫提供的java.sql包下面的相關接口,由此再間接地通過MySQL驅(qū)動的jar包通過網(wǎng)絡訪問MySQL服務器,所有復雜的網(wǎng)絡通訊都被封裝到JDBC驅(qū)動中,因此,Java程序本身只需要引入一個MySQL驅(qū)動的jar包就可以正常訪問MySQL服務器:

      1.1、使用JDBC的好處

      JDBC API 是一個 Java API,它可以訪問任何類型的表格數(shù)據(jù),特別是可以訪問存儲在關系數(shù)據(jù)庫里的數(shù)據(jù)。JDBC 可以用 Java 語言在各種平臺上實現(xiàn),比如 Windows 系統(tǒng), Mac OS 系統(tǒng),和各種版本的 UNIX 系統(tǒng)。

      并且:

      • 各數(shù)據(jù)庫廠商使用相同的接口,Java代碼不需要針對不同數(shù)據(jù)庫分別開發(fā);

      • Java程序編譯期僅依賴java.sql包,不依賴具體數(shù)據(jù)庫的jar包;

      • 可隨時替換底層數(shù)據(jù)庫,訪問數(shù)據(jù)庫的Java代碼基本不變。

       

      2、下載導入 JDBC 驅(qū)動

      2.1、下載 JDBC 驅(qū)動

      可參考:http://www.rzrgm.cn/NyanKoSenSei/p/11510438.html

      2.2、將 JDBC 驅(qū)動導入項目

      將 JDBC 驅(qū)動導入項目就跟將普通的 jar 包導入項目一樣。下載完 JDBC 驅(qū)動后,將其解壓,可以看到里面有兩個 jar 包。

      在 java 項目中新建一個 lib 文件夾,將 JDBC 解壓后里面的 xxx.bin.jar 包復制到項目的 lib 文件夾中,右鍵要使用的jar包,選擇Build Path-->Add to Build Path,將其添加為項目依賴即可。

      可參考:https://jingyan.baidu.com/article/bad08e1e23982609c851219e.html

       

      3、使用JDBC操作數(shù)據(jù)庫

      構建一個 JDBC 應用程序包括以下六個步驟-

      • 導入數(shù)據(jù)包:需要你導入含有需要進行數(shù)據(jù)庫編程的 JDBC 類的包。大多數(shù)情況下,使用 import java.sql. 就足夠了。

      • 注冊 JDBC 驅(qū)動器:需要你初始化一個驅(qū)動器,以便于你打開一個與數(shù)據(jù)庫的通信通道。

      • 打開連接:需要使用 DriverManager.getConnection() 方法創(chuàng)建一個 Connection 對象,它代表與數(shù)據(jù)庫的物理連接。

      • 執(zhí)行查詢:需要使用類型聲明的對象建立并提交一個 SQL 語句到數(shù)據(jù)庫。

      • 提取結(jié)果數(shù)據(jù):要求使用適當?shù)?nbsp;ResultSet.getXXX() 方法從結(jié)果集中檢索數(shù)據(jù)。

      • 清理環(huán)境:依靠 JVM 的垃圾收集來關閉所有需要明確關閉的數(shù)據(jù)庫資源。

       

      3.1、操作數(shù)據(jù)庫代碼示例

      在導入驅(qū)動 jar 包后,我們就可以使用 JDBC 驅(qū)動來操作數(shù)據(jù)庫了。

      代碼示例:

      package jdbcTest;
      
      import java.net.URL;
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.SQLException;
      import java.sql.Statement;
      
      public class JDBCTest {
          public static void main(String[] args) throws Exception {
              //1.注冊驅(qū)動(mysql5之后的驅(qū)動jar包可以省略注冊驅(qū)動的步驟)
              Class.forName("com.mysql.jdbc.Driver");
              //2.獲取數(shù)據(jù)庫連接對象
              Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_test", "root", "123456");
              //3.定義sql語句
              String sql = "update students set name = 'hahaha' where id = 1";
              //4.獲取執(zhí)行sql的對象
              Statement stmt = conn.createStatement();
              //5.執(zhí)行sql
              int count = stmt.executeUpdate(sql);
              
              System.out.println(count);   
              //6.釋放資源
              stmt.close();
              conn.close();
          }
      }

      合理地 try{} catch(){} 的寫法:

      public static void main(String[] args) {
          Connection conn = null;
          Statement stmt = null;
          try {
              //1.注冊驅(qū)動(mysql5之后的驅(qū)動jar包可以省略注冊驅(qū)動的步驟)
              Class.forName("com.mysql.jdbc.Driver");
              //2.獲取數(shù)據(jù)庫連接對象
              conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_test", "root", "123456");
              //3.定義sql語句
              String sql = "update students set name = 'hahaha' where id = 1";
              //4.獲取執(zhí)行sql的對象
              stmt = conn.createStatement();
              //5.執(zhí)行sql
              int count = stmt.executeUpdate(sql);
              System.out.println(count); 
          } catch (Exception e) {
              e.printStackTrace();
          }finally {
              //6.釋放資源
              if(stmt != null) {
                  try {
                      stmt.close();
                  } catch (SQLException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
              
              if(conn != null) {
                  try {
                      conn.close();
                  } catch (SQLException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
              
          }
      }

       

      3.2、常用的 JDBC 組件介紹

      JDBC 的 API 提供了以下接口和類:

      DriverManager :這個類管理一系列數(shù)據(jù)庫驅(qū)動程序。匹配連接使用通信子協(xié)議從 JAVA 應用程序中請求合適的數(shù)據(jù)庫驅(qū)動程序。識別 JDBC 下某個子協(xié)議的第一驅(qū)動程序?qū)⒈挥糜诮?shù)據(jù)庫連接。

      Driver : 這個接口處理與數(shù)據(jù)庫服務器的通信。你將很少直接與驅(qū)動程序互動。相反,你使用 DriverManager 中的對象,它管理此類型的對象。它也抽象與驅(qū)動程序?qū)ο蠊ぷ飨嚓P的詳細信息。

      Connection : 此接口具有接觸數(shù)據(jù)庫的所有方法。該連接對象表示通信上下文,即,所有與數(shù)據(jù)庫的通信僅通過這個連接對象進行。

      Statement : 使用創(chuàng)建于這個接口的對象將 SQL 語句提交到數(shù)據(jù)庫。除了執(zhí)行存儲過程以外,一些派生的接口也接受參數(shù)。

      ResultSet : 在你使用語句對象執(zhí)行 SQL 查詢后,這些對象保存從數(shù)據(jù)獲得的數(shù)據(jù)。它作為一個迭代器,讓您可以通過它的數(shù)據(jù)來移動。

      SQLException : 這個類處理發(fā)生在數(shù)據(jù)庫應用程序的任何錯誤。

       

      3.3、先注冊 JDBC 驅(qū)動程序(mysql5之后的驅(qū)動程序可省略)

      在使用驅(qū)動程序之前,你必須在你的程序里面注冊它。我們可以通過加載 Oracle 驅(qū)動程序的類文件到內(nèi)存中來注冊驅(qū)動程序,在程序里做一次注冊即可。注冊驅(qū)動實際上就是告訴程序應該使用哪個數(shù)據(jù)庫驅(qū)動 jar 包。

      注冊一個驅(qū)動程序中最常用的方法是使用 Java 的 Class.forName() 方法來動態(tài)加載驅(qū)動程序的類文件到內(nèi)存中,它會自動將其注冊。

      try {
         Class.forName("oracle.jdbc.driver.OracleDriver");
      }
      catch(ClassNotFoundException ex) {
         System.out.println("Error: unable to load driver class!");
      }

      (注意:在mysql5之后的驅(qū)動jar包可以省略注冊驅(qū)動的步驟) 

       

      3.4、然后使用JDBC連接數(shù)據(jù)庫(Connection)

      要通過 JDBC 操作數(shù)據(jù)庫,我們需要先連接數(shù)據(jù)庫。當你加載了驅(qū)動程序之后,你可以通過 DriverManager.getConnection() 方法建立一個連接。Connection代表一個JDBC連接,它相當于 Java 程序到數(shù)據(jù)庫的連接(通常是TCP連接)。

      打開一個Connection時,需要準備URL、用戶名和密碼,才能成功連接到數(shù)據(jù)庫。

      數(shù)據(jù)庫連接的代碼示例如下:

      // JDBC連接的URL, 不同數(shù)據(jù)庫有不同的格式:
      String JDBC_URL = "jdbc:mysql://localhost:3306/test";  //URL
      String JDBC_USER = "root";           //用戶名
      String JDBC_PASSWORD = "password";   //密碼
      
      // 獲取連接
      Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);
      
      ...
      
      // 最后需關閉連接
      conn.close();

      核心代碼是DriverManager提供的靜態(tài)方法getConnection()DriverManager會自動掃描classpath,找到所有的JDBC驅(qū)動,然后根據(jù)我們傳入的URL自動挑選一個合適的驅(qū)動。

      JDBC連接是一種昂貴的資源,使用后要及時釋放。可以使用try (resource)來自動釋放JDBC連接:

      try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD)) {
             ...
      }

      在 JDBC 程序的末尾,它必須明確關閉所有的連接到數(shù)據(jù)庫的連接,以結(jié)束每個數(shù)據(jù)庫會話。但是,如果忘了,Java 垃圾收集器也會關閉連接,它會完全清除過期的對象。依托垃圾收集器,特別是在數(shù)據(jù)庫編程,是非常差的編程習慣,我們應該養(yǎng)成用 close()方法關閉連接對象的習慣。

       

      3.4.1、數(shù)據(jù)庫連接的URL格式

      URL是由數(shù)據(jù)庫廠商指定的格式,例如,MySQL的URL是:

      jdbc:mysql://服務器IP:端口號/數(shù)據(jù)庫名稱?key1=value1&key2=value2

      假設數(shù)據(jù)庫運行在本機localhost,端口使用標準的3306,數(shù)據(jù)庫名稱是learnjdbc。示例如下:

      jdbc:mysql://localhost:3306/learnjdbc?useSSL=false&characterEncoding=utf8
      
      # 如果連接的是本地服務器,并且服務器默認端口是3306,那么可以簡寫為以下形式,即省略服務器地址和端口號:
      jdbc:mysql:///數(shù)據(jù)庫名稱

      (后面的兩個參數(shù)表示不使用SSL加密,使用UTF-8作為字符編碼(注意MySQL的UTF-8是utf8),不寫也行) 

      下表列出了常用的 JDBC 驅(qū)動程序名和數(shù)據(jù)庫URL。

      上表中 URL 格式所有加粗的部分都是靜態(tài)的,你需要將剩余部分按照你的數(shù)據(jù)庫實際情況進行設置。

       

      3.4.2、如何創(chuàng)建連接對象

      我們可以通過 DriverManager.getConnection() 方法來建立一個數(shù)據(jù)庫連接,加載 DriverManager.getConnection() 參數(shù)有以下三種:

      1. getConnection(String url)
      2. getConnection(String url, Properties prop)
      3. getConnection(String url, String user, String password)

      使用URL、用戶名、密碼:getConnection() 最常用的方式是需要你提供一個數(shù)據(jù)庫 URL,用戶名和密碼:

      String URL = "jdbc:oracle:thin:@amrood:1521:EMP";
      String USER = "username";
      String PASS = "password"
      Connection conn = DriverManager.getConnection(URL, USER, PASS);

      只使用URL:在只使用url時,數(shù)據(jù)庫的 URL ,包括用戶名和密碼,將表現(xiàn)為以下的格式:

      jdbc:oracle:driver:username/password@database

      示例:

      String URL = "jdbc:oracle:thin:username/password@amrood:1521:EMP";
      Connection conn = DriverManager.getConnection(URL);

      使用數(shù)據(jù)庫 URL 和 Properties 對象:Properties 對象保存了一組關鍵數(shù)值。它通過調(diào)用 getConnection() 方法,將驅(qū)動程序?qū)傩詡鬟f給驅(qū)動程序。

      import java.util.*;
      
      String URL = "jdbc:oracle:thin:@amrood:1521:EMP";
      Properties info = new Properties( );
      info.put( "user", "username" );
      info.put( "password", "password" );
      
      Connection conn = DriverManager.getConnection(URL, info);

       

      3.5、獲取執(zhí)行sql的對象并且執(zhí)行sql

      一旦我們獲得了數(shù)據(jù)庫的連接,我們就可以和數(shù)據(jù)庫進行交互。JDBC 的 Statement,CallableStatement 和 PreparedStatement 接口定義的方法和屬性,可以讓你發(fā)送 SQL 命令或 PL/SQL 命令到數(shù)據(jù)庫,并從你的數(shù)據(jù)庫接收數(shù)據(jù)。在數(shù)據(jù)庫中,它們還定義了幫助 Java 和 SQL 數(shù)據(jù)類型之間轉(zhuǎn)換數(shù)據(jù)差異的方法。

      下表提供了每個接口的用途概要,根據(jù)實際目的決定使用哪個接口。

       

      查詢數(shù)據(jù)庫可以分為以下幾步:

      第一步,通過Connection提供的createStatement()方法創(chuàng)建一個Statement對象,用于執(zhí)行一個查詢;

      第二步,執(zhí)行Statement對象提供的executeQuery("SELECT * FROM students")并傳入SQL語句,執(zhí)行查詢并獲得返回的結(jié)果集,使用ResultSet來引用這個結(jié)果集;

      第三步,反復調(diào)用ResultSetnext()方法并讀取每一行結(jié)果。

      完整查詢代碼如下:

      try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD)) {
          try (Statement stmt = conn.createStatement()) {
              try (ResultSet rs = stmt.executeQuery("SELECT id, grade, name, gender FROM students WHERE gender=1")) {
                  while (rs.next()) {
                      long id = rs.getLong(1); // 注意:索引從1開始
                      long grade = rs.getLong(2);
                      String name = rs.getString(3);
                      int gender = rs.getInt(4);
                  }
              }
          }
      }

      注意要點:

      StatmentResultSet都是需要關閉的資源,因此嵌套使用try (resource)確保及時關閉;rs.next()用于判斷是否有下一行記錄,如果有,將自動把當前行移動到下一行(一開始獲得ResultSet時當前行不是第一行);ResultSet獲取列時,索引從1開始而不是0;必須根據(jù)SELECT的列的對應位置來調(diào)用getLong(1)getString(2)這些方法,否則對應位置的數(shù)據(jù)類型不對,將報錯。

       

      3.5.1、使用 Statement 對象來操作數(shù)據(jù)庫

      在你準備使用 Statement 對象執(zhí)行 SQL 語句之前,你需要使用 Connection 對象的 createStatement() 方法先創(chuàng)建一個 Statement 對象。

      Connection conn = DriverManager.getConnection(URL, 用戶名, 密碼);
      Statement stmt = conn.createStatement( );

      當你創(chuàng)建了一個 Statement 對象之后,你可以用它的三個執(zhí)行方法的任一方法來執(zhí)行 SQL 語句。

      • boolean execute(String SQL) : 該方法可以執(zhí)行任何的SQL語句。如果第一個結(jié)果是一個 ResultSet 對象,則返回的布爾值為 true ,否則返回 false 。當你需要使用真正的動態(tài) SQL 時,可以使用這個方法來執(zhí)行 SQL DDL 語句。

      • int executeUpdate(String SQL) : 常用該方法來執(zhí)行DML語句(增刪改),也可執(zhí)行DDL語句(操作數(shù)據(jù)庫和表結(jié)構)。它返回的是執(zhí)行 SQL 語句影響的行的數(shù)目。

      • ResultSet executeQuery(String SQL) : 常用該方法執(zhí)行DQL語句(查詢),它返回一個 ResultSet 對象。
      String sql = "update students set name = 'hahaha' where id = 1";
      Statement stmt = conn.createStatement();
      int count = stmt.executeUpdate(sql);

      在使用后我們應該關閉 Statement 對象。通過調(diào)用 close() 方法就可以關閉 Statement 對象。其實在我們關閉了 Connection 對象后,它也會自動關閉 Statement 對象。但我們應該始終明確關閉 Statement 對象,以確保真正的清除。

      Statement stmt = null;
      try {
         stmt = conn.createStatement( );
         . . .
      }
      catch (SQLException e) {
         . . .
      }
      finally {
         stmt.close();
      }

       

      3.5.2、使用PreparedStatement對象操作數(shù)據(jù)庫

      PreparedStatement 接口擴展了 Statement 接口,它讓你用一個常用的 Statement 對象增加幾個高級功能。這個 statement 對象可以提供靈活多變的動態(tài)參數(shù)。

      創(chuàng)建 PreparedStatement 對象:

      String SQL = "Update Employees SET age = ? WHERE id = ?";
      PreparedStatement pstmt = conn.prepareStatement(SQL);

      JDBC 中所有的參數(shù)都被用 ? 符號表示,這是已知的參數(shù)標記。在執(zhí)行 SQL 語句之前,你必須賦予每一個參數(shù)確切的數(shù)值。

      setXXX() 方法將值綁定到參數(shù),其中 XXX 表示你希望綁定到輸入?yún)?shù)的 Java 數(shù)據(jù)類型。如果你忘了賦予值,你將收到一個 SQLException。每個參數(shù)標記映射它的序號位置。第一標記表示位置 1 ,下一個位置為 2 等等。這種方法不同于 Java 數(shù)組索引,它是從 0 開始的。

      String sql = "SELECT * FROM user WHERE login=? AND pass=?";
      PreparedStatement ps = conn.prepareStatement(sql);
      ps.setObject(1, name);
      ps.setObject(2, pass);

      所有的 Statement對象 的方法都與數(shù)據(jù)庫交互,(a) execute(),(b) executeQuery(),及 (c) executeUpdate() 也能被 PreparedStatement 對象引用。然而,這些方法被 SQL 語句修改后是可以輸入?yún)?shù)的。

      PreparedStatement 對象在使用后也需要關閉,只需簡單調(diào)用 close() 方法就可以完成這項工作。如果你關閉了 Connection 對象,那么它也會關閉 PreparedStatement 對象。然而,你應該始終明確關閉 PreparedStatement 對象,以確保真正的清除。

       

      4、JDBC事務

      數(shù)據(jù)庫事務(Transaction)是由若干個SQL語句構成的一個操作序列,有點類似于Java的synchronized同步。數(shù)據(jù)庫系統(tǒng)保證在一個事務中的所有SQL要么全部執(zhí)行成功,要么全部不執(zhí)行,即數(shù)據(jù)庫事務具有ACID特性:

      • Atomicity:原子性
      • Consistency:一致性
      • Isolation:隔離性
      • Durability:持久性

      數(shù)據(jù)庫事務可以并發(fā)執(zhí)行,而數(shù)據(jù)庫系統(tǒng)從效率考慮,對事務定義了不同的隔離級別。SQL標準定義了4種隔離級別,分別對應可能出現(xiàn)的數(shù)據(jù)不一致的情況:

       

      4.1、JDBC管理事務

      要在JDBC中執(zhí)行事務,本質(zhì)上就是如何把多條SQL包裹在一個數(shù)據(jù)庫事務中執(zhí)行。

      在 JDBC 中,我們可以使用 connection 對象來管理事務,connection 對象提供了3個方法來進行事務管理:

      • setAutoCommit():設置是否自動提交,方法中需要傳入一個boolean類型的參數(shù),true為自動提交,false為手動提交。進行事務管理時,應該在所有sql執(zhí)行前設置為false,此時意味著開啟了事務

      • commit():主動提交事務。應該在當所有sql執(zhí)行完畢時調(diào)用該方法主動提交事務。

      • rollback():回滾事務。應該在捕獲異常時調(diào)用giant方法來回滾事務。

      偽代碼:

      Connection conn = openConnection();
      try {
          // 關閉自動提交,即開啟事務
          conn.setAutoCommit(false);
          // 執(zhí)行多條SQL語句:
          insert(); update(); delete();
          // 提交事務:
          conn.commit();
      } catch (SQLException e) {
          // 回滾事務:
          conn.rollback();
      } finally {
          conn.setAutoCommit(true);  //最后恢復至自動提交
          conn.close();
      }

      在MySQL中,默認會自動提交事務,也就是任意一條SQL語句都會被當做是一個事務,并且自動提交,所以需要主動將自動提交關閉掉。使用 conn.setAutoCommit(false) 來關閉自動提交,即開啟事務。執(zhí)行完指定的若干條SQL語句后,我們可以調(diào)用 conn.commit() 來提交事務。如果事務提交失敗,此時我們可以調(diào)用conn.rollback()來回滾事務。最后,在finally中通過conn.setAutoCommit(true)Connection對象的狀態(tài)恢復到初始值。

      實例代碼如下:

      public void jdbcTest2() {
          Connection conn = null;
          PreparedStatement ps1 = null;
          PreparedStatement ps2 = null;
      
          try {
              Class.forName("com.mysql.jdbc.Driver");
              conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_test", "root", "123456");
      
              //關閉自動提交,開啟事務
              conn.setAutoCommit(false);
      
              //多條sql
              String updatesql1 = "update userbalance set money = money - ? where username = ?";
              ps1 = conn.prepareStatement(updatesql1);
              ps1.setBigDecimal(1, new BigDecimal(500));
              ps1.setString(2, "zhangsan");
      
              String updatesql2 = "update userbalance set money = money + ? where username = ?";
              ps2 = conn.prepareStatement(updatesql2);
              ps2.setBigDecimal(1, new BigDecimal(500));
              ps2.setString(2, "lisi");
      
              //執(zhí)行sql
              int count1 = ps1.executeUpdate();
              //模擬異常
              int a = 5 / 0;
              int count2 = ps2.executeUpdate();
      
              //提交事務
              conn.commit();
      
              System.out.println("結(jié)果:" + count1 + count2);
      
          } catch (Exception e) {
              e.printStackTrace();
      
              //在異常出現(xiàn)時需要回滾事務
              try {
                  conn.rollback();
              } catch (SQLException ex) {
                  ex.printStackTrace();
              }
      
          } finally {
              //最后需要恢復至自動提交
              try {
                  conn.setAutoCommit(true);
              } catch (SQLException e) {
                  e.printStackTrace();
              }
      
              //釋放資源。為了避免空指針異常,必須先判斷是否為null
              if(ps1 != null) {
                  try {
                      ps1.close();
                  } catch (SQLException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
      
              if(ps2 != null) {
                  try {
                      ps2.close();
                  } catch (SQLException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
      
              if(conn != null) {
                  try {
                      conn.close();
                  } catch (SQLException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
          }
      }

       

      4.2、JDBC定義事務的隔離級別

      如果要設定事務的隔離級別,可以使用如下代碼:

      // 設定隔離級別為READ COMMITTED:
      conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

      如果沒有調(diào)用上述方法,那么會使用數(shù)據(jù)庫的默認隔離級別。MySQL的默認隔離級別是REPEATABLE READ

       

      posted @ 2020-07-27 23:26  wenxuehai  閱讀(871)  評論(0)    收藏  舉報
      //右下角添加目錄
      主站蜘蛛池模板: 综合色天天久久| 69精品无人区国产一区| 亚洲国产成人久久精品不卡| 少妇高潮喷潮久久久影院| 2021久久精品国产99国产精品| 黄色大全免费看国产精品| 涩涩爱狼人亚洲一区在线| 忍着娇喘人妻被中出中文字幕| 四虎国产精品永久入口| 国产精品爱久久久久久久电影| 99国产欧美另类久久久精品| 精品无码中文视频在线观看| 国产伦一区二区三区久久| 成人深夜节目在线观看| 亚洲色大成网站www永久男同| 欧美xxxxhd高清| 久久精品国产精品亚洲综合| 最新日韩精品视频在线| 亚洲人成网线在线播放VA| 国产成人精品2021欧美日韩| 韩国精品久久久久久无码| 久久久久久性高| 国产精品免费第一区二区| 亚洲精品麻豆一二三区| 国产精品1区2区3区在线观看| 国产一区二区三区高清视频| 制服丝袜美腿一区二区| 熟女丝袜潮喷内裤视频网站| 亚洲精品国产一区二区在线观看| 亚洲精品无码久久一线| 潮喷无码正在播放| 成人3d动漫一区二区三区| 日韩在线视频一区二区三| 国产精品福利中文字幕| 国产精品亚洲аv无码播放 | 国产日韩av二区三区| 国产成人亚洲精品成人区| 亚洲gv猛男gv无码男同| 亚洲av成人精品日韩一区| 国产亚洲精品AA片在线播放天 | 非会员区试看120秒6次|