【问题标题】:Closing database related resources within method在方法中关闭数据库相关资源
【发布时间】:2014-12-18 12:01:13
【问题描述】:

@Joeblade 建议我将数据库连接逻辑移动到一个单独的方法,如果不是一个单独的类,因为用户界面类已经非常混乱,有很多用户界面代码,所以添加 db 对可读性没有帮助代码给它。如果需要,这也将有助于重用数据库代码。我做的。但现在,我的问题是关于关闭资源。

static Connection getConnection() {
    return connection;
} 

public ResultSet Execute_Query(String queryIn) throws SQLException {
    ResultSet resSet = null;        
    try {               
        connection = TableWithBottomLine.getConnection();
        Statement stmt = null;
        stmt = connection.createStatement();
        resSet = stmt.executeQuery(queryIn);                    
    } catch (SQLException e) {
        e.printStackTrace();
    }               
    return resSet;
}

public String textForLabel() throws SQLException{

    List<Float> floatArrayList = new ArrayList<Float>();

        String query ="SELECT f.Flat, f.Mobile, f.Food, f.Alcohol, f.Transport, f.Outdoor, f.Pauls_stuff, f.Stuff FROM finance.fin f WHERE f.tbl_Date >= DATE_FORMAT( NOW( ) ,  '%Y-%m-10' ) + INTERVAL IF( DAY( NOW( ) ) >10, 0 , -1 ) MONTH AND f.tbl_Date <= CURDATE( ) ";

        try {               
            ResultSet rs = null;
            rs = Execute_Query(query);          

            while (rs.next()){
              floatArrayList.add(rs.getFloat("Flat"));
              floatArrayList.add(rs.getFloat("Mobile"));
              floatArrayList.add(rs.getFloat("Food"));
              floatArrayList.add(rs.getFloat("Alcohol"));
              floatArrayList.add(rs.getFloat("Transport"));
              floatArrayList.add(rs.getFloat("Outdoor"));
              floatArrayList.add(rs.getFloat("Pauls_stuff"));
              floatArrayList.add(rs.getFloat("Stuff"));
            }           
       } catch(SQLException ee){
           ee.printStackTrace();
         }
// Irrelevant stuff down below.....
  1. 是否必须在 Execute_Query() 方法中关闭 Connection、Statement、ResultSet 并在 textForLabel() 方法中关闭 ResultSet(仅)?
  2. 如何使用 try-with-resources 功能关闭?

【问题讨论】:

  • 在方法中没有方法之类的东西。方法中只能有 OBJECTS - 可能包含方法,除了 lba-construction 之外,它们具有不同的范围,或多或少是孤立的。
  • 谢谢。我编辑了标题。
  • 你让事情变得更糟了,你的代码中没有一个 lambda - 因此范围不同。

标签: java mysql sql database resources


【解决方案1】:

试试这样的

} catch (SQLException e) {
   e.printStackTrace();
} finally {
   connection.close();
}

finally 语句将确保 'connection.close();'即使代码抛出异常也会被调用。

【讨论】:

  • 你看到我的要求了吗?
  • 是的,'但是现在,我的问题是关于关闭资源'。在你的代码中使用 finally 来关闭你想要的资源。我弄错了吗?
  • 我们不要在这里讨论。我会通过问你一个简单的问题来告诉你是否错了:你的答案是我问的第一个问题还是第二个问题? :))
  • 对不起,如果我显得咄咄逼人,我不想开始讨论。这个答案是针对第二个问题的。我试图在网上找到一个可能对你有很大帮助的连接工厂的例子。如果我找到了,我会发表评论。
  • 对不起,我只是找不到连接工厂的好例子。但作为建议,当您的代码抛出异常时使用此“connection.rollback()”,它将撤消先前代码使用该连接在数据库中所做的操作。
【解决方案2】:

移动所有的数据库逻辑,而不仅仅是连接建立代码。

List<Float> listMyStuff() {
    ArrayList<Float> list = new ArrayList<Float>();
    Connection con = null;
    Statement statement = null;
    ResultSet rs = null;

    try {
        con = DriverManager.getConnection(MY_DB_URL);
        statement = con.createStatement();
        rs = statement.executeQuery(MY_SQL);
        while(rs.next()) {
            list.add(rs.getFloat("Flat"));
            list.add(rs.getFloat("Mobile"));
            list.add(rs.getFloat("Food"));
            list.add(rs.getFloat("Alcohol"));
            list.add(rs.getFloat("Transport"));
            list.add(rs.getFloat("Outdoor"));
            list.add(rs.getFloat("Pauls_stuff"));
            list.add(rs.getFloat("Stuff"));            
        }
    }
    catch(SQLException e) {
        e.printStackTrace();
        //Do something else!?!?
    }
    finally {
        if(rs != null) { try{ rs.close(); }catch(Throwable t){} }
        if(statement != null) { try{ statement.close(); }catch(Throwable t){} }
        if(con != null) { try{ con.close(); }catch(Throwable t){} }
    }

    return list;
}

【讨论】:

  • 谢谢。这是将数据库逻辑与 UI 或业务逻辑分离的一个很好的例子。现在,请告诉我一些事情,如果我的程序中有几个查询,我应该每次为每个查询都制作一个这样的特定方法还是我可以制作一个通用方法并重用它?
【解决方案3】:

如果您选择这样做,对资源使用 try 会好得多。

首先获取您的连接详细信息并准备 try 中的语句。

      String query ="SELECT f.Flat, f.Mobile, f.Food, f.Alcohol, f.Transport, f.Outdoor, f.Pauls_stuff, f.Stuff FROM finance.fin f WHERE f.tbl_Date >= DATE_FORMAT( NOW( ) ,  '%Y-%m-10' ) + INTERVAL IF( DAY( NOW( ) ) >10, 0 , -1 ) MONTH AND f.tbl_Date <= CURDATE( ) ";
        try (Connection connection = DriverManager.getConnection(url);
    Statement stmt=connection.createStatement();) {
        try (ResultSet rs = stmt.executeQuery(query); ) {
                while(rs.next()) {
    floatArrayList.add(rs.getFloat("Flat"));
                  floatArrayList.add(rs.getFloat("Mobile"));
                  floatArrayList.add(rs.getFloat("Food"));
                  floatArrayList.add(rs.getFloat("Alcohol"));
                  floatArrayList.add(rs.getFloat("Transport"));
                  floatArrayList.add(rs.getFloat("Outdoor"));
                  floatArrayList.add(rs.getFloat("Pauls_stuff"));
                  floatArrayList.add(rs.getFloat("Stuff"));
                }           
           } 
}catch(SQLException ee){
               ee.printStackTrace();
    }

【讨论】:

  • 感谢您的解决方案。有人建议我将我的数据库连接逻辑移出相同的方法。我做到了,你又把它拉回来了……
  • ok.. 将上述代码添加到以字符串为参数的方法中。现在通过将查询作为另一个类的参数传递来调用该方法。现在您的数据库操作将从您的用户界面中移出。
猜你喜欢
  • 2014-01-05
  • 2010-09-05
  • 2019-09-12
  • 2011-06-14
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多