Nigdy nie należy przekazywać ResultSet
wokół za pomocą publicznych metod. Jest to podatne na wycieki zasobów, ponieważ jesteś zmuszony zachować otwarte oświadczenie i połączenie. Zamknięcie ich spowodowałoby niejawne zamknięcie zestawu wyników. Ale trzymanie ich otwartych spowoduje, że będą się kołysać i spowodować, że DB zabraknie zasobów, gdy jest ich zbyt wiele otwartych.
Zmapuj go na kolekcję Javabeans w ten sposób i zamiast tego zwróć:
public List<Biler> list() throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
List<Biler> bilers = new ArrayList<Biler>();
try {
connection = database.getConnection();
statement = connection.prepareStatement("SELECT id, name, value FROM Biler");
resultSet = statement.executeQuery();
while (resultSet.next()) {
Biler biler = new Biler();
biler.setId(resultSet.getLong("id"));
biler.setName(resultSet.getString("name"));
biler.setValue(resultSet.getInt("value"));
bilers.add(biler);
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
return bilers;
}
Lub, jeśli już korzystasz z Javy 7, skorzystaj z spróbuj-z-zasobami oświadczenie, które automatycznie zamknie te zasoby:
public List<Biler> list() throws SQLException {
List<Biler> bilers = new ArrayList<Biler>();
try (
Connection connection = database.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, name, value FROM Biler");
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
Biler biler = new Biler();
biler.setId(resultSet.getLong("id"));
biler.setName(resultSet.getString("name"));
biler.setValue(resultSet.getInt("value"));
bilers.add(biler);
}
}
return bilers;
}
Przy okazji, nie powinieneś deklarować Connection
, Statement
i ResultSet
jako zmienne instancji (poważny problem z bezpieczeństwem wątków!), ani nie połykaj SQLException
w tym momencie (wywołujący nie będzie miał pojęcia, że wystąpił problem), ani nie zamyka zasobów w tym samym try
(jeśli np. zamknięcie zestawu wyników zgłosi wyjątek, to instrukcja i połączenie są nadal otwarte). Wszystkie te problemy zostały naprawione w powyższych fragmentach kodu.