Я думаю, что Вы подвели итог его вполне хорошо в Вашем собственном ответе.
В процессе UTF-8-ing(?) от вплотную Вы могли бы также хотеть удостовериться, что сам Java использует UTF-8. Используйте-Dfile.encoding=utf-8 в качестве параметра к JVM (может быть настроен в catalina.bat).
Пусто или нет, но выполнение следующих действий всегда неверно :
resultSet = statement.executeQuery(sql);
string = resultSet.getString(1); // Epic fail. The cursor isn't set yet.
Это не ошибка. Это задокументированное поведение . Это упоминается в каждом приличном руководстве по JDBC . Вам необходимо установить курсор ResultSet с помощью next ()
, прежде чем вы сможете получить доступ к любым данным.
Если вас действительно интересует, существует ли предположительно уникальная строка или нет, тогда просто проверьте результат 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;
}
Если вы действительно ожидаете только ноль или одну строку, то просто выполните что-то вроде:
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?
}
Если вы действительно ожидаете только ноль или много строк, затем просто выполните что-то вроде:
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?
}
Из JavaDocs для ResultSet :
Объект ResultSet поддерживает курсор указывая на текущую строку данных. Изначально курсор установлен перед первым рядом. Следующий способ перемещает курсор в следующую строку и потому что он возвращает false, когда есть больше нет строк в ResultSet объект, его можно использовать в цикле while для итерации по набору результатов.
Вам необходимо разместить ResultSet
в строке, например, вызвав вызов next ()
, прежде чем пытаться прочитать какие-либо данные. Если вызов next ()
возвращает false
, то набор результатов пуст.