關於Java的No operations allowed after connection closed問題簡述、分析以及修改方案
問題簡述
之前沒有研究明白這個問題,現在大概懂了一些,所以對本文做了一些修改
以上是控制檯報錯內容:在數據庫連接被關閉後,操作不被允許
問題分析
之前只知道大概這個東西和靜態塊有關係,具體關於靜態塊的問題,有空研究一下再發博客
每次發現這種問題,第一反應是是否數據庫被關閉了,但是仔細發現一般情況下沒有
十有八九是因爲數據庫連接也就是con是靜態的(static),(代碼如下)
private static Connection conn = null;
無論是用debug或者是System.out.println(con); 都會發現con並非空值,是能打印出東西的,就是沒重載過的toString方法打印的那個字符串,而且會發現 con在關閉後和關閉前打印的字符串是一模一樣的 ,說明con在關閉後並非爲空了,而是依然存在的,只是不允許再次操作,聯想到老師的修改方法(當時沒啥問題,但是今天我發現這個問題偶爾又會出現)
目前確定問題所在就在於static
(綜合老師的改法和自己的改法,總結出了兩個解決方法,都有它自己的優點)
修改方案
修改方案1:
這個方法是基於老師的改法然後修改了錯誤後經過實戰確定有效
總結:
這個方法可以有效避免數據庫連接打開過多,避免資源佔用問題(始終保持只打開一個數據庫連接)
缺陷
這個方法中獲得的連接必須使用 try catch包裹或者直接拋出異常,注意事項較多
package demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConnect {
// MySQL 8.0 以下版本 - JDBC 驅動名及數據庫 URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/student? characterEncoding=utf-8&useSSL=false";
// 數據庫的用戶名與密碼,需要根據自己的設置
static final String USER = "root";
static final String PASS = "123456";
private static Connection conn = null;
public static Connection getConnect() throws SQLException {
if (conn != null) {
conn.close();
}
conn = null;
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, USER, PASS);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
public static void close() {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
修改方案2:
這個方法是自己之前寫的沒有過多的修改
總結:
這個方法修改便捷,每一次獲取的都是新生成的數據庫連接,不會造成太多後續問題,關閉數據庫連接手動使用 .close() 方法
缺陷
可能會忘記關閉數據庫連接,造成大量資源佔用
package demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConnect {
// MySQL 8.0 以下版本 - JDBC 驅動名及數據庫 URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/student? characterEncoding=utf-8&useSSL=false";
// 數據庫的用戶名與密碼,需要根據自己的設置
static final String USER = "root";
static final String PASS = "123456";
public static Connection getConnect() throws SQLException {
Connection conn = null;
if (conn == null) {
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, USER, PASS);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return conn;
}
}
希望如果發現我的錯誤,及時指正,有任何問題也可以在評論區交流