2017-04-25 50 views
2

我是Java新手,我的工作都与JDBC相关 - 关于插入和处理数据。在其所有工作正常。单尝试捕获块中的多个JDBC语句。这是好的做法吗?

要减少代码使用单个try{} catch()块来编写多个JDBCStatementsPrepared 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 
    } 
} 

因此,这是很好的应对或其他别的办法?

截至目前我的代码工作得很好,我们是否有任何未来的问题与这种方法。

+1

如果这个代码工作正常,你应该提交我们的[代码审查(HTTPS:/ /codereview.stackexchange.com/)姊妹网站。 –

+0

我看到的最大的问题是,如果您不使用试用资源来解决问题,并且您会自动使用较小范围的尝试块,则不会关闭资源。顺便说一下:你的代码效率低下:当你查询这两个表时,你只查询两次表,只能查询一次。 –

回答

2

由于您只是在这里执行SELECT操作,因此不需要显式事务,因为您没有更改数据库的状态,也没有任何可以回滚的地方。将单个try块中的所有SELECT语句分组没有任何问题。但是,有一个潜在的缺点,即如果一个SELECT失败,您的代码将退出该try块,所有后续查询将不会运行。如果你可以容忍这一点,那么你可以保持原样。与此类似的是一系列串联连接的灯泡;如果一个人休息,他们都会出去。

对于每个查询,您可以使用单独的try块。然后,即使其中一个发生异常,其他人也可能成功完成。这里的比喻将是一系列并联电路中的灯泡。

0

只要确保你闭上你的语句和结果集:

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 
} 

}

1

如果你很高兴与所有后续SELECT■如果一个失败,失败,那么我会改变抛出一个异常的方法

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

然后从调用方法中捕获SQLException。

注意我觉得这是更好地抛出/搭上SQLException而非Exception

+0

有点类似于我刚刚写的...反馈是欢迎那里。 – GhostCat

2

我觉得你的代码就可以了。 您最后需要在块中关闭结果集,语句和连接。

0

更好的方法是创建一个方法,做常用的操作:当调用此方法与try catch块围绕着它

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

0

1.您可以使用像executeQuery(Connection conn, Statement st, String sql)这样的方法来封装和缩减您的代码行。

2.不要依赖于通用Exception,捕获SQL特定的异常类太

3。我没有在那里看到finally块,以便正确关闭资源,除非您在其他地方执行此操作。或者,你可以尝试使用try with resource语法消除需要finally

4.See的,你需要在catch块做什么 - 你需要异常传播链向上上方或失败的计划在那里?

5.In我看来,一个ResultSetStatement需要活得短,因为他们可以因此尝试,只要你能关闭它们 - 不要等到全部关闭单块。点#1将有助于实现这一点。

从技术的正确性和有效性的角度来看,在编写代码方面没有任何坏处 - 对所有SQL使用单个try-catch并且排除任何异常(因为我看到的只有SELECT sqls),但是有干净,可读和可维护的代码,在这方面,你的代码看起来很差。

2

这违反了Single ResponsbilitySingle Layer of Abstraction原则。

所以,尽管这段代码在技术上是有效的,您不仅应该关注其正确性,还应该关注其可读性。和可测性。而且我认为你所展示的输入内容都不是“很棒”。

因此;来自干净的代码(质量)角度;我宁愿建议去沿着线的东西:

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

的小帮手你们每个人到了那里不同的情况。当然,你不会停留在那里;但尝试隔离共同方面的帮手;并可能找到方法与单一的,更通用的帮手。

当然:你尽量避免捕获例外如果可能的话。相反,你可以捕获最具体的例外!

+2

+1我同意你的意见,甚至想补充一点,因为'helperMethod1'和'helperMethod2'在功能上几乎完全相同,所以它们可能被重构为一个参数化方法 –

+0

好主意。把我的答案说成是这个。 – GhostCat

0

尽管您的代码有效,但我强烈建议您将重构为更好的维护和可读性,如下所示。此外,确保资源被正确关闭:

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