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

可以在此处找到更多信息:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.html#queryForObject-java.lang.String-org.springframework.jdbc.core.namedparam.SqlParameterSource-org.springframework.jdbc.core.RowMapper-