How to get Map data using JDBCTemplate.queryForMap
Asked Answered
G

4

47

How to load data from JDBCTemplate.queryForMap() as it returns the Map Interface? How is the query data maintained internally in the map? I tried to load it, but I got this exception: org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result

Code:-

public List getUserInfoByAlll() {
    List profilelist=new ArrayList();
    Map m=new HashMap();
    m=this.jdbctemplate.queryForMap("SELECT userid,username  FROM USER");
    Set s=m.keySet();
    Iterator it=s.iterator();
    while(it.hasNext()){
        String its=(String)it.next();
        Object ob=(Object)m.get(its);
        log.info("UserDAOImpl::getUserListSize()"+ob);
    }
    return profilelist;
}
Glidden answered 5/4, 2012 at 13:45 Comment(0)
I
67

queryForMap is appropriate if you want to get a single row. You are selecting without a where clause, so you probably want to queryForList. The error is probably indicative of the fact that queryForMap wants one row, but you query is retrieving many rows.

Check out the docs. There is a queryForList that takes just sql; the return type is a

List<Map<String,Object>>.

So once you have the results, you can do what you are doing. I would do something like

List results = template.queryForList(sql);

for (Map m : results){
   m.get('userid');
   m.get('username');
} 

I'll let you fill in the details, but I would not iterate over keys in this case. I like to explicit about what I am expecting.

If you have a User object, and you actually want to load User instances, you can use the queryForList that takes sql and a class type

queryForList(String sql, Class<T> elementType)

(wow Spring has changed a lot since I left Javaland.)

Iridize answered 5/4, 2012 at 13:49 Comment(2)
We are having queryForObject if retriving single object.what is difference between queryForObject and queryForMap?Glidden
from the documentation, queryForObject returns an instance of the specified class. queryForMap returns a map where each column is a key for the value.Iridize
G
56

I know this is really old, but this is the simplest way to query for Map.

Simply implement the ResultSetExtractor interface to define what type you want to return. Below is an example of how to use this. You'll be mapping it manually, but for a simple map, it should be straightforward.

jdbcTemplate.query("select string1,string2 from table where x=1", new ResultSetExtractor<Map>(){
    @Override
    public Map extractData(ResultSet rs) throws SQLException,DataAccessException {
        HashMap<String,String> mapRet= new HashMap<String,String>();
        while(rs.next()){
            mapRet.put(rs.getString("string1"),rs.getString("string2"));
        }
        return mapRet;
    }
});

This will give you a return type of Map that has multiple rows (however many your query returned) and not a list of Maps. You can view the ResultSetExtractor docs here: http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/jdbc/core/ResultSetExtractor.html

Glindaglinka answered 15/10, 2015 at 14:27 Comment(2)
I prefer this answer to the chosen one, much simpler, less work required.Corvin
@Corvin Not to mention less temporary objects alocatedPlaybook
K
34

To add to @BrianBeech's answer, this is even more trimmed down in java 8:

jdbcTemplate.query("select string1,string2 from table where x=1", (ResultSet rs) -> {
    HashMap<String,String> results = new HashMap<>();
    while (rs.next()) {
        results.put(rs.getString("string1"), rs.getString("string2"));
    }
    return results;
});
Katonah answered 25/5, 2017 at 19:27 Comment(2)
HashMap<String,String> results = new HashMap<>(); results.put(rs.getString("string1"), rs.getString("string2")); return results;Kwabena
No need for while loop , already it is getting itrated over resultsetKwabena
A
12

You can do something like this.

 List<Map<String, Object>> mapList = jdbctemplate.queryForList(query));
    return mapList.stream().collect(Collectors.toMap(k -> (Long) k.get("userid"), k -> (String) k.get("username")));

Output:

 {
  1: "abc",
  2: "def",
  3: "ghi"
}
Asperity answered 5/11, 2019 at 10:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.