Я использую Jdbctemplate для получения одного значения String из базы данных. Вот мой метод.
public String test() {
String cert=null;
String sql = "select ID_NMB_SRZ from codb_owner.TR_LTM_SLS_RTN
where id_str_rt = '999' and ID_NMB_SRZ = '60230009999999'";
cert = (String) jdbc.queryForObject(sql, String.class);
return cert;
}
В моем сценарии вполне возможно НЕ получить ответ на мой запрос, поэтому мой вопрос заключается в том, как мне обойти следующее сообщение об ошибке.
EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
Мне казалось, что я должен просто вернуть null вместо того, чтобы генерировать исключение. Как я могу это исправить? Заранее спасибо.
источник
ResultSet.next()
было бы вызвано без необходимости. В этом случае использование aResultSetExtractor
- гораздо более эффективный инструмент.return null
вcatch(EmptyResultDataAccessException exception){ return null; }
?Вы также можете использовать
ResultSetExtractor
вместоRowMapper
. Оба так же просты, как и друг друга, разница только в том, что вы звонитеResultSet.next()
.ResultSetExtractor
Имеет дополнительное преимущество , что вы можете обрабатывать все случаи , когда Есть более чем одна строка или нет строк , возвращаемых.ОБНОВЛЕНИЕ : прошло несколько лет, и у меня есть несколько уловок.
JdbcTemplate
великолепно работает с лямбдами java 8, для которых предназначены следующие примеры, но вы можете легко использовать статический класс для достижения того же.Хотя речь идет о простых типах, эти примеры служат руководством для общего случая извлечения объектов предметной области.
Прежде всего. Предположим, что у вас есть объект учетной записи с двумя свойствами для простоты
Account(Long id, String name)
. Вероятно, вы захотите иметьRowMapper
для этого объекта домена.Теперь вы можете использовать это средство сопоставления непосредственно в методе для сопоставления
Account
объектов домена из запроса (jt
являетсяJdbcTemplate
экземпляром).Отлично, но теперь нам нужна наша исходная проблема, и мы используем мое исходное решение, повторно используя
RowMapper
для выполнения сопоставления для нас.Отлично, но это шаблон, который вы можете и захотите повторить. Таким образом, вы можете создать общий фабричный метод для создания новой
ResultSetExtractor
задачи.Создание
ResultSetExtractor
now становится тривиальным.Я надеюсь, что это поможет показать, что теперь вы можете довольно легко комбинировать части мощным способом, чтобы упростить свой домен.
ОБНОВЛЕНИЕ 2 : объедините с необязательным для необязательных значений вместо нуля.
Который теперь при использовании может иметь следующее:
источник
Это не лучшее решение, потому что вы полагаетесь на исключения для потока управления. В вашем решении нормально получать исключения, нормально иметь их в журнале.
источник
ResultSet.next()
было бы вызвано без необходимости. В этом случае использование aResultSetExtractor
- гораздо более эффективный инструмент.Хорошо, я разобрался. Я просто обернул его в try catch и отправил обратно null.
источник
На самом деле, вы можете поиграть
JdbcTemplate
и настроить свой собственный метод по своему усмотрению. Я предлагаю сделать что-то вроде этого:Работает как оригинал
jdbc.queryForObject
, но безthrow new EmptyResultDataAccessException
когдаsize == 0
.источник
UserMapper implements RowMapper<String>
.DataAccessUtils.singleResult(...)
это то, что я искал. ThxПоскольку при использовании queryForObject я часто хочу возвращать значение NULL при отсутствии данных, я счел полезным расширить JdbcTemplate и добавить метод queryForNullableObject, аналогичный приведенному ниже.
Теперь вы можете использовать это в своем коде так же, как вы использовали queryForObject
Мне было бы интересно узнать, думает ли кто-нибудь еще, что это хорошая идея?
источник
Используя Java 8 или выше, вы можете использовать
Optional
и Java Streams.Таким образом, вы можете просто использовать
JdbcTemplate.queryForList()
метод, создать Stream и использовать,Stream.findFirst()
который вернет первое значение Stream или пустойOptional
:Чтобы повысить производительность запроса, вы можете добавить его
LIMIT 1
к своему запросу, чтобы из базы данных передавалось не более 1 элемента.источник
Вы можете использовать групповую функцию, чтобы ваш запрос всегда возвращал результат. т.е.
источник
В Postgres вы можете сделать так, чтобы почти любой запрос с одним значением возвращал значение или ноль, обернув его:
и, следовательно, избежать сложности в вызывающем.
источник
Поскольку getJdbcTemplate (). QueryForMap ожидает минимальный размер, равный единице, но когда он возвращает null, он показывает EmptyResultDataAccesso fix dis, когда можно использовать приведенную ниже логику
источник
Я имел дело с этим раньше и писал на весенних форумах.
http://forum.spring.io/forum/spring-projects/data/123129-frustrated-with-emptyresultdataaccessexception
Мы получили совет использовать тип SQlQuery. Вот пример того, что мы сделали, пытаясь получить значение из БД, которого может не быть.
В DAO мы просто звоним ...
Непонятно по производительности, но работает и аккуратно.
источник
Для Байрона вы можете попробовать это ..
источник
делать
работать, убедитесь, что ваш jdbcTemplate имеет тип
источник
Мы можем использовать query вместо queryForObject, основное различие между query и queryForObject заключается в том, что список возвращаемых запросов Object (на основе возвращаемого типа Row mapper) и этот список может быть пустым, если данные не получены из базы данных, в то время как queryForObject всегда ожидает, что будет только один объект. не извлекается из db ни null, ни несколько строк, и в случае, если результат пуст, тогда queryForObject выдает исключение EmptyResultDataAccessException, я написал один код с использованием запроса, который преодолеет проблему EmptyResultDataAccessException в случае нулевого результата.
источник
IMHO возврат a
null
- плохое решение, потому что теперь у вас есть проблема с отправкой и интерпретацией его (вероятного) клиентского интерфейса. У меня была такая же ошибка, и я решил ее, просто вернувList<FooObject>
. Я использовалJDBCTemplate.query()
.Во внешнем интерфейсе (веб-клиент Angular) я просто просматриваю список и, если он пуст (нулевой длины), считаю, что записей не найдено.
источник
Я просто ловлю это "EmptyResultDataAccessException"
тогда вы можете проверить:
источник