通过单个方法关闭多个资源的最佳实践

时间:2014-08-08 19:52:35

标签: java jsp

我是Java的新手。现在我正在使用JSP和Servelet开发一个Web服务。我有一个名为DBUtil的类来处理数据库操作。因为这个类充当许多JSP页面的辅助类,所以我将每个函数都设置为静态。一个例子是电话:

  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;  
}

所以每个静态函数都会打开一些资源并关闭它。现在的问题是,许多功能必须关闭多个资源,例如ResultSetPreparedStatementConnection。其中一些甚至有五个以上的资源必须按特定顺序关闭。因此,我写了一个函数如下:

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();
            }
        }
    }
}

因此,我不必为try - catch - rs.close()的陈述编写繁琐的长行。相反,我可以简单地调用closeResource(pstmt,rs,conn)(以保持每个函数更短)。

这是一个好习惯吗?是否有任何其他解决方案可以通过单个函数关闭多个资源(我实际上是在寻找C宏类似的解决方案,但却一无所获)。

同时,我也想问一下我的静态函数数据库操作方式是不是很好?我不想在JSP页面中缓存像Conn这样的对象,因为可能存在一些线程安全问题。如果我错了,天真,请纠正我。

2 个答案:

答案 0 :(得分:1)

您可以通过在try-with-resources(Java 7+)之间声明资源来使用( )。在括号之间,您可以声明实现AutoClosable的对象。

以下是使用Scanner和ServerSocket的示例,这些资源需要关闭,并且是AutoClosable

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

一旦try块完成,括号内声明的所有资源都将自动关闭

Try-with-resources Tutorial

答案 1 :(得分:0)

如果您已经拥有AutoCloseable,那么您正在使用Java 7或更高版本。然后,如果您使用try-with-resources代替它会更好:

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

此外,对于每个必须执行语句的方法,最好将Connection作为参数传递,这样您就可以重用单个连接而不是按语句打开/关闭它,从而大大改善了应用程序性能。