Java中的静态finally块

3
我有一个使用静态初始化块建立与数据库连接的类。该类有许多公共静态方法用于查询数据库。我想在程序终止前执行一个静态块来正确关闭这个连接,就像在try/catch中的finally块一样。我几乎可以确定在Java中不存在这样的机制。那么,我的最佳选择是每次查询时都打开和关闭连接吗?

@thanga 不是那个的副本。拜托,大家。 - Shahzeb
请发布您的代码。论坛上的人可以为您进行更正,否则每个人都只是在猜测。 - Shahzeb
1
可能是一个关闭挂钩..http://javapapers.com/core-java/jvm-shutdown-hook/ - RP-
3
当JVM关闭时,你唯一可能知道的是通过一个关闭钩子(shut down hook),但是这假定正常的关闭已经发生。一般来说,更好的解决方案可能是在需要时创建短暂的Connection实例,并在使用完后关闭它们,或者使用某种连接池。 - MadProgrammer
如果您有多个查询从单个线程运行(我猜测),那么为什么要重复打开和关闭连接?这只会增加不必要的问题(依赖于数据库)。相反,创建一个singleton,为每个数据库打开一次连接,在完成所有操作后,只需调用一个处理语句、结果集和连接的dispose-off方法 - mustangDC
显示剩余6条评论
4个回答

3
请看这个:程序关闭时运行一个方法? 你可以尝试在这个方法中编写关闭连接的代码。
public static void main(String[] args) {
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
        public void run() {
            //code to close connection
        }
    }, "Shutdown-thread"));
}

当应用程序正常退出时,上述代码可以正常工作。但是如果虚拟机中止,则无法保证是否会运行任何关闭挂钩。 - Sridhar
问题是:我的最佳选择是对每个查询打开和关闭连接吗? - mustangDC
如果您有太多的查询,每个查询都打开和关闭连接并不好。这将增加您的代码行数并导致不必要的开销。使用 shutDownHook 可以减少所有这些问题。 - Ridhima

1
public class JdbcDBManager {
private Connection connection = null;
private PreparedStatement preparedStatement = null;
private ResultSet resultSet = null;

public JdbcDBManager(String url, String user, String pass) throws ClassNotFoundException, SQLException {
    Class.forName("org.gjt.mm.mysql.Driver");
    this.connection = DriverManager.getConnection(url, user, pass);
}

public void close() {
    try {if (this.preparedStatement != null)this.preparedStatement.close();} catch (Exception e) {e.printStackTrace();}
    try {if (this.resultSet != null)this.resultSet.close();} catch (Exception e) {e.printStackTrace();}
    try {if (this.connection != null)this.connection.close();} catch (Exception e) {e.printStackTrace();}
}
public void customerInsert(Customer customer) {
    try {
        String query = "INSERT INTO customer(email,product) VALUES(?,?,?,?,?)";
        this.preparedStatement = this.connection.prepareStatement(query);
        this.preparedStatement.setString(1, customer.getEmail());
        this.preparedStatement.setString(3, customer.getProduct());
    } catch (Exception e) { e.printStackTrace();}
}}

你可以为每个数据库创建一个对象,在最终处理完成后将其关闭。
public class test {

public static void process() throws ClassNotFoundException, SQLException {
    JdbcDBManager customerDB = new JdbcDBManager(JdbcURL.URL, JdbcURL.USER, JdbcURL.PASS);
    try {
        customerDB.insertCustomer(Customer customer);
        doSomething(customerDB); // Pass db object as a parameter
    } finally { customerDB.close();} // close it when you are finally done
}
doSomething(JdbcDBManager customerDB){
     ---------------------------
     --process info in db-------
} }

这样,您只需打开一次连接,并在最终完成进程时关闭连接。

1
每次查询都打开和关闭连接会给系统带来额外的负担,使应用程序变慢。您可以在 DB 程序的最后一个查询周围使用 try catch 块,并在 finally 子句中释放连接(针对程序的最后一个查询)。请注意:如果 JVM 在主线程完成执行之前终止,即 System.exit() 执行,则不会执行后续代码和 finally 块。

0

我最好的选择是在每个查询中打开和关闭连接吗? 答案:不是

我建议您遵循以下步骤:

使用单例类打开连接,类似于这样:

public class connectDB {
static Connection conn = null;

public static Connection getConnection(){
    if (conn != null) return conn;
    String connString = "DATABASE ACCESS URL HERE";
    return getConnection(connString);
}

private static Connection getConnection(String conString){
    try{
        Class.forName("LOAD DRIVER HERE");
        String uname = "DB USERNAME";
        String pass = "DB PASSWORD";
        conn = DriverManager.getConnection(conString, uname, pass);  
    }
    catch(Exception e){
        //Handle Exceptions
        e.printStackTrace(); //<--Retrieves the error/Exception for you
    }
    return conn;
}
}

并使用类似以下的方式关闭连接:

public static void closeConnection(Connection conn) {
try {
    conn.close();
}
catch (SQLException e) {
    //Handle Exception Here
}
}

只需调用 conn = connectDB.getConnection() 来进行连接,另一个用于关闭连接,最好在 finally 语句块中执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接