NamedParameterJdbcTemplate.query 只返回一个元素
NamedParameterJdbcTemplate.query for returning only one element
我正在编写一个方法来检索 DB 的元素,提供一个 Long id 参数。
这个 id 是唯一的,所以该方法应该只是 return 一个元素,我想创建一个 class 实例来检索这个元素。
我采用了以下非常有效的方法:
@Override
public ElementEntity getElement(final long id)
{
final MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("element_id", id);
final List<ElementEntity > listOfElements =
namedParameterJdbcOperations.query(SQL_RETURN_ELEMENT_BY_ID, paramSource, ROW_MAPPER_ELEMENT);
return !listOfElements .isEmpty() ? listOfElements.get(0) : null;
}
ROW_MAPPER是这样实现的:
private static final RowMapper<ElementEntity > ROW_MAPPER_INSTALLER =
(rs, RowNum) ->
new ElementEntityBuilder().setElement(rs.getBytes("ELEMENT")).build();
该元素是一个字节数组。我再说一遍,效果很好。但我想避免使用列表并检索第一个位置,而是直接创建 ElementEntity。所以我尝试了以下方法:
@Override
public ElementEntity getElement(final long id)
{
final MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("element_id", id);
return namedParameterJdbcOperations.query(SQL_RETURN_ELEMENT_BY_ID, paramSource, (ResultSet rs) -> new DesktopAppInstallerEntity(rs.getBytes("ELEMENT")));
}
尽管我没有再做任何更改,但它给了我以下错误:org.h2.jdbc.JdbcSQLNonTransientException: No data is available
。
这是完整的错误(我更改了一些词以避免显示真实的 SQL 查询):
org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [SELECT SOMETHING FROM SOMEWHERE WHERE id = ?]; No data is available [2000-200]; nested exception is org.h2.jdbc.JdbcSQLNonTransientException: No data is available [2000-200]
我对这一切还很陌生 JDBC,但在我看来,当我应用此更改时,paramSource 无法正常工作,而且我完全不知道为什么会这样,因为我我只是在更改结果提取器。
好吧,我自己想出来了。我将分享我的答案以帮助社区。我使用 NamedParameterJdbcOperations.queryForObject
而不是 namedParameterJdbcOperations.query
并使用相同的 ROW_MAPPER:
@Override
public ElementEntity getElement(final long id)
{
final MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("id", id);
try
{
return namedParameterJdbcOperations.queryForObject(SQL_RETURN_ELEMENT, paramSource, ROW_MAPPER_ELEMENT);
}
catch (EmptyResultDataAccessException e)
{
return null;
}
}
在我的特定情况下,当 SQL 查询尝试查找数据库中不存在的元素时,我很感兴趣。为此,我捕获并处理抛出的 EmptyResultDataAccessException
。
我正在编写一个方法来检索 DB 的元素,提供一个 Long id 参数。
这个 id 是唯一的,所以该方法应该只是 return 一个元素,我想创建一个 class 实例来检索这个元素。
我采用了以下非常有效的方法:
@Override
public ElementEntity getElement(final long id)
{
final MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("element_id", id);
final List<ElementEntity > listOfElements =
namedParameterJdbcOperations.query(SQL_RETURN_ELEMENT_BY_ID, paramSource, ROW_MAPPER_ELEMENT);
return !listOfElements .isEmpty() ? listOfElements.get(0) : null;
}
ROW_MAPPER是这样实现的:
private static final RowMapper<ElementEntity > ROW_MAPPER_INSTALLER =
(rs, RowNum) ->
new ElementEntityBuilder().setElement(rs.getBytes("ELEMENT")).build();
该元素是一个字节数组。我再说一遍,效果很好。但我想避免使用列表并检索第一个位置,而是直接创建 ElementEntity。所以我尝试了以下方法:
@Override
public ElementEntity getElement(final long id)
{
final MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("element_id", id);
return namedParameterJdbcOperations.query(SQL_RETURN_ELEMENT_BY_ID, paramSource, (ResultSet rs) -> new DesktopAppInstallerEntity(rs.getBytes("ELEMENT")));
}
尽管我没有再做任何更改,但它给了我以下错误:org.h2.jdbc.JdbcSQLNonTransientException: No data is available
。
这是完整的错误(我更改了一些词以避免显示真实的 SQL 查询):
org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [SELECT SOMETHING FROM SOMEWHERE WHERE id = ?]; No data is available [2000-200]; nested exception is org.h2.jdbc.JdbcSQLNonTransientException: No data is available [2000-200]
我对这一切还很陌生 JDBC,但在我看来,当我应用此更改时,paramSource 无法正常工作,而且我完全不知道为什么会这样,因为我我只是在更改结果提取器。
好吧,我自己想出来了。我将分享我的答案以帮助社区。我使用 NamedParameterJdbcOperations.queryForObject
而不是 namedParameterJdbcOperations.query
并使用相同的 ROW_MAPPER:
@Override
public ElementEntity getElement(final long id)
{
final MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("id", id);
try
{
return namedParameterJdbcOperations.queryForObject(SQL_RETURN_ELEMENT, paramSource, ROW_MAPPER_ELEMENT);
}
catch (EmptyResultDataAccessException e)
{
return null;
}
}
在我的特定情况下,当 SQL 查询尝试查找数据库中不存在的元素时,我很感兴趣。为此,我捕获并处理抛出的 EmptyResultDataAccessException
。