簡體   English   中英

Single Try Catch Block中的多個JDBC語句。 這是好的做法嗎?

[英]Multiple JDBC Statements in Single Try Catch Block. is it Good Practice?

我是Java新手,我的工作都與JDBC有關 - 關於插入和處理數據。 在它的所有工作正常。

使用單個try{} catch()塊來編寫多個JDBC StatementsPrepared Statements來減少代碼。

示例代碼:

public void dashboardReports()
{
    try {

        String total_stock_value="select sum(price*closingstock)as tsv from purchase_table";
        Statement ps_tsv=connection.createStatement();
        ResultSet set_tsv=ps_tsv.executeQuery(total_stock_value);
        if(set_tsv.next())
        {
            total_stock.setText(set_tsv.getString("tsv"));              
        }           

        String tota_sales="select sum(INVOICE_VALUE) as iv from  PARTYWISE_ACCOUNTS_LEDGER";
        Statement st_total_sales=connection.createStatement();
        ResultSet set_total_sales=st_total_sales.executeQuery(tota_sales);
        if(set_total_sales.next())
        {
            total_sales.setText(set_total_sales.getString("iv"));
        }           

        String total_purchases="select sum(CP_INVOICEVALUE)as cpi from COMPANY_PAYMENTS";
        Statement st_tps=connection.createStatement();
        ResultSet set_tps=st_tps.executeQuery(total_purchases);
        if(set_tps.next())
        {
            total_purchases_label.setText(set_tps.getString("cpi"));
        }

        String total_collectionss="select sum(PAYMENT_REC) as payrec from PARTYWISE_ACCOUNTS_LEDGER";
        Statement ps_toco=connection.createStatement();
        ResultSet set_toco=ps_toco.executeQuery(total_collectionss);
        if(set_toco.next())
        {
            total_collections.setText(set_toco.getString("payrec"));
        }

        String total_payments="select sum(CP_PAYMENTREC) as paid from COMPANY_PAYMENTS";
        Statement ps_topa=connection.createStatement();
        ResultSet set_topa=ps_topa.executeQuery(total_payments);
        if(set_topa.next())
        {
            total_payments_label.setText(set_topa.getString("paid"));
        }

    } catch (Exception e) {
        // TODO: handle except
    }
}

這是處理的好方法還是其他方式?

到目前為止,我的代碼工作得非常好,我們對這種方法有任何未來的問題。

這違反了單一責任單層抽象原則。

雖然這段代碼在技術上是有效的; 你不僅應該關注它的正確性 ,還要關注它的可讀性。 和可測試性。 而且我認為你所展示的輸入中都沒有“偉大”。

從而; 來自干凈的代碼(質量)觀點; 我寧願建議采取以下措施:

