我花了很多时间来找到解决方案,但我仍然不能。
我找到了一些有关如何将“ IN”元素传递到PreparedStatement中的解决方案,但是如果有其他解决方案,我很高兴看到,但是无论如何我还是有
RowMapper<Map<BigInteger, Status>> mapper = new QueryDescriptionById.RowMapperDescription();
@Override
public Multimap<BigInteger, Status> findObject(BigInteger[] ids) {
StringBuilder builder = new StringBuilder();
for (Object id : ids) {
builder.append("?,");
}
String statement = SQL + builder.deleteCharAt(builder.length() - 1).toString() + ")";
Multimap<BigInteger, Status> multimap = ArrayListMultimap.create();
intoMap(multimap, getJdbcTemplate().query(statement, ps -> {
int index = 1;
for (BigInteger id : ids) {
ps.setInt(index++, id.intValue());
}
}, mapper));
return multimap;
}
private void intoMap(Multimap<BigInteger, Status> multimap, List<Map<BigInteger, Status>> list) {
list.forEach(map -> map.forEach((multimap::put)));
}
class RowMapperDescription implements RowMapper {
@Override
public Map<BigInteger, Status> mapRow(ResultSet rs, int rowNum) throws SQLException {
Status status = new Status();
Map<BigInteger, Status> map = new HashMap<>();
BigInteger id = rs.getBigDecimal("ID").toBigInteger();
BigInteger parentId = rs.getBigDecimal("PARENT_ID").toBigInteger();
status.setId(id);
status.setDescription(rs.getString("attempt_status_text"));
map.put(parentId, status);
return map;
}
}
但是当我仅将1个元素传递给BigInteger []时,它会很好地工作,但是当有2个或更多元素时,它不会进入我的映射器。
为什么?
PS
我尝试使用ResultSet代替RowMapper
return getJdbcTemplate().query(SQL, ids, resultSet -> {
Multimap<BigInteger, Status> multimap = ArrayListMultimap.create();
int rowNum = 0;
while (resultSet.next()) {
System.out.println("rownum = " + rowNum);
mapper.mapRow(resultSet, rowNum++).forEach(multimap::put);
}
return multimap;
})
但是在控制台中没有任何行,这意味着resultSet没有next()
PS
我的SQL
很困难,所以我只写了一个简短的版本。看起来像
private String SQL = "select el1,el2 from mytable where el3 in(";
我尝试使用in(";
和in :ID
和in = :ID
和in (:ID)
和in (?)
以及其他一些我不记得的变体(-:
已编辑
实际上,我不明白为什么会起作用
public QueryDescriptionBySmsId(DataSource dataSource) {
super(dataSource, SQL);
logger.debug("Created QueryStatus");
declareParameter(new SqlParameter("ID", Types.NUMERIC));
compile();
logger.debug("Created QueryStatus");
}
@Override
public Multimap<BigInteger, Status> query(Set<BigInteger> ids) {
Map<String, Set> paramMap = Collections.singletonMap("ID", smsIds);
List l = executeByNamedParam(paramMap); // it returns a lot of elements which I am looking for
}
但这不起作用
@Override
public Multimap<BigInteger, SmsStatus> query(Set<BigInteger> sids) {
Map<String, Set> paramMap = Collections.singletonMap("ID", ids);
return getJdbcTemplate().query(SQL, resultSet -> {
int rowNum = 0;
Multimap<BigInteger, SmsStatus> multimap =
ArrayListMultimap.create();
while (resultSet.next()) {
mapper.mapRow(resultSet, rowNum++).forEach(multimap::put);
}
return multimap;
},paramMap);
}
显示错误
SQL状态[99999];错误代码[17004];无效的列类型
答案 0 :(得分:0)
我已经像那样更改了代码,现在可以使用了,但是我不喜欢这种解决方案
public class QueryDescriptionById extends SqlQuery implements IQueryDescriptionById {
RowMapper<Map<BigInteger, Status>> mapper = new RowMapperDescription();
public QueryDescriptionById(DataSource dataSource) {
super(dataSource, SQL);
}
public Multimap<BigInteger, SmsStatus> query(Set<BigInteger> ids) {
Map<String, Set> paramMap = Collections.singletonMap("ID", ids);
NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(getJdbcTemplate().getDataSource());
return template.query(SQL, paramMap, resultSet -> {
int rowNum = 0;
Multimap<BigInteger, Status> multimap = ArrayListMultimap.create();
while (resultSet.next()) {
mapper.mapRow(resultSet, rowNum++).forEach(multimap::put);
}
return multimap;
});
}
.........
.........
.........
}