在java中,我会做类似下面的事情来迭代resultset
并形成查询,
public Map<String, List<MODEL>> fun(){
Map<String, List<MODEL>> map = new TreeMap<String, List<MODEL>>();
LinkedHashSet<String> set = new LinkedHashSet<String>();
String sql = "select distinct(column) from table where conditions orderby column ";
ResultSet rslt = stmt.executeQuery(sql);
while (rslt.next()) {
al.add(rslt.getString(1));
}
for (String s : al) {
List<MODEL> list = new ArrayList<MODEL>();
String sql2 = "select * from table where column="+s;
ResultSet rslt2 = stmt.executeQuery(sql2);
while (rslt2.next()) {
MODEL obj = new MODEL();
// set values to setters from resultset
list.add(obj);
}
map.put(s, list);
}
return map;
}
我使用单独查询的原因是,我将不同的值添加到地图键及其对应的值(如列表)到地图的值。注意 (在结果中它具有 column1 的重复值),但我需要将它们存储为地图键,从而使其成为唯一的。 我还需要所有相关的值,以便填充列表
如何使用JdbcTemplate
,
提前致谢
答案 0 :(得分:2)
正如多人所说,你的解决方案效率不高,虽然它可能有效但你基本上陷入了1+N select problem的陷阱。 1个查询检索一个id,然后为每个id检索另一个查询(因此1 + N选择)。
最好只编写一个查询,一次性检索所有内容。查看您的代码,您有以下2个查询,根据它们的外观,它们在同一个表上运行。
String sql1 = "select distinct(column) from table where conditions orderby column ";
String sql2 = "select * from table where column="+s
现在,您可以将第一个查询作为第二个查询的子选择
String sql = "select * from table where column in (select distinct(column) from table where conditions) order by column";
然而,再次从它的外观来看,将第二个查询中的where子句放在一起也是可能的(或者甚至更容易)。
String sql = "select * from table where conditions order by column";
您现在可能会获取您的密钥(在Map
中)获取多个值。您可以自己对结果使用ResultSetExtractor
循环或使用为您进行迭代的RowCallbackHandler
做两件事。
您需要做的只是对结果进行迭代(或让JdbcTemplate
为您执行此操作),如果Map
已经存在,则{key> List
。如果是先添加一行,则首先创建List
并将其添加到结果Map
。
public Map<String, List<MODEL>> fun(){
final Map<String, List<MODEL>> map = new TreeMap<String, List<MODEL>>();
String sql = "select * from table where conditions order by column";
getJdbcTemplate().query(sql, new RowCallbackHandler() {
public void processRow(ResultSet resultSet) throws SQLException {
String key = rs.getString("column");
List rows = map.get(key);
if (rows == null) {
rows = new new ArrayList<MODEL>();
map.put(key, rows);
}
MODEL obj = new MODEL();
// set values to setters from resultset
rows.add(obj);
}, "arguments");
return map;
}
另一种解决方案,只有在“列”也是MODEL
类的一部分时才有效。这样,您可以使用RowMapper
并获取所有List
个对象的MODEL
,然后进行分区。您可以使用Google Guava使其更容易实现,或者如果您使用的是Java 8,则可以使用新的流api。
答案 1 :(得分:1)
正如@geoand所说,最好的事情(无论是直接的JDBC代码还是使用JDBCTemplate)都是使用Join进行单个查询。
但是,正如您在评论中提到的那样,您绝对肯定第一个查询的结果集总是小(可疑),那么您可以存储从中检索到的值首先在列表中查询,然后使用列表作为参数,使用“in”子句执行第二次查询。这将导致两个查询。
在任何情况下,你真的不想对第一个查询返回的每个项目进行单独的查询,因为即使对于少量项目,这也会非常慢。但是,如果您认为必须,则将第一个查询的结果存储在列表中,然后为列表中的每个项目发出另一个查询。
TLDR;不,JDBCTemplate不提供执行所需操作的机制,主要是因为它通常被认为是编程反模式的规范示例。