我是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;
}
所以每个静态函数都会打开一些资源并关闭它。现在的问题是,许多功能必须关闭多个资源,例如ResultSet
,PreparedStatement
和Connection
。其中一些甚至有五个以上的资源必须按特定顺序关闭。因此,我写了一个函数如下:
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这样的对象,因为可能存在一些线程安全问题。如果我错了,天真,请纠正我。
答案 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块完成,括号内声明的所有资源都将自动关闭
答案 1 :(得分:0)
如果您已经拥有AutoCloseable
,那么您正在使用Java 7或更高版本。然后,如果您使用try-with-resources
代替它会更好:
try (Connection con = ...;
Statement stmt = ...;
ResultSet rs = ...) {
} catch (...) {
}
此外,对于每个必须执行语句的方法,最好将Connection
作为参数传递,这样您就可以重用单个连接而不是按语句打开/关闭它,从而大大改善了应用程序性能。