接口java |
應用場景mysql |
Statementsql |
當在運行時使用靜態 SQL 語句時(Statement接口不能接受的參數)數據庫 |
PrepareStatement | 當計劃屢次使用 SQL 語句時(PreparedStatement 接口接收在運行時輸入參數)數組 |
CallableStatement併發 |
當要訪問數據庫中的存儲過程時(CallableStatement對象的接口還能夠接受運行時輸入參數)分佈式 |
一、boolean execute(String SQL) 性能
若是 ResultSet 對象能夠被檢索返回布爾值 true,不然返回 false。使用這個方法來執行 SQL DDL 語句,或當須要使用真正的動態 SQLcode
二、int executeUpdate(String SQL) 對象
用於執行 INSERT、UPDATE 或 DELETE 語句以及 SQLDDL(數據定義語言)語句。返回值是一個整數,指示受影響的行數(即更新計數)
三、ResultSet executeQuery(String SQL)
返回 ResultSet 對象。用於產生單個結果集的語句,例如 SELECT 語句
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 對象爲全部的 DBMS 提供了一種以標準形式調用存儲過程的方法。存儲過程儲存在數據庫中。對儲存過程的調用是 CallableStatement 對象所含的內容。三種類型的參數有:IN,OUT和INOUT。
CallableStatement cstmt = null; try { String SQL = "{call getEXAMPLEName (?, ?)}"; cstmt = conn.prepareCall (SQL); . . . } catch (SQLException e) { . . . } finally { cstmt.close(); }
結果集一般是經過執行查詢數據庫的語句生成,表示數據庫查詢結果的數據表。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鏈接是自動提交模式的,每條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!"); } }
批量處理容許將相關的SQL語句分組到批處理中,並經過對數據庫的一次調用來提交它們,一次執行完成與數據庫之間的交互。
不須要JDBC驅動程序來支持此功能。應該使用DatabaseMetaData.supportsBatchUpdates()方法來肯定目標數據庫是否支持批量更新處理。若是JDBC驅動程序支持此功能,該方法將返回true。
一、使用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()
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();