关于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;
}
}
希望如果发现我的错误,及时指正,有任何问题也可以在评论区交流