JDBC(2)

  • JDBC接口

接口java

應用場景mysql

Statementsql

當在運行時使用靜態 SQL 語句時(Statement接口不能接受的參數)數據庫

PrepareStatement

當計劃屢次使用 SQL 語句時(PreparedStatement 接口接收在運行時輸入參數)數組

CallableStatement併發

當要訪問數據庫中的存儲過程時(CallableStatement對象的接口還能夠接受運行時輸入參數)分佈式

 

  • Statement接口

一、boolean execute(String SQL)    性能

       若是 ResultSet 對象能夠被檢索返回布爾值 true,不然返回 false。使用這個方法來執行 SQL DDL 語句,或當須要使用真正的動態 SQLcode

二、int executeUpdate(String SQL)    對象

        用於執行 INSERT、UPDATE 或 DELETE 語句以及 SQLDDL(數據定義語言)語句。返回值是一個整數,指示受影響的行數(即更新計數)

三、ResultSet executeQuery(String SQL)    

       返回 ResultSet 對象。用於產生單個結果集的語句,例如 SELECT 語句

 

  • PrepareStatement接口

PreparedStatement 接口擴展了 Statement 接口,有利於高效地執行屢次使用的 SQL 語句

import java.sql.*;

public class JdbcTest {

   // JDBC 驅動器的名稱和數據庫地址

   static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; 

   static final String DB_URL = "jdbc:mysql://localhost/EXAMPLE";

   static final String USER = "root";

   static final String PASS = "";

   public static void main(String[] args) {

       Connection conn = null;

       PreparedStatement stmt = null;

       try{

           //註冊 JDBC 驅動器

           Class.forName("com.mysql.jdbc.Driver");

           //打開鏈接

           System.out.println("Connecting to database...");

           conn = DriverManager.getConnection(DB_URL,USER,PASS);

           //執行查詢

           System.out.println("Creating statement...");

           //這裏咱們要更改一個同窗的年齡,參數待定

           String sql = "UPDATE Students set age=? WHERE id=?";

           stmt = conn.prepareStatement(sql);

           //將值綁定到參數,參數從左至右序號爲1,2...

           stmt.setInt(1, 22);  // 綁定 age 的值(序號爲1)

           stmt.setInt(2, 1); // 綁定 ID 的值

           // 更新 ID 爲1的同窗的年齡

           int rows = stmt.executeUpdate();

           System.out.println("被影響的行數 : " + rows );

           // 查詢全部記錄,並顯示.

           sql = "SELECT id, name, age FROM Students";

           ResultSet rs = stmt.executeQuery(sql);

           //處理結果集

           while(rs.next()){

               //檢索

               int id  = rs.getInt("id");

               int age = rs.getInt("age");

               String name = rs.getString("name");

               //顯示

               System.out.print("ID: " + id);

               System.out.print(", Age: " + age);

               System.out.print(", Name: " + name);

               System.out.println();

           }

           //清理

           rs.close();

           stmt.close();

           conn.close();

       }catch(SQLException se){

           se.printStackTrace();

       }catch(Exception e){

           e.printStackTrace();

       }finally{

           try{

               if(stmt!=null)

                   stmt.close();

           }catch(SQLException se2){

           }

    try{

         if(conn!=null)

                 conn.close();

      }catch(SQLException se){

              se.printStackTrace();

          }

       }

           System.out.println("Goodbye!");

   }

}

 

  • CallableStatement接口

CallableStatement 對象爲全部的 DBMS 提供了一種以標準形式調用存儲過程的方法。存儲過程儲存在數據庫中。對儲存過程的調用是 CallableStatement 對象所含的內容。三種類型的參數有:IN,OUT和INOUT。

CallableStatement cstmt = null;

try {

   String SQL = "{call getEXAMPLEName (?, ?)}";

   cstmt = conn.prepareCall (SQL);

   . . .

}

catch (SQLException e) {

   . . .

}

finally {

   cstmt.close();

}
  • ResultSet結果集

