一次執行多條SQL的技術要點如下:
-
DatabaseMetaData接口是描述有關數據庫的整體綜合信息,由於DatabaseMetaData是接口,所以沒有構造方法,故不能使用new來創建DatabaseMetaData對象,但是可以通過Connection的getMetaData()方法創建。例如:DatabaseMetaData md=con.getMetaData()。
-
DatabaseMetaData類的supportsBatchUpdates方法用於判斷此數據庫是否支持批量更新。其返回值類型為boolean,如果此數據庫支持批量更新,則返回true;否則返回false。
-
Statement的addBatch(String sql)方法將給定的SQL命令添加到此Statement對象的當前命令列表中,此方法可多次調用。
-
Statement的executeBatch()方法的作用是將一批命令提交給數據庫來執行,如果全部命令執行成功,則返回更新計數組成的數組。
1.java處理事務的程序
在與數據庫操作時,如果執行多條更新的SQL語句(如:update或insert語句),在執行第一條后如果出現異常或電腦斷電, 則后面的SQL語句執行不了,這時候設定我們自己提交SQL語句,不讓JDBC自動提交,格式為:
conn.setAutoCommit(false); stmt.addBatch("insert into people values(078,'ding','duo')"); stmt.addBatch("insert into people values(30,'nokia','ddd')"); stmt.executeBatch(); 執行多條SQL語句; conn.commit(); //事務提交 //恢復自動提交模式 conn.setAutoCommit(true); .... if (con != null) { con.rollback(); con.setAutoCommit(true); } //如果發現異常,則采取回滾
如果多條語句重復,只是參數不變的話可以這樣
特殊情況:如果是只是參數不變,如下也是一樣的
PreparedStatement ps=conn.prepareStatement("insert into temp values(?)"); ps.setInt(1, 100); ps.addBatch(); ps.setInt(1, 200); ps.addBatch(); ps.executeBatch();
package net.xsoftlab.dict; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Batch { /** 判斷數據庫是否支持批處理 */ public static boolean supportBatch(Connection con) { try { // 得到數據庫的元數據 DatabaseMetaData md = con.getMetaData(); return md.supportsBatchUpdates(); } catch (SQLException e) { e.printStackTrace(); } return false; } /** 執行一批SQL語句 */ public static int[] goBatch(Connection con, String[] sqls) throws Exception { if (sqls == null) { return null; } Statement sm = null; try { sm = con.createStatement(); for (int i = 0; i < sqls.length; i++) { sm.addBatch(sqls[i]);// 將所有的SQL語句添加到Statement中 } // 一次執行多條SQL語句 return sm.executeBatch(); } catch (SQLException e) { e.printStackTrace(); } finally { sm.close(); } return null; } public static void main(String[] args) throws Exception { System.out.println("沒有執行批處理時的數據為:"); query(); String[] sqls = new String[3]; sqls[0] = "UPDATE staff SET depart='Personnel' where name='mali'"; sqls[1] = "INSERT INTO staff (name, age, sex,address, depart, worklen,wage) VALUES ('mali ', 27, 'w', 'china','Technology','2','2300')"; sqls[2] = "DELETE FROM staff where name='marry'"; Connection con = null; try { con = getConnection();// 獲得數據庫連接 boolean supportBatch = supportBatch(con); // 判斷是否支持批處理 System.out.println("支持批處理? " + supportBatch); if (supportBatch) { int[] results = goBatch(con, sqls);// 執行一批SQL語句 // 分析執行的結果 for (int i = 0; i < sqls.length; i++) { if (results[i] >= 0) { System.out.println("語句: " + sqls[i] + " 執行成功,影響了" + results[i] + "行數據"); } else if (results[i] == Statement.SUCCESS_NO_INFO) { System.out.println("語句: " + sqls[i] + " 執行成功,影響的行數未知"); } else if (results[i] == Statement.EXECUTE_FAILED) { System.out.println("語句: " + sqls[i] + " 執行失敗"); } } } } catch (ClassNotFoundException e1) { throw e1; } catch (SQLException e2) { throw e2; } finally { con.close();// 關閉數據庫連接 } System.out.println("執行批處理后的數據為:"); query(); } public static Connection getConnection() {// 數據庫連接 Connection con = null; try { Class.forName("com.mysql.jdbc.Driver");// 加載Mysql數據驅動 con = DriverManager.getConnection( "jdbc:mysql://localhost:3306/myuser", "root", "123456");// 創建數據連接 } catch (Exception e) { System.out.println("數據庫連接失敗"); } return con; } public static void query() throws Exception {// 查詢所有的數據 Connection con = getConnection(); Statement st = con.createStatement(); ResultSet rs = st.executeQuery("select * from staff"); while (rs.next()) { String name = rs.getString("name"); int age = rs.getInt("age"); String sex = rs.getString("sex"); String address = rs.getString("address"); String depart = rs.getString("depart"); String worklen = rs.getString("worklen"); String wage = rs.getString("wage"); System.out.println(name + " " + age + " " + sex + " " + address + " " + depart + " " + worklen + " " + wage); } } }
程序解讀:
-
support_Batch()方法判斷數據庫是否支持SQL語句的批處理。通過Connection的getMetaData方法獲得數據庫的元數據對象DatabaseMetaData,再調用DatabaseMetaData supportsBatchUpdates方法判斷數據庫是否支持批處理。
-
startBatch()方法執行一組SQL語句。首先創建執行SQL語句的Statement對象,通過Statement類的addBatch方法將待執行SQL語句添加到執行緩沖區中,再調用executeBatch方法將執行緩沖區中的SQL語句全部執行,返回一個整型數組,如果數組元素的值大於等於0,則表示該語句執行成功,該值表示了執行該SQL語句修改的記錄的行數;如果數組元素的值等於Statement.SUCCESS_NO_INFO常量,表示該語句也執行成功,但不知道具體修改了多少條記錄;如果數組元素的值等於Statement.EXECUTE_FAILED常量,表示該語句執行失敗。
-
getConnection()方法封裝了數據庫的連接方式。如果在程序中需要使用數據庫,直接調用此方法即可。
-
query()方法的作用是查詢數據庫,傳入執行查詢語句的Statement對象和待執行的SQL語句,通過Statement的executeQuery方法執行SQL語句,返回一個ResultSet對象。再調用ResultSet的next()方法,根據字段名將數據取出,並打印在控制台上。