【问题标题】:Is closing the db connection necessary here?这里需要关闭数据库连接吗?
【发布时间】:2016-01-10 00:47:35
【问题描述】:

我正在使用 java 和 mssql 进行一个学校项目,我在数据库连接方面遇到了一些问题。

这种情况需要关闭数据库连接吗?

我想构建一个由 Person 对象组成的 Animal 对象。

这是来自 DBLayer/DBAnimal 的代码:

首先我们有我连接到数据库并获取结果集的方法。

public Animal findAnimal(int id) 
    {
        con = DBConnection.getInstance().getDBcon();
        PreparedStatement preStmnt = null;
        String query = "select * from animal where id = ?";
        Animal animalObj = null;
        ResultSet results;
        try 
        {
            preStmnt = con.prepareStatement(query);
            preStmnt.setInt(1, id);
            results = preStmnt.executeQuery();
            if (results.next()) 
            {
                animalObj = buildAnimal(results);
            }
        } catch (SQLException SQLe) {
            System.out.println("SQL Exception i findAnimal: " + SQLe);
        } catch (Exception e) {
            System.out.println("Exception i findAnimal() " + e.getMessage());

        }

        DBConnection.closeConnection(); 
        return animalObj;
    }

然后我在哪里构建 Animal 对象并调用 FindPersonOnId 方法:

public Animal buildAnimal(ResultSet results) throws SQLException 
    {

        Animal animalObj = new Animal();

        Person personObj = new Person();

        try 
        {

            animalObj.setId(results.getInt("id"));
            animalObj.setName(results.getString("name"));           
            animalObj.setRace(results.getInt("raceid"));
            animalObj.setSpecie(findSpecieId(results.getInt("raceid")));
            animalObj.setSex(results.getString("sex").charAt(0));
            animalObj.setBorn(results.getDate("born"));
            animalObj.setAlive(results.getBoolean("alive"));
            animalObj.setPerson(dbPerson.findPersonOnId(results.getInt("personId")));
        }

        catch (SQLException e) 
        {
            System.out.println("Exception i buildAnimal" + e.getMessage());
        }

        return animalObj;
    }

这是来自 DBLayer/DBPerson:

public Person findPersonOnId(int id) 
    {
        con = DBConnection.getInstance().getDBcon();
        PreparedStatement preStmnt = null;
        String query = "SELECT * FROM " + TABLE_NAME + " WHERE id = ?";
        Person personObj = null;
        ResultSet results;
        try 
        {
            preStmnt = con.prepareStatement(query);
            preStmnt.setInt(1, id);
            results = preStmnt.executeQuery();
            if (results.next()) 
            {
                personObj = buildPerson(results);
            }
        } 
        catch(SQLException SQLe) 
        {
            System.out.println("SQLException i findPersonOnId(id): " + SQLe);
        } 
        catch (Exception e)
        {
            System.out.println("Fejl i findPersonOnId(id): " + e.getMessage());
        }

        DBConnection.getInstance().closeConnection();
        return personObj;
    }

如您所见,我两次都使用 closeConnection,这会导致一些问题,因为它非常慢。而且我在徘徊,在这种情况下完全有必要关闭连接。

如果不是,会是什么情况?

【问题讨论】:

  • DBConnection 类的设计似乎有问题; getDBcon() 方法返回一个Connection 实例,但另一方面,它的closeConnection() 方法不将Connection 实例作为输入参数。类如何在内部发挥作用——closeConnection() 是否总是关闭最后打开的连接?如果同时打开多个连接会怎样?还是DBConnection 总是只包含一个Connection 实例?
  • 通常,关闭/打开Connections 由外部管理,例如由您的应用程序服务器(它在内部分配来自连接池的连接)。但是,您应该关闭 StatementResultSet 对象(这是您的代码不执行 ATM 的操作)。最好的方法是使用try-with-resources statement
  • @MickMnemonic 如果你的应用服务器使用了连接池,你仍然应该关闭连接以表明你已经完成了它;在这种情况下,这并没有真正关闭连接,而是将其返回到池中。但是你不需要知道:你应该在完成后关闭连接。
  • @ErwinBolwidt,这取决于 - 你应该只关闭你自己打开/获得的连接。最好使用 try-with-resources 来完成。但是,您不应关闭已注入 DAO 并可能在同一事务的其他地方使用的连接。
  • @MickMnemonic,但是我现在遇到的问题是,当我使用 Person 对象构建 Animal 对象时,我必须与数据库连接两次,而现在我两次都关闭了连接,在性能/速度方面这是一个问题。所以如果我使用 try-with-resources 语句,我不会有同样的问题吗?

标签: java sql sql-server database jdbc


【解决方案1】:

是的

每次建立连接时,都必须确保它最终会关闭,否则会泄漏资源,并且会留下太多打开的连接,导致应用程序中断。

话虽如此,有一些工具和库可以让这件事变得更容易,Spring JdbcTemplate 就是其中之一。

不查看您的 DBConnection 类,它似乎正在尝试做 Datasource 所做的事情,请考虑改用正确的 datasource

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 2016-01-18
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 2013-11-25
    相关资源
    最近更新 更多