結果集一般是經過執行查詢數據庫的語句生成,表示數據庫查詢結果的數據表。ResultSet 對象具備指向其當前數據行的光標。最初,光標被置於第一行以前。next 方法將光標移動到下一行;由於該方法在 ResultSet 對象沒有下一行時返回 false,因此能夠在 while 循環中使用它來迭代結果集。光標能夠方便咱們對結果集進行遍歷。默認的 ResultSet 對象不可更新,僅有一個向前移動的光標。所以,只能迭代它一次,而且只能按從第一行到最後一行的順序進行。

 

ResultSet接口的方法可分爲三類:

一、導航方法:用於移動光標

二、獲取方法:用於查看當前行的光標所指向的列中的數據

三、更新方法:用於更新當前行的列中的數據

 

JDBC 提供下列鏈接方法來建立所需的ResultSet語句:

createStatement(int RSType, int RSConcurrency);

prepareStatement(String SQL, int RSType, int RSConcurrency);

prepareCall(String sql, int RSType, int RSConcurrency);

RSType 表示 ResultSet 對象的類型,RSConcurrency 是 ResultSet 常量,用於指定一個結果集是否爲只讀或可更新。

ResultSet 的類型,若是不指定 ResultSet 類型,將自動得到一個是 TYPE_FORWARD_ONLY。

類型(RSType)

描述

ResultSet.TYPE_FORWARD_ONLY

遊標只能向前移動的結果集

ResultSet.TYPE_SCROLL_INSENTITIVE

遊標能夠向前和向後滾動,但不及時更新,就是若是數據庫裏的數據修改過,

並不在ResultSet中反應出來

ResultSet.TYPE_SCROLL_SENTITIVE

遊標能夠向前和向後滾動,並及時跟蹤數據庫的更新,以便更改ResultSet中的數據

 

併發(RSConcurrency)

描述

ResultSet.CONCUR_READ_ONLY

建立結果集只讀。默認

ResultSet.CONCUR_READ_UPDATABLE

建立一個可更新的結果集

好比初始化一個 Statement 對象來建立一個雙向、可更新的ResultSet對象:

try {

         Statement stmt = conn.createStatement(

                                 ResultSet.TYPE_SCROLL_INSENSITIVE,

                                 ResultSet.CONCUR_UPDATABLE);

      }

      catch(Exception ex) {

         ....

      }

      finally {

         ....

      }

 

  • 導航方法(用於光標的移動)

ResultSet接口中如下方法涉及遊標的移動:

實例代碼:

import java.sql.*;

public class JdbcTest {

   // JDBC 驅動器名稱 和數據庫地址

   static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";

   //數據庫的名稱爲 EXAMPLE

   static final String DB_URL = "jdbc:mysql://localhost/EXAMPLE";

   // 數據庫用戶和密碼

   static final String USER = "root";

   static final String PASS = "";

   public static void main(String[] args) {

       Connection conn = null;

       Statement stmt = null;

       try{

           //註冊JDBC 驅動程序

           Class.forName("com.mysql.jdbc.Driver");

           //打開鏈接

           System.out.println("Connecting to database...");

           conn = DriverManager.getConnection(DB_URL,USER,PASS);

           System.out.println("Creating statement...");

           //建立所需的ResultSet,雙向,只讀

           stmt = conn.createStatement(

                           ResultSet.TYPE_SCROLL_INSENSITIVE,

                           ResultSet.CONCUR_READ_ONLY);

           String sql;

           sql = "SELECT id, name, age FROM Students";

           ResultSet rs = stmt.executeQuery(sql);

           // 將光標移到最後一行

           System.out.println("Moving cursor to the last...");

           rs.last();

           //處理結果集

           System.out.println("Displaying record...");

           int id  = rs.getInt("id");

           int age = rs.getInt("age");

           String name = rs.getString("name");

           //顯示

           System.out.print("ID: " + id);

           System.out.print(", Age: " + age);

           System.out.print(", Name: " + name);

           System.out.println();

           // 將光標移到第一行

           System.out.println("Moving cursor to the first row...");

           rs.first();

           System.out.println("Displaying record...");

           id  = rs.getInt("id");

           age = rs.getInt("age");

           name = rs.getString("name");

           //顯示

           System.out.print("ID: " + id);

           System.out.print(", Age: " + age);

           System.out.print(", Name: " + name);

           //將光標移至下一行

           System.out.println("Moving cursor to the next row...");

           rs.next();

           System.out.println("Displaying record...");

           id  = rs.getInt("id");

           age = rs.getInt("age");

           name = rs.getString("name");

           // 顯示

           System.out.print("ID: " + id);

           System.out.print(", Age: " + age);

           System.out.print(", Name: " + name);

           rs.close();

           stmt.close();

           conn.close();

       }catch(SQLException se){

           se.printStackTrace();

       }catch(Exception e){

           e.printStackTrace();

       }finally{

           try{

               if(stmt!=null)

                   stmt.close();

           }catch(SQLException se2){

           }

           try{

               if(conn!=null)

                   conn.close();

           }catch(SQLException se){

               se.printStackTrace();

           }

       }

       System.out.println("Goodbye!");

   }

}

 

  • 獲取方法(獲取結果集的某填數據)

