java執行多條SQL語句


一次執行多條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);
        }
    }
 
}

程序解讀:

  1. support_Batch()方法判斷數據庫是否支持SQL語句的批處理。通過Connection的getMetaData方法獲得數據庫的元數據對象DatabaseMetaData,再調用DatabaseMetaData supportsBatchUpdates方法判斷數據庫是否支持批處理。

  2. startBatch()方法執行一組SQL語句。首先創建執行SQL語句的Statement對象,通過Statement類的addBatch方法將待執行SQL語句添加到執行緩沖區中,再調用executeBatch方法將執行緩沖區中的SQL語句全部執行,返回一個整型數組,如果數組元素的值大於等於0,則表示該語句執行成功,該值表示了執行該SQL語句修改的記錄的行數;如果數組元素的值等於Statement.SUCCESS_NO_INFO常量,表示該語句也執行成功,但不知道具體修改了多少條記錄;如果數組元素的值等於Statement.EXECUTE_FAILED常量,表示該語句執行失敗。

  3. getConnection()方法封裝了數據庫的連接方式。如果在程序中需要使用數據庫,直接調用此方法即可。

  4. query()方法的作用是查詢數據庫,傳入執行查詢語句的Statement對象和待執行的SQL語句,通過Statement的executeQuery方法執行SQL語句,返回一個ResultSet對象。再調用ResultSet的next()方法,根據字段名將數據取出,並打印在控制台上。

 

2.寫成存儲過程

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM