带有春季启动和名称参数的本机查询


您需要使用Spring Boot运行本机查询吗?您应该查询遗留应用程序的数据库吗?您是否认为,如果您执行一个本机查询,就可以在数据库中保存许多表的映射?

在这些情况下,我最喜欢的方法是使用NamedParameterJdbcTemplate。接下来,我们将看到一个如何使用它的例子。在我们的情况下,我们必须从给定的客户那里获得订单数量。

首先,我们必须定义将获得查询结果的POJO (DTO):

public class NativeQueryDTO {
    private String name;
    private int orderCount;
...
    //Getters - Setters   
}

然后我们必须创建存储库,其中包含返回所需信息的方法:

@Component
public class NativeRepository {
    @Autowired 
    private NamedParameterJdbcTemplate jdbcTemplate;

    public NativeQueryDTO countCustomerOrder(Long id){        
        MapSqlParameterSource parameters = new MapSqlParameterSource();
        parameters.addValue("customerId", id);

        String sql = " select c.name, count(o) as orderCount  "
                   + " from customers c, orders o "
                   + " where c.id = o.customer_id and c.id = :customerId "
                   + " group by c.name ";

        return (NativeQueryDTO)jdbcTemplate.queryForObject(
            sql, parameters, BeanPropertyRowMapper.newInstance(NativeQueryDTO.class));  
    }
}

前面的代码使用了执行查询的queryForObject方法,并且将必要的参数与MapSqlParameterSource类型的对象一起传递。为了获得正确的映射作为第三个参数,我们必须发送一个带有类映射的BeanPropertyRowMapper。因为我们正在使用BeanPropertyRowMapper,所以我们不需要实现一个RowMapper。

最后,在Spring的官方文档中,他们建议在需要更好性能的情况下实现一个定制的行映射器。

public class NativeQueryDTOMapper implements RowMapper<NativeQueryDTO> {
    @Override
    public NativeQueryDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
        NativeQueryDTO dto = new NativeQueryDTO();
        dto.setName(rs.getString("name"));
        dto.setOrderCount(rs.getInt("orderCount"));
        return dto;
    }  
}

然后按如下方式使用它:

return (NativeQueryDTO)jdbcTemplate.queryForObject(
            sql, parameters, new NativeQueryDTOMapper());  

我们已经看到,在Spring Boot中使用本机查询非常容易,我希望这个例子有所帮助。下次见!