#java #sql #hibernate
#java #sql #гибернация
Вопрос:
Мне нужно реализовать метод DAO для проверки существования строки в таблице и соответствующего возврата логического значения. Показана грубая версия:
public boolean check(Integer bookId) {
logger.info(BookDAOImpl.class.getName() ".check() method called.");
return bookId.equals(this.get(bookId).getBookId());
}
Мне не нужно возвращать найденную строку.
Поскольку это только для демонстрационного приложения, я использую:
@Override
public boolean check(Integer bookId) {
logger.info(PersonDAOImpl.class.getName() ".check() method called.");
try {
Book book = this.get(bookId);
return bookId.intValue() == book.getBookId().intValue();
}
catch(IndexOutOfBoundsException e) {
return false;
}
}
Комментарии:
1. Могу ли я узнать, почему вы хотите реализовать такой метод, какова основная идея, стоящая за этим?
2. Согласно вопросу, чтобы буквально проверить существование строки в таблице и соответственно вернуть логическое поле.
3. .. и как вы будете уверены, что после возврата из
get(bookId);
никакой другой транзакции сеанс не будет зафиксирован иbookId
не будет изменен.?4. Допустимый вопрос, но поскольку это всего лишь простое демонстрационное приложение, меня не очень волнуют проблемы параллелизма. BookID в любом случае является ключом, поэтому он никогда не должен меняться.
5. Хорошо, но это не очень хорошая практика, я хотел бы добавить еще одну вещь. Используйте
Criteria
API вместе сProjection
и выберите только один столбец вместо выбора всех столбцов.
Ответ №1:
Я предполагаю, что вы пытаетесь оптимизировать проверку в интересах производительности.
Позвольте мне уточнить так: получение строки состоит из трех шагов: 1. Выполнение вызова / запроса метода по сети 2. Сканирование Oracle и поиск совпадающих строк (с индексом или без него) 3. Копирование данных строки и их возврат
Затраты, связанные с (1) и (2), огромны, тогда как стоимость (3) невелика. Итак, ИМХО, нет смысла пытаться оптимизировать объем возвращаемых данных.
Например, если для проверки требуется 120 мс, для получения данных может потребоваться всего 125 мс. В обычных случаях вряд ли будет разница в 5%.
Примечание: — Если ваше условие WHERE использует индексы, (2) также станет менее дорогостоящим — Если вы выбираете от 50 до сотен столбцов, тогда имеет смысл найти способ сделать это.
Предложение: если вы не выбираете более 50 столбцов, не беспокойтесь. Просто получите полные данные и проверьте resultList.size().
Комментарии:
1. Хороший совет. Это только для демонстрационного приложения. Я опубликовал свой окончательный метод.
2. Рад помочь. Еще одна вещь: вы можете перехватить исключение NullPointerException вместо того, чтобы индексировать вне границ. Также вы можете полностью опустить try catch и просто сделать это, если хотите: return book==null? false:BookID.intValue() == book.getBookId().intValue();
3.
Where
по первичному ключу (учитывая, что bookid является первичным ключом) не будет дорогостоящим.
Ответ №2:
Просто запросите базу данных, используя hibernate с BookID. Если возвращается какой-либо результирующий набор, верните true или false.