【问题标题】:Type mismatch: cannot convert from List<Map<String,Object>> to List<Object>类型不匹配:无法从 List<Map<String,Object>> 转换为 List<Object>
【发布时间】:2016-04-08 09:56:54
【问题描述】:

我们有

 String sql = "SELECT * FROM user WHERE id = '" +userId +"'";
 List<Object> userList = template.queryForList(sql);

查询应返回具有给定 id 的不同用户。 templateJdbcTemplate 类的对象。
这里查询返回Map&lt;String,Object&gt; 的列表,左侧是List&lt;Object&gt;。有没有办法进行转换。这是 Spring 事务管理示例的一部分。

【问题讨论】:

  • 只是好奇,你说“我猜它会回来”是什么意思?不确定返回类型本身?
  • 那么我的解决方案确实适用于这种情况。如果有任何问题,请告诉我。

标签: java spring jdbctemplate


【解决方案1】:

您始终可以只使用您首先感兴趣的values,例如:

List<Object> userList = new ArrayList<Object>(template.queryForList(sql).values());

如果它返回List&lt;Map&lt;String, Object&gt;&gt; 而不是Map&lt;String,Object&gt;

List < Object > userList = new ArrayList < Object > ();
for (Map < String, Object > obj: template.queryForList(sql)) {
    userList.addAll(obj.values());
}

这应该会根据需要为您提供Object 的列表。如果您需要探索为什么Map.values() 不能直接转换为列表,我们需要为此创建一个新的ArrayList,可以在这里找到:why HashMap Values are not cast in List

【讨论】:

  • 我收到以下错误: List> 类型的方法 values() 未定义。
  • 所以它返回 List> 而不是 Map 正如你所提到的那样。
  • 相应地更新了解决方案。
【解决方案2】:

我认为你应该采取另一种方法。 Spring 无法从数据库返回的数据中构建对象,但您可以使用RowMapper 来构建用户对象。此外,您不应自行构建查询,而应使用PreparedStatements。否则你可能容易受到 SQL 注入的攻击。

下面是一个例子:

template.query("SELECT * FROM user WHERE id = ?", new Object[] { userId }, new RowMapper<User>() {

    public User mapRow(ResultSet rs, int rowNum) {
        // Build a user from the current row and return it
    }

});

【讨论】:

  • 感谢您的回复,很好奇如果用户类有一个对象作为实例变量应该怎么做,那么从数据库接收到的值如何用于设置该实例变量的值因为数据库不包含该对象,而只包含一个 VARCHAR 或 NUMBER 值。
  • 我真的不明白你的意思。如果您需要进一步的帮助,请将您的User 类和相应表的结构添加到您的问题中。
【解决方案3】:

我想你把它搞糊涂了。最好的方法确实是 Steffen Kreutz 所建议的。考虑以下示例:

数据库中的用户表有以下字段:

1. UserID -> Type: Int
2. User_Name -> Type: Varchar
3. User_Contact -> Type: Varchar
...

现在,您可以简单地编写一个 RowMapper 将所有这些字段映射到您的自定义 POJO 对象,如下所示:

POJO 类:

public class User{
     private int userId;
     private String userName;
     private String userContact;

     public int getUserId() {
          return this.userId;
     }

     public void setUserId(int userId) {
          this.userId = userId;
     }

     /* Other Getter-Setter(s) */
}

查询字符串:

private static final String SELECT_QUERY = "SELECT * FROM user WHERE id = ?";

JdbcTemplate 调用: 在这里,您将 userId 传递给 ?。 JdbcTemplate 会自动处理它。

List<User> = (List<User>) jdbcTemplate.query(SELECT_QUERY, new Object[] { userId }, new UserRowMapper());

最后是 UserRowMapper 类:

class UserRowMapper implements RowMapper {

  @Override
  public Object mapRow(ResultSet resultSet, int row) throws SQLException {
    User user = new User();

    user.setUserId(resultSet.getInt("UserID"));
    user.setUserName(resultSet.getString("User_Name"));
    user.setUserContact(resultSet.getString("User_Contact"));

    return user;
  }
}

这确实是使用 JdbcTemplate 的最佳和推荐方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-17
    • 2014-04-07
    • 1970-01-01
    • 2015-12-18
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    相关资源
    最近更新 更多