方法

說明

public int getInt(String columnName) throws SQLException

獲取當前行中名爲 ColumnName 列的值

public int getInt(int columnIndex) throws SQLException

獲取當前行中指定列的索引的值。列索引從1開始,

意味着一個行的第一列是1,行的第二列是2。

getString等方式相似。

 

 

  • 更新方法

一、更新結果集

方法

說明

public void updateString(String columnName,String s) throws SQLException

修改當前行中名爲 ColumnName 列的值爲s

public void updateString (int columnIndex,String s)) throws SQLException

修改當前行中指定列中索引的值爲s

updateDouble()等方式相似。

二、更新數據庫(在更新結果集以後)

方法

說明

public void updateRow()

將當前行記錄更新到數據庫

public  void deleteRow()

從數據庫刪除當前行

public  void refreshRow()

 用數據庫中的最近值刷新當前行

public  void cancelRowUpdates()

取消對 ResultSet 對象中的當前行所做的更新。此方法在調用更新方法以後,但在調用 updateRow 方法以前調用才能夠回滾對行所做的更新。若是沒有進行任何更新或者已經調用 updateRow 方法,則此方法無效

public  void insertRow()

將當前行記錄插入到數據庫

代碼示例:

Statement stmt = conn.createStatement(

        ResultSet.TYPE_SCROLL_INSENSITIVE,

        ResultSet.CONCUR_UPDATABLE);

String sql = "SELECT id, name, age FROM Students";

ResultSet rs = stmt.executeQuery(sql);

//將光標移動到一個特殊的行,能夠用來插入新行到結果集。當前光標位置被記住

rs.moveToInsertRow();

//結果集中插入新行

rs.updateInt("id",5);

rs.updateString("name","John");

rs.updateInt("age",21);

//將插入結果集的新行插入到數據庫中

rs.insertRow();

//將光標返回到當前行(返回到moveToInsertRow() 方法中被記住的光標位置)

rs.moveToCurrentRow();

 

  • JDBC事務

默認狀況下,JDBC鏈接是自動提交模式的,每條SQL語句執行完後自動提交到數據庫。

事務是一條或者多條SQL語句做爲一個邏輯單元,而且若是事務中任何語句執行失敗,則整個事務失敗。

本身管理和控制事務能夠:

一、提升程序的運行性能

二、保持業務流程的完整性

三、採用分佈式事務管理方式

 

事務的四大特性:(ACID)

一、原子性(Atomicity)

二、一致性(Consistency)

三、隔離性(Isolation)

四、持久性(Durability)

 

開啓JDBC事務須要關閉自動提交:

Connection conn = null;

conn = DriverManager.getConnection(URL);

//關閉自動提交

conn.setAutoCommit(false);

事務的提交:

conn.commit();

事務的回滾:

conn.rollBack();

 

代碼示例:

import java.sql.*;

public class JdbcTest {

   // JDBC 驅動器名稱 和數據庫地址

   static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; 

   //數據庫的名稱爲 EXAMPLE

   static final String DB_URL = "jdbc:mysql://localhost/EXAMPLE";

   //  數據庫用戶和密碼

   static final String USER = "root";

   static final String PASS = ""; 

