空かどうかはわかりませんが、次のことを行うと常に問題が発生します。
resultSet = statement.executeQuery(sql);
string = resultSet.getString(1); // Epic fail. The cursor isn't set yet.
これはバグではありません。これは文書化された動作です。すべてのまともなJDBCチュートリアルはそれについて言及しています。next()
データにアクセスする前に、を使用してResultSetのカーソルを設定する必要があります。
おそらく一意の行が存在するかどうかに実際に興味がある場合は、の結果を確認してくださいnext()
。たとえば、架空UserDAO
のクラスでは:
public boolean exist(String username, String password) throws SQLException {
boolean exist = false;
try (
Connection connection = database.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id FROM user WHERE username = ? AND password = MD5(?)");
) {
statement.setString(1, username);
statement.setString(2, password);
try (ResultSet resultSet = statement.executeQuery()) {
exist = resultSet.next();
}
}
return exist;
}
実際に0行または1行しか期待できない場合は、次のようにします。
public User find(String username, String password) throws SQLException {
User user = null;
try (
Connection connection = database.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, username, email, birthdate FROM user WHERE username = ? AND password = MD5(?)");
) {
statement.setString(1, username);
statement.setString(2, password);
try (resultSet = statement.executeQuery()) {
if (resultSet.next()) {
user = new User(
resultSet.getLong("id"),
resultSet.getString("username"),
resultSet.getString("email"),
resultSet.getDate("birthdate"));
}
}
}
return user;
}
次に、ビジネス/ドメインオブジェクトでそれに応じて処理します。
User user = userDAO.find(username, password);
if (user != null) {
// Login?
}
else {
// Show error?
}
実際に0行または多数の行しか期待できない場合は、次のようにします。
public List<User> list() throws SQLException {
List<User> users = new ArrayList<User>();
try (
Connection connection = database.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, username, email, birthdate FROM user");
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
users.add(new User(
resultSet.getLong("id"),
resultSet.getString("username"),
resultSet.getString("email"),
resultSet.getDate("birthdate")));
}
}
return users;
}
次に、ビジネス/ドメインオブジェクトでそれに応じて処理します。
List<User> users = userDAO.list();
if (!users.isEmpty()) {
int count = users.size();
// ...
}
else {
// Help, no users?
}