类型不匹配:无法将List<Map<String,Object>>转换为List<Object>

4

我们有

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

这个查询应该返回给定id的不同用户。 template 是一个JdbcTemplate类的对象。
这里的查询返回了一个Map<String,Object>的列表,而左侧是List<Object>。是否有办法进行转换。这是Spring事务管理示例的一部分。


好奇一下,当你说“我猜它返回”时,你是指什么?不确定返回类型本身吗? - Aaditya Gavandalkar
那么我的解决方案对于这种情况确实有效。如果有任何问题,请告诉我。 - Aaditya Gavandalkar
3个回答

2

您始终可以仅使用您最感兴趣的,例如:

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

如果返回的是 List<Map<String, Object>> 而不是 Map<String,Object>
List < Object > userList = new ArrayList < Object > ();
for (Map < String, Object > obj: template.queryForList(sql)) {
    userList.addAll(obj.values());
}

这应该会给你一个所需的Object列表。如果你需要探索为什么Map.values()不能直接转换为列表,我们需要创建一个新的ArrayList,可以在这里找到:为什么HashMap值不能强制转换为List

我收到了以下错误: 类型List<Map<String,Object>>没有定义方法values()。 - user1
因此,它返回的是List<Map<String,Object>>,而不是你在问题中提到的Map<String,Object>。 - Aaditya Gavandalkar
相应地更新了解决方案。 - Aaditya Gavandalkar

1
我觉得你有些混淆了。最好的方法确实是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的最佳推荐方式。


1
我认为你应该采取另一种方法。Spring 无法从数据库返回的数据构建对象,但是你可以使用 RowMapper 构造用户对象。此外,你不应该自己构建查询,而是使用 PreparedStatement。否则,你可能会容易受到 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
    }

});

感谢您的回复,我很好奇如果Users类有一个对象作为实例变量,那么当从数据库接收到值时,如何将其用于设置该实例变量的值,因为数据库中并不包含该对象,而只包含VARCHAR或NUMBER值。 - user1
我不太明白你的意思。如果需要进一步帮助,请在问题中添加您的“User”类和相应表的结构。 - stevecross

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接