outer method ...
  try {
    helperMethod1();
    helperMethod2();
  } catch( ...

你可以在那里找到每個不同案例的小幫手。 當然,你不會止步於此; 但試着隔離那些助手的共同方面; 並且可能想方設法使用單一的,更通用的幫助器。

當然:如果可能的話,你盡量避免捕獲異常 相反,您可以捕獲最具體的異常!

由於您只在這里進行SELECT操作,因此不需要顯式事務,因為您沒有更改數據庫的狀態,也沒有什么可以回滾。 將所有SELECT語句分組到單個try塊中沒有任何問題。 但是,存在一個潛在的缺點,即如果一個SELECT失敗,您的代碼將退出該try塊,並且所有后續查詢都不會運行。 如果你可以容忍這一點,那么你可以保持原樣。 與此相似的是一系列連續串聯的燈泡; 如果一個人休息,那么他們都會出去。

您擁有的替代方法是為每個查詢使用單獨的try塊。 然后,即使其中一個例外發生,其他人也可能成功完成。 這里的類比是並聯電路中的一系列燈泡。

我認為你的代碼還可以。 最后你需要在塊中關閉結果集,語句和連接。

如果你對所有后續的SELECT失敗感到滿意,如果一個失敗,那么我會改變方法以拋出異常

public void dashboardReports() throws SQLException 
{
 ....
}

然后從調用方法中捕獲SQLException。

注意我認為拋出/捕獲SQLException而不是Exception更好

只需確保關閉語句和結果集:

try {

    String total_stock_value="select sum(price*closingstock)as tsv from purchase_table";
    try (Statement ps_tsv=connection.createStatement();
        ResultSet set_tsv=ps_tsv.executeQuery(total_stock_value)) {
        if(set_tsv.next())
        {
            total_stock.setText(set_tsv.getString("tsv"));
        }
    }

    String tota_sales="select sum(INVOICE_VALUE) as iv from  PARTYWISE_ACCOUNTS_LEDGER";
    try (Statement st_total_sales=connection.createStatement();
            ResultSet set_total_sales=st_total_sales.executeQuery(tota_sales)) {
        if(set_total_sales.next())
        {
            total_sales.setText(set_total_sales.getString("iv"));
        }
    }

    String total_purchases="select sum(CP_INVOICEVALUE)as cpi from COMPANY_PAYMENTS";
    try (Statement st_tps=connection.createStatement();
            ResultSet set_tps=st_tps.executeQuery(total_purchases)) {
        if(set_tps.next())
        {
            total_purchases_label.setText(set_tps.getString("cpi"));
        }
    }

    String total_collectionss="select sum(PAYMENT_REC) as payrec from PARTYWISE_ACCOUNTS_LEDGER";
    try (Statement ps_toco=connection.createStatement();
            ResultSet set_toco=ps_toco.executeQuery(total_collectionss)) {
        if(set_toco.next())
        {
            total_collections.setText(set_toco.getString("payrec"));
        }
    }

    String total_payments="select sum(CP_PAYMENTREC) as paid from COMPANY_PAYMENTS";
    try (Statement ps_topa=connection.createStatement();
            ResultSet set_topa=ps_topa.executeQuery(total_payments)) {
        if(set_topa.next())
        {
            total_payments_label.setText(set_topa.getString("paid"));
        }
    }

} catch (Exception e) {
    // TODO: handle except
}

}

更好的方法是創建執行常見操作的方法:

public String execute(String query) throws SQLException {
Statement ps_toco=connection.createStatement();
        ResultSet set_toco=ps_toco.executeQuery(query);
        return set_toco.next();
}

當你調用這個方法時,用try catch塊包圍它。

1.您可以使用executeQuery(Connection conn, Statement st, String sql)來封裝和減少代碼行。

2.不要依賴泛型Exception ,也要捕獲特定於sql的異常類

3.除非你在其他地方這樣做,否則我不會在那里看到finally阻止正確關閉資源。 或者,您可以嘗試使用try with resource語法來消除finally塊的需要

4.看看你需要在catch塊中做什么 - 你需要在鏈上傳播異常還是在那里失敗程序?

5.在我看來, ResultSetStatement需要盡可能短,所以盡快關閉它們 - 不要等到單塊關閉它們。 第1點將有助於實現這一目標。

從技術正確性和有效性的角度來看,編寫代碼的方式沒有任何損害 - 對所有SQL使用單個try-catch並消除任何異常(因為我只看到SELECT sqls)但是它有干凈,可讀和可維護的代碼,在這方面,你的代碼看起來很糟糕。

雖然您的代碼有效,但我強烈建議重構它以獲得更好的維護和可讀性 ,如下所示。 另外,請確保正確關閉資源:

public void dashboardReports() {
     handleTotalStocks();
     handleTotalSales();
     handleTotalPurchages();
     //Add others
}

handleTotalStocks()方法:

private void handleTotalStocks() {
       String total_stock_value="select sum(price*closingstock)as tsv 
                     from purchase_table";

     try(Statement ps_tsv=connection.createStatement();
        ResultSet set_tsv=ps_tsv.executeQuery(total_stock_value);) {
         if(set_tsv.next()) {
            total_stock.setText(set_tsv.getString("tsv"));
         }
       }
  }
 //add other methods

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM