【发布时间】:2019-06-14 14:54:26
【问题描述】:
我正在构建一个基本的 java 应用程序来将一些文件加载到 mysql 数据库中。我能够毫无问题地加载文件并填充我的表格。然而,在与查看我的代码的人交谈后,我显然没有正确关闭我的连接并浪费资源。我在哪里没有关闭连接?我做错了吗?
我正在使用我的 DbSinger 类中的 try-with-resources 构造来对我的数据库执行准备好的语句,只要实现了 AutoCloseable 接口,它就会自动关闭连接,它就是在 Db 的父类中。然而,close() 方法永远不会到达。 DbSinger 在我的 main() 中实例化,然后运行它的单一方法 populateSingers() 与 Singer的 ArrayList > 对象。
连接类
public class SQLConnection {
private static final String servername = "localhost";
private static final int port = 3306;
private static final String user = "ng_user";
private static final String pass = "ng";
private static final String db = "ng_music";
private static final String connectionString = "jdbc:mysql://" + servername + ":" + port + "/" + db;
public Connection provide() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
return DriverManager.getConnection(connectionString, user, pass);
}
catch (SQLException | ClassNotFoundException e) {
throw new SQLConnectionException(e);
}
}
public class SQLConnectionException extends RuntimeException {
SQLConnectionException(Exception e) {super(e);}
}
}
抽象父类
public abstract class Db implements AutoCloseable{
private Connection connection;
Db() {
SQLConnection sqlC = new SQLConnection();
this.connection = sqlC.provide();
}
@Override
public synchronized void close() throws SQLException {
if(connection != null) {
connection.close();
connection = null;
System.out.println("Connection closed");
}
}
Connection getConnection() {
return connection;
}
boolean checkIfPopulated(String query){
try {
PreparedStatement ps = getConnection().prepareStatement(query);
ResultSet rs = ps.executeQuery();
return !rs.next();
} catch (SQLException e) {
e.printStackTrace();
}
return true;
}
}
对歌手表的数据库执行查询的具体类
public class DbSinger extends Db {
public DbSinger() {
super();
}
public void populateSingers(ArrayList<Singer> singers) {
String populateSingersQuery = "insert into ng_singers(name, dob, sex) values(?,?,?)";
if(!checkIfPopulated("select * from ng_singers")){
System.out.println("Singer Table is already populated");
return;
}
try (PreparedStatement ps = getConnection().prepareStatement(populateSingersQuery)) {
for (Singer s : singers) {
ps.setString(1, s.getName());
ps.setDate(2, java.sql.Date.valueOf(s.getDob()));
ps.setString(3, s.getSex());
ps.addBatch();
}
ps.executeBatch();
System.out.println("Singers added to table");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
我的代码能够执行,能够正常运行并执行所需的操作,但我想了解为什么以及在何处不关闭连接,并了解如何解决此问题。或者至少了解我是否接近这个错误。
【问题讨论】:
-
请出示实例化
DbSinger的代码。另外,您没有在checkIfPopulated方法中关闭PreparedStatement -
没问题!
public static void main(String[] args) { start(); } public static void start() { DAO dao = new DAO(); DbSinger dbSinger = new DbSinger(); dbSinger.populateSingers(dao.loadSingers("data/ng_singers.txt")); }DAO 类和 dao.loadSingers 只返回 Singer 对象的 ArrayList。我认为通过使用 try-with-resources 我不需要每次都关闭连接?但如果不是这样,我会手动关闭它们 -
将该代码放入您的问题中并查看我的答案。
标签: java mysql connection try-with-resources