繁体   English   中英

如何使用Spring jdbc模板(jdbcTemplate或namedParameterJDBCTem)从数据库中检索值

[英]How to use Spring jdbc templates (jdbcTemplate or namedParameterJDBCTem) to retrieve values from database

现在进入春天的几天。 将Spring-JDBC集成到我的Web应用程序中。 我成功地在我的DB上执行CRUD操作,对锅炉板代码的减少印象深刻。 但我没有使用NamedParameterJDBCTemplate提供的query*()方法。 Internet上的大多数示例都提供了RowMapperResultSetExtractor的用法。 虽然两种用法都很好,但它迫使我创建必须实现这些接口的类。 我必须为我为DB加载的每种类型的数据创建bean(或者我可能是错的)。

问题出现在代码部分我使用过这样的东西:

String query="select username, password from usertable where username=?"
ps=conn.prepareStatement(query);
ps.setString(username);
rs=ps.executeQuery();

if(rs.next()){
    String username=rs.getString("username");
    String password=rs.getString("password")

    //Performs operation on them
}  

由于这些值不存储在任何bean中并直接使用,因此我无法在这种情况下集成jdbcTemplate。 当我从数据库中仅提取bean中存在的部分属性时,会出现另一种情况。 例:

public class MangaBean{
    private String author;
    private String title;
    private String isbn;
    private String releaseDate;
    private String rating;

    //getters and setters

} 

制图员:

public class MangaBeanMapper implements RowMapper<MangaBean>{

    @Override
    public MangaBean mapRow(ResultSet rs, int arg1) throws SQLException {
        MangaBean mb=new MangaBean();
        mb.setAuthor(rs.getString("author"));
        mb.setTitle(rs.getString("title"));
        mb.setIsbn(rs.getString("isbn"));
        mb.setReleaseDate(rs.getString("releaseDate"));
        mb.setRating(rs.getString("rating"));
        return mb;
    }
}

以上安排如下:

String query="select * from manga_data where isbn=:isbn"
Map<String, String> paramMap=new HashMap<String, String>();
paramMap.put("isbn", someBean.getIsbn());
return template.query(query, paramMap, new MangaBeanMapper());

但是,如果我只想从我的db中检索两个/三个值,我就不能使用上面的模式,因为它生成BadSqlGrammarException: releaseDate does not exist in ResultSet 示例:

String query="select title, author where isbn=:isbn"
Map<String, String> paramMap=new HashMap<String, String>();
paramMap.put("isbn", someBean.getIsbn());
return template.query(query, paramMap, new MangaBeanMapper());

Template是NamedParameterJDBCTemplate一个实例。 请告诉我这些情况的解决方案。

其他答案是明智的:您应该创建一个DTO bean,或使用BeanPropertyRowMapper

但是如果你想能够拥有比BeanPropertyRowMapper更多的控制权,(或者反射使它太慢),你可以使用

queryForMap

方法,它将返回一个映射列表(每行一个),返回的列为键。 因为您可以在Map上调用get(/* key that is not there */)而不抛出异常(它只返回null),所以无论选择哪个列,都可以使用相同的代码填充对象。

您甚至不需要编写自己的RowMapper,只需使用spring提供的BeanPropertyRowMapper即可 它的工作方式是匹配返回给bean属性的列名。 您的查询具有与您的bean完全匹配的列,如果不是,您将在select中使用as,如下所示...

-- This query matches a property named matchingName in the bean
select my_column_that doesnt_match as matching_name from mytable;

BeanPropertyRowMapper应该与您列出的两个查询一起使用。

在第一个例子中,我只想创建一个DTO Bean / Value对象来存储它们。 它有一个共同实现的模式是有原因的,它需要几分钟的代码并提供许多长期的好处。

在第二个示例中,创建第二个rowmapper实现,在那里设置字段,或者在必要时为mangabean提供null / subsitute值:

    @Override
    public MangaBean mapRow(ResultSet rs, int arg1) throws SQLException {
    MangaBean mb=new MangaBean();
    mb.setAuthor(rs.getString("author"));
    mb.setTitle(rs.getString("title"));
   /* mb.setIsbn("unknown");*/
    mb.setReleaseDate("unknown");
    mb.setRating(null);
    return mb;
    }

通常,是:对于大多数查询,您将创建一个bean或对象以将结果转换为。 我会建议更多大多数情况,这是你想要做的。

但是,您可以创建一个RowMapper,将结果集映射到映射,而不是像这样映射bean。 下行将失去bean的类型管理,并且您将依赖于您的jdbc驱动程序为每列返回正确的类型。

正如@NimChimpskey刚刚发布的那样,最好创建一个小bean对象:但如果你真的不想这样做,这是另一种选择。

  class SimpleRowMapper implements RowMapper<Map<String, Object>> {
    String[] columns;

    SimpleRowMapper(String[] columns) {
      this.columns = columns;
    }

    @Override
    public Map<String, Object> mapRow(ResultSet resultSet, int i) throws SQLException {
      Map<String, Object> rowAsMap = new HashMap<String, Object>();
      for (String column : columns) {
        rowAsMap.put(column, resultSet.getObject(column));
      }
      return rowAsMap;
    }
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM