user3923502
user3923502

Reputation: 13

Best practice for closing multiple Resources by a single method

I am very new to Java. Now I am developing a web service with JSP and Servelet's. I had a class called DBUtil which deals with databases operations. Because this class serves as a helper class for many JSP pages, I put every function static. One example is the call:

  public static boolean isAdmin (String uid) {
   boolean  result = false;
   Connection conn = getConnection(); // Datamanager.getConnection(...);
   PreparedStatement pstmt = null;
   ResultSet rs = null;  
   try{
       pstmt = conn.prepareStatement("select u_admin from table where uid = ?");
       pstmt.setInt(1,Integer.parseInt(uid));
       rs = pstmt.executeQuery();
       if(rs.next()){
                result = rs.getBoolean(1);
       }
   }catch(){
       e.printStackTrace();
   }finally{
       try{
           if(rs != null){
               rs.close();
               rs = null;
           }
       }catch(Exception e){
           e.printStackTrace();
       }
       try{
           if(pstmt != null){
               pstmt.close();
               pstmt = null;
           }
       }catch(Exception e){
           e.printStackTrace();
       }
       try{
           if(conn != null){
                conn.close();
                conn = null;
           }
       }catch(Exception e){
           e.printStackTrace();
       }            
    }     
    return result;  
}

So every static function will open some resources and close it. Now the Problem is that many functions have to close multiple Resourses such as ResultSet, PreparedStatement and Connection. Some of them even have more than five Resources that have to be closed in a certain order. Hence, I wrote a function as followings:

private static void closeResource(AutoCloseable ...resources ){
    if (resources == null || resources.length == 0) {
       return;
    } else {
        for (AutoCloseable rs: resources) {
            try{
                if(rs!= null) rs.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}

So that I don't have to write a tedious long lines of try-catch-Statements for rs.close(). Instead, I can simply call closeResource(pstmt,rs,conn) (for keeping every function shorter).

Is this a good practice? Is there any other Solutions for closing multiple Resources by a single function (I was actually looking for C macro like solutions, yet found nothing).

Meanwhile, I also want to ask if my static function way of database operating is a good practice? I don't want to cache object like Conn in JSP pages because there might be some Thread-safe issues. Correct me if I am wrong and naive.

Upvotes: 0

Views: 244

Answers (2)

Vince
Vince

Reputation: 15146

You can use try-with-resources by declaring resources between ( ) (Java 7+). Between the parentheses, you can declare objects that implement AutoClosable.

Here's an example of using Scanner and ServerSocket, which are resources that require closing, and are AutoClosable:

try (Scanner scanner = new Scanner(System.in); ServerSocket socket = new ServerSocket(15180)) {
     //use resources
}

All resources declared within the parentheses will automatically close once the try block has completed

Try-with-resources Tutorial

Upvotes: 1

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85799

If you already have AutoCloseable, then you're working with Java 7 or later. Then, it would be better if you use try-with-resources instead:

try (Connection con = ...;
     Statement stmt = ...;
     ResultSet rs = ...) {
} catch (...) {
}

Also, for every method that has to execute a statement, it would be better if you pass the Connection as parameter so you can reuse a single connection instead of opening/closing it per statement, thus heavily improving the app performance.

Upvotes: 0

Related Questions