茫茫網海中的冷日 - 對這文章發表回應
茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1675450 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_00124.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

對這文章發表回應

發表限制: 非會員 可以發表

發表者: 冷日 發表時間: 2019/7/29 13:14:40
PreparedStatement: How to insert data into multiple tables using JDBC

Could somebody tell me whether the first stmt.close(); required in the following JDBC code, for executing two different SQL queries against two different tables?
public class MyService {
    private Connection connection = null;

    public void save(Book book) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "password");

            PreparedStatement stmt = connection.prepareStatement("INSERT INTO PUBLISHER (CODE, PUBLISHER_NAME) VALUES (?, ?)");
            stmt.setString(1, book.getPublisher().getCode());
            stmt.setString(2, book.getPublisher().getName());
            stmt.executeUpdate();

            stmt.close(); //1

            stmt = connection.prepareStatement("INSERT INTO BOOK (ISBN, BOOK_NAME, PUBLISHER_CODE) VALUES (?, ?, ?)");
            stmt.setString(1, book.getIsbn());
            stmt.setString(2, book.getName());
            stmt.setString(3, book.getPublisher().getCode());
            stmt.executeUpdate();

            stmt.close(); //2
        } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }
        finally { connection.close(); }
    }
}


In my book, I would always recommend closing resources that have been opened to avoid possible leaks.
A slightly more modern way would be to use try-with-resources:
try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "password")) {

    try (PreparedStatement stmt = connection.prepareStatement("INSERT INTO PUBLISHER (CODE, PUBLISHER_NAME) VALUES (?, ?)")) {
        stmt.setString(1, book.getPublisher().getCode());
        stmt.setString(2, book.getPublisher().getName());
        stmt.executeUpdate();
    }
    // stmt is auto closed here, even if SQLException is thrown

    try (PreparedStatement stmt = connection.prepareStatement("INSERT INTO BOOK (ISBN, BOOK_NAME, PUBLISHER_CODE) VALUES (?, ?, ?)");
        stmt.setString(1, book.getIsbn());
        stmt.setString(2, book.getName());
        stmt.setString(3, book.getPublisher().getCode());
        stmt.executeUpdate();
    }
    // stmt is auto closed here, even if SQLException is thrown
}
// connection is auto closed here, even if SQLException is thrown


It is a common misconception with statements that closing them releases all that preparing them built. This is wrong. The optimisation that results in the preparation of the statement is performed by the database. It is then stored/cached by the database and usually re-used next time the statement is prepared.
As a result, prepared statements can be closed and prepared as often as you wish - the database will recognise the same statement next time around and recover the cached preparations it made last time - if it wishes to.
In summary - yes, statements should be closed - and no, this does not reduce the effectiveness of your queries.

It is not required but it is recommended. http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#close()
The next line after the first close() in your code assigns a new value to the reference stmt, so the object you use to execute the first insert will be GC'd and closed eventually. It is good practice to go ahead and close it when you know you're done with it. This releases the JDBC resources immediately.

Its good practice to close the Statement handle as it will release the JDBC & Database resources. You can read more about stmt.close() here
I would like to point out that its good to close your Statement object in finally block so that DB resources are released even if an Exception occurs.

Yes, both the stmt.close() methods are necessary. You should always explicitly close the Statement or PreparedStatement object to ensure proper cleanup.

 try{
     String insertIntoCust = "insert into NORTHWIND_CUSTOMER(CUSTOMER_ID,FIRST_NAME,LAST_NAME,ADDRESS,CITY,STATE,POSTAL_CODE) values(?,?,?,?,?,?)";
     pst = connect.prepareStatement(insertIntoCust);
     pst.setString(1, txtCustomerId.getText());
     pst.setString(2, txtFirstName.getText());
     pst.setString(3, txtLastName.getText());
     pst.setString(4, txtAddress2.getText());
     pst.setString(5, txtCity.getText());
     pst.setString(6, txtState.getText());
     pst.setString(7, txtPostalCode.getText());

     pst.execute();

     String insertIntoOrder = "insert into NORTHWIND_ORDER(ORDER_ID,ORDER_DATE) values(?,?)";
     pst = connect.prepareStatement(insertIntoOrder);
     pst.setString(1, txtOrderId.getText());
     pst.setString(2, txtOrderDate.getText());

     pst.execute();
     JOptionPane.showMessageDialog(null, "Saved");
 }catch(Exception e){
     JOptionPane.showMessageDialog(null, e);
 }

With the code above, I could insert data into multiple tables with one button. The pst.execute need to be inserted in both queries; if not, the query that have the pst.execute is the table that will receive the data.
shareimprove this answer

原文出處:java - PreparedStatement: How to insert data into multiple tables using JDBC - Stack Overflow
內容圖示
url email imgsrc image code quote
樣本
bold italic underline linethrough   












 [詳情...]
validation picture

注意事項:
預覽不需輸入認證碼,僅真正發送文章時才會檢查驗證碼。
認證碼有效期10分鐘,若輸入資料超過10分鐘,請您備份內容後,重新整理本頁並貼回您的內容,再輸入驗證碼送出。

選項

Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|