Reputation: 1188
can someone tell me where and how I have to close the connection here? Do I have to close the Connection in the Connection class or in the Controller class? I already tried to put followin at the end of the method in the connection class:
if (conn != null) {
try {
conn.close();
} catch (SQLException e) { /* ignored */}
}
But then I get: "No operations allowed after statement closed."
Here is my Code:
public class DB_Connection {
String url = "XXX";
Statement statement;
public DB_Connection (){
try {
Connection con = (Connection) DriverManager.getConnection(url);
statement = (Statement) con.createStatement();
}
catch (SQLException ex){
System.out.println("Failed connection");
}
}
public void addSubject(String subject) throws SQLException {
try {
statement.executeUpdate("INSERT INTO `Subject` VALUES ('" + subject + "')" );
System.out.println("Added " + subject + "to database");
} catch(SQLException e) {
System.out.println("SQL Exception");
}
}
}
And I call it from here:
public class MenuController {
@FXML
public void SendSubject(ActionEvent e) throws IOException, SQLException {
DB_Connection connection = new DB_Connection();
connection.addSubject("English");
}
}
Thanks for your help!
Upvotes: 1
Views: 9879
Reputation: 719416
You need to close the connection after you have finished using it. There are many ways to deal with that, but here's what I suggest you do:
public class DBConnection implements AutoCloseable {
private String url = ...
private Connection con;
private Statement statement;
public DBConnection () throws SQLException {
try {
con = DriverManager.getConnection(url);
statement = con.createStatement();
} finally {
// Avoid leak if an exception was thrown in createStatement
if (statement == null) {
con.close();
}
}
}
public void addSubject(String subject) throws SQLException {
statement.executeUpdate("INSERT INTO `Subject` VALUES ('" +
subject + "')" );
}
public void close() throws SQLException {
con.close();
}
}
Then use it like this:
try (DBConnection connection = new DBConnection()) {
connection.addSubject("English");
}
Explanation / commentary:
close()
method is the way that the application tells the DBConnection
class "I have finished".DBConnection
as `AutoCloaseable means that we can use try-with-resources to manage the closure ... which is simpler and more robust.private
as per good OO design principles.SQLException
to propagate to the caller. Those exceptions cannot be handled properly in DBConnection
class itself.The other approach is to do away with the DBConnection
class entirely, and have the calling code take care of the connection object and the statements for itself. Certainly, in this small example the DBConnection
abstraction adds minimal value.
Upvotes: 5
Reputation: 2234
Don't close conn
object in the Connection class,
Better to close in DAO class
only or in the Main method
or in the Method itself.
for example:
public void addSubject(String subject) throws SQLException {
........
........//**some operations**
// close here after some operation done
if (conn != null) {
try {
conn.close();
} catch (SQLException e) { sysout(e);}
}
}
Upvotes: 0
Reputation: 9170
When you get it going following Stephen's guidance, take a look at PreparedStatement
as well...
Declare PreparedStatement
rather than Statement
:
private PreparedStatement pStmt;
Create the PreparedStatement
:
pStmt = con.prepareStatement("INSERT INTO `Subject` VALUES (?)");
Reuse the PreparedStatement
:
public void addSubject(String subject) throws SQLException {
pStmt.setString(1, subject);
pStmt.executeUpdate();
pStmt.clearParameters();
}
Allows re-use and some protection from injection.
Upvotes: 1
Reputation: 311031
Don't hold connections etc. as member variables at all. You should make them all (Connection, Statement/PreparedStatement, ResultSet
) local variables and use the try-with-resources idiom.
Upvotes: 0