patternjavaMinor
Library of news articles
Viewed 0 times
newsarticleslibrary
Problem
I have a library of news articles. Each story is unique by
Come what may (like an exception, or something), I want to make sure to release the JDBC resources used by the
id.public String getStory(String id) throws Exception {
Connection conn = MysqlDb.getConn(dbName);
try {
for(Publisher p : Publishers) {
PreparedStatement prpStmt = conn.prepareStatement("SELECT story FROM " + p + " WHERE id='" + id + "'");
ResultSet rs = prpStmt.executeQuery();
while (rs.next()) {
String story = rs.getString(1);
rs.close();
return story;
}
rs.close();
}
} finally {
conn.close();
}
return null;
}Come what may (like an exception, or something), I want to make sure to release the JDBC resources used by the
Connection and ResultSet objects. Does finally always execute in Java?- Closing the database connection in a
finallyblock makes sense, right? In the code I've looked at, I've not seenfinallyreally used for anything.
- Maybe making sure that the
ResultSetcloses is not absolutely necessary? But, theclose()method must exist for some reason... But, in my method above, the scope is too narrow to be closed by thefinallyblock. What to do? Create anotherfinallywith adequate scope for theResultSet?
Solution
The best way to close a
but using try-with-resources, which is the best practice as of Java 7:
There are a couple of other issues in your code:
-
You're not using the prepared statement properly and to its full advantage. Don't create a query string as a concatenation of variables used in the WHERE clause. Those values should be set via the prepared statement. In its current form, your query may be vulnerable to SQL injection attacks.
-
The inner
-
You should use try-with-resources for the prepared statement and the result set too
-
"Publishers" looks like a collection, a variable, but by the naming conventions of Java only class names should start with a capital letter. So this should be renamed to
With the above suggestions applied, the code becomes:
Connection is... not doing it yourself,but using try-with-resources, which is the best practice as of Java 7:
public String getStory(String id) throws Exception {
try (Connection conn = MysqlDb.getConn(dbName)) {
for (Publisher p : Publishers) {
PreparedStatement prpStmt = conn.prepareStatement("SELECT story FROM " + p + " WHERE id='" + id + "'");
ResultSet rs = prpStmt.executeQuery();
while (rs.next()) {
String story = rs.getString(1);
rs.close();
return story;
}
rs.close();
}
}
return null;
}There are a couple of other issues in your code:
-
You're not using the prepared statement properly and to its full advantage. Don't create a query string as a concatenation of variables used in the WHERE clause. Those values should be set via the prepared statement. In its current form, your query may be vulnerable to SQL injection attacks.
-
The inner
while loop is not actually looping. You should replace the while with an if.-
You should use try-with-resources for the prepared statement and the result set too
-
"Publishers" looks like a collection, a variable, but by the naming conventions of Java only class names should start with a capital letter. So this should be renamed to
publishers.With the above suggestions applied, the code becomes:
public String getStory(String id) throws Exception {
try (Connection conn = MysqlDb.getConn(dbName)) {
for (Publisher p : publishers) {
String sql = "SELECT story FROM " + p + " WHERE id = ?";
try (PreparedStatement prpStmt = conn.prepareStatement(sql)) {
prpStmt.setString(1, id);
try (ResultSet rs = prpStmt.executeQuery()) {
if (rs.next()) {
return rs.getString(1);
}
}
}
}
}
return null;
}Code Snippets
public String getStory(String id) throws Exception {
try (Connection conn = MysqlDb.getConn(dbName)) {
for (Publisher p : Publishers) {
PreparedStatement prpStmt = conn.prepareStatement("SELECT story FROM " + p + " WHERE id='" + id + "'");
ResultSet rs = prpStmt.executeQuery();
while (rs.next()) {
String story = rs.getString(1);
rs.close();
return story;
}
rs.close();
}
}
return null;
}public String getStory(String id) throws Exception {
try (Connection conn = MysqlDb.getConn(dbName)) {
for (Publisher p : publishers) {
String sql = "SELECT story FROM " + p + " WHERE id = ?";
try (PreparedStatement prpStmt = conn.prepareStatement(sql)) {
prpStmt.setString(1, id);
try (ResultSet rs = prpStmt.executeQuery()) {
if (rs.next()) {
return rs.getString(1);
}
}
}
}
}
return null;
}Context
StackExchange Code Review Q#113951, answer score: 7
Revisions (0)
No revisions yet.