在RowMapper中使用查询
在java中我会做类似下面的事情来迭代resultset
并形成查询,
public Map<String, List> fun(){ Map<String, List> map = new TreeMap<String, List>(); LinkedHashSet set = new LinkedHashSet(); 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 list = new ArrayList(); 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; }
我使用单独查询的原因是,我将不同的值添加到地图键及其对应的值(作为List)到地图的值。 注意 (在结果中它具有column1的重复值),但我需要将它们存储为map键,从而使其成为唯一的。 我还需要所有相关的值,以便填充列表
如何使用JdbcTemplate
实现相同的function,
提前致谢
正如多人所说,你的解决方案效率不高,虽然它可能有效但你基本上陷入了1 + N选择问题的陷阱。 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
是否已经存在List
。 如果是先添加一行,如果不是先创建List
并将其添加到结果Map
。
public Map> fun(){ final Map> map = new TreeMap>(); 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 (); map.put(key, rows); } MODEL obj = new MODEL(); // set values to setters from resultset rows.add(obj); }, "arguments"); return map; }
另一个解决方案,只有在’列’也是MODEL
类的一部分时才有效。 这样你就可以使用RowMapper
获取所有MODEL
对象的List
,然后进行分区。 您可以使用Google Guava使其更容易实现,或者如果您使用的是Java 8,则可以使用新的流api。
正如@geoand所说,最好的事情(无论是直接的JDBC代码还是使用JDBCTemplate)都是使用Join进行单个查询。
但是,如果您在评论中提到,您绝对肯定第一个查询的结果集总是很小(可疑),那么您可以将从第一个查询中检索到的值存储在列表中,然后执行第二个查询带有“in”子句,使用列表作为参数。 这将导致两个查询。
在任何情况下,您实际上不希望对从第一个查询返回的每个项目执行单独的查询,因为这将非常慢,即使对于少量项目也是如此。 但是,如果您认为必须 ,则将第一个查询的结果存储在列表中,然后为列表中的每个项目发出另一个查询。
TLDR; 不,JDBCTemplate不提供执行所需操作的机制,主要是因为它通常被认为是编程反模式的规范示例。
- 是否可以在没有带有@XmlJavaTypeAdapter的no-args构造函数的类上使用@XmlSeeAlso?
- 如何在Java中使用ln
- Rhino:限制可以从JavaScript访问的Java包
- Glassfish无法在root用户部署,因为声明了default-web-module
- 任何人都可以推荐基于MVC的Java Web框架并支持REST吗?
- 每个不可变的class级应该是最终的吗?
- 在JMeter中的BeanShell Sampler中将字符串解析为整数
- 经常使用instanceof是一种好习惯吗?
- java.lang.IllegalArgumentException:string curve25519 not a OID bouncycastle 1.52