一次執行多條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()方法,根據字段名將數據取出,並打印在控制台上。