   public static void main(String[] args) {

       Connection conn = null;

       Statement stmt = null;

       try{

           //註冊JDBC 驅動程序

           Class.forName("com.mysql.jdbc.Driver");

           //打開鏈接

           System.out.println("Connecting to database...");

           conn = DriverManager.getConnection(DB_URL,USER,PASS);

           conn.setAutoCommit(false); 

           //執行查詢

           System.out.println("Creating statement...");

           stmt = conn.createStatement();

           //插入

           String sql = "INSERT INTO Students  " +

                    "VALUES (5, 20, 'Rose')";

           stmt.executeUpdate(sql);

           //查找

           sql = "SELECT id, name, age FROM Students";

           ResultSet rs = stmt.executeQuery(sql);

           //提交事務

           conn.commit();

           //獲得和處理結果集

           while(rs.next()){

               //檢索

               int id  = rs.getInt("id");

               int age = rs.getInt("age");

               String name = rs.getString("name");

               //顯示

               System.out.print("ID: " + id);

               System.out.print(", Age: " + age);

               System.out.print(", Name: " + name);

               System.out.println();

           }

           //清理環境

           rs.close();

           stmt.close();

           conn.close();

       }catch(SQLException se){

           // JDBC 操做錯誤

           se.printStackTrace();

           // conn.rollback();

           try{

                 if(conn!=null)

                    conn.rollback();

              }catch(SQLException se2){

                 se2.printStackTrace();

              }

       }catch(Exception e){

           // Class.forName 錯誤

           e.printStackTrace();

       }finally{

           //這裏通常用來關閉資源的

           try{

               if(stmt!=null)

                   stmt.close();

           }catch(SQLException se2){

           }

           try{

               if(conn!=null)

                   conn.close();

           }catch(SQLException se){

               se.printStackTrace();

           }

       }

       System.out.println("Goodbye!");

   }

}

 

  • JDBC批處理

       批量處理容許將相關的SQL語句分組到批處理中,並經過對數據庫的一次調用來提交它們,一次執行完成與數據庫之間的交互。

       不須要JDBC驅動程序來支持此功能。應該使用DatabaseMetaData.supportsBatchUpdates()方法來肯定目標數據庫是否支持批量更新處理。若是JDBC驅動程序支持此功能,該方法將返回true。

 

  • 使用Statement對象進行批處理

一、使用createStatement()方法建立一個Statement對象

二、設置使用自動提交爲 false

三、添加任意多個SQL 語句到批量處理,使用addBatch()方法

四、使用executeBatch()方法,將返回一個整數數組,數組中的每一個元素表明了各自的更新語句的更新計數

五、最後,提交使用commit()方法的全部更改
 

//建立 statement 對象

Statement stmt = conn.createStatement();

//關閉自動提交

conn.setAutoCommit(false);

//建立 SQL 語句

String SQL = "INSERT INTO Students (id, name, age) VALUES(6,'Mike', 21)";

//將 SQL 語句添加到批處理中

stmt.addBatch(SQL);

//建立更多的 SQL 語句

String SQL = "INSERT INTO Students (id, name, age) VALUES(7, 'Angle', 23)";

//將 SQL 語句添加到 批處理中

stmt.addBatch(SQL);

//建立整數數組記錄更新狀況

int[] count = stmt.executeBatch();

//提交更改

conn.commit()

 

  • 使用prepareStatement對象進行批處理
String SQL = "INSERT INTO Employees (id, name, age) VALUES(?, ?, ?)";

//建立 PrepareStatement 對象

PreparedStatemen pstmt = conn.prepareStatement(SQL);

//關閉自動鏈接

conn.setAutoCommit(false);

//綁定參數

pstmt.setInt( 1, 8 );

pstmt.setString( 2, "Cindy" );

pstmt.setInt( 3, 17 );

//添入批處理

pstmt.addBatch();

//綁定參數

pstmt.setInt( 1, 9 );

pstmt.setString( 2, "Jeff" );

pstmt.setInt( 3, 22 );

//添入批處理

pstmt.addBatch();

//建立數組記錄更改

int[] count = pstmt.executeBatch();

//提交更改

conn.commit();
相關文章
相關標籤/搜索