简体   繁体   中英

Can return connection object inside a try with resources

I have connection provider class as bleow to return connection.

 public class ConnectionProvider {

    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection ConnectDB() throws ClassNotFoundException, SQLException {  

        try (Connection connection = DriverManager
                .getConnection("jdbc:mysql://localhost:3306/jspservlet_test","root", "root");
                ) {

            return connection;
        }           
    }
}

Here is main method to call connection provider.

public void Test() {

        try {               
            Connection con =  ConnectionProvider.ConnectDB();

            PreparedStatement ps = con.prepareStatement("");                            

        } catch (SQLException e) {          

            e.printStackTrace();
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
        }

    }

But "com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed." error are always show at below line of code.

PreparedStatement ps = con.prepareStatement("");

Because, according to Oracle documentation, If use try with resources java 7 features, resources are auto close after try block even it's errors occurred or not. So even I returned the connection it's already closed.

Let me know, my usage logic is wrong? How can I return this connection inside try with resource? I tried many time googling for solution but does not get convenience answers for me.

Let me know your suggestion and feedback please.

What you can't do...

With a try-with-resources as you have it after you return the connection you return (d) is close(d). You can't return the connection from inside the try with resources.

What you can do...

Pass the connection (inside your try-with-resources ) to a method that takes a connection . You can also use a ConnectionPool, and get the Connection when you need it (to create and execute a query).

Let me know, my usage logic is wrong?

The usage of 'try-with-resources' logic is wrong in this context, because the intention of ConnectDB() is to return a connection instance which could be actually used by the caller to send a SQL statement, but instead, the connection instance is getting auto-closed, before it could be used by the caller, because of using ' try-with-resources ' construct of Java.

Quick how-to on try-with-resource and JDBC

Your ConnectionProvider's ConnectDB already declares it is throwing SQLException - so no need to catch it in here: (You should consider replacing this code with connection pool maybe)

public class ConnectionProvider {
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection ConnectDB() throws SQLException {  
      return DriverManager.getConnection("jdbc:mysql://localhost:3306/jspservlet_test","root", "root");
    }
}

Instead use try-with-resource in your test-class to clean up your code and focus on errors your SQL code might have:

public void Test() {

    try (Connection con =  ConnectionProvider.ConnectDB();
         PreparedStatement ps = con.prepareStatement("SELECT 1")) {
         //Prepare your Statement
         ps.setInt(1, 1);
         //And another try-with-resource for the result - note the closing brace
         try(ResultSet rs = ps.executeQuery()) {
            while(rs.next()) {
               //Handle your Result
               System.out.println(rs.getString(1));
            }
         } // This closes try-with-resource. Exception will be rethron to be caught in outer catch!          
    } catch (SQLException e) {          
        //SQL is Broken - but only ONE catch to catch them all
        e.printStackTrace();
    } 

}

That way you gain

  • Better readability for your code (no calls to close surrounded by finally and if != null)
  • Centralized error handling if anything in your SQL code breaks (so you can focus on functional error of "statement didn't run")
  • Better code quality: No need to worry about Cursors, Statements, Connections not being propery closed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM