spring jdbctemplate - 如何将list(包含多个参数)绑定到查询args中

时间:2017-06-16 13:04:03

标签: spring jdbctemplate

我想知道如何将对象列表绑定到带有多个参数的sql中,其中'子句。

Select * from order where order_id = ? and action_code = ?

数据就像

List<Order> orderList = new ArrayList<>();
orderList.add(1,"KP");
orderList.add(2,"DP");
orderList.add(3,"KP");

这是我尝试过的 我有一份订单清单。每个订单都有订单ID(长)和操作代码(字符串)。现在我需要查询带有order id和action代码的db作为where子句中的参数。

从订单中选择* order_id =?和action_code =?。

我试图在args中传递一个对象数组。 [这个工作]。

Object[] args = new Object[ size of orderList ]
int i = 0
for (Order order : orderList)
{
   args[i] = new Object[]{order.getOrderId(), order.getActionCode()};
   i++;
}

我正在触发查询,如下所示

jdbcTemplate.query(sql, args, rowMapper);

当我运行应用程序时,我得到以下错误。

org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [SELECT * where ORD_I = ? AND ACT_C = ?]; SQL state [99999]; error code [17004]; Invalid column type; nested exception is java.sql.SQLException: Invalid column type

但是,如果我按照以下方式传递数据

jdbcTemplate.query(sql, new Object[] {orderList.get(0).getOrderId, orderList.get(0).getActionCode()}, rowMapper);

到目前为止我尝试了什么 我提供的类型如下[在DB中,order_id是数字(38),action_code是Char(2))

int[] types = new int[] { java.sql.Types.NUMERIC, java.sql.Types.CHAR 
};
jdbcTemplate.query(sql, args, types, rowMapper);

我有一个例外说。 [当我用java.sql.Types.VARCHAR替换java.sql.Types.CHAR时出现相同的错误]

org.springframework.dao.InvalidDataAccessApiUsageException: args and argTypes parameters must match

以下设置工作

 int[] types = new int[] { java.sql.Types.NUMERIC, java.sql.Types.CHAR 
    };
jdbcTemplate.query(sql, new Object[] {orderList.get(0).getOrderId, orderList.get(0).getActionCode()}, types, rowMapper);

我已经提到了以下问题 How set Array/List in Spring jdbcTemplate as parameter? - 讨论从列表中传递一个参数

how to bind a list of tuples using Spring JDBCTemplate? - 谈论元组。如果我必须使用tableA.id = tableB.id和tableA.id =?查询2个表和tableB.seq_id = ?,然后上面的解决方案无效。

我搜索了很多,但现在我已经遇到了障碍。请帮助。

1 个答案:

答案 0 :(得分:0)

我知道此解决方案不适用于列表,但我建议使用NamedParameterJdbcTemplates而不是常规的jdbcTemplate。它更直接,也是一个相对微小的变化:

SQL:

Select * from order where order_id = :orderId and action_code = :actionCode

orderID actionCode 对应参数HashMap中的String键值(如下所示)。

爪哇:

Map<String, Object> parameters = new HashMap<>();
parameters.put("orderID","KP");
parameters.put("actionCode","DP");

namedParameterJdbcTemplate.execute(sqlQueryString, parameters);

使用字符串键将所有参数加载到键值映射中。

编辑以回答评论:

为什么不在循环中执行查询,并将结果保存到地图?我正在考虑使用伪代码:

for (set in parameterSet){
parameters.put(set1, set2); 
ResultSet rs = jdbcTemplate.execute(queryString, parameters); 
otherMap.put(set1 + set2, rs);}

此处setorderIDactionCode参数的组合,parameterSetsorderIDactionCode的所有组合(集合)你想要查询,otherMap是你创建的一些地图集合,用于将数据保存在for循环之外,使用第一和第二组参数的连接作为键,结果集作为值。 / p>

修改后续评论

如果您有1000个唯一对,那么这意味着每个唯一的参数对应返回不同的,互斥的ResultSet。例如,在WHERE条件中输入参数A和B应返回与参数A和C中的参数不同的ResultSet。我没有看到围绕此参数的快捷方式。你基本上要问1000个不同的问题,每个问题都有不同的答案。确保获得所有ResultSet并仅执行一个查询的唯一方法是为第一个参数和第二个参数提供所有可能的值:

WHERE parameter1 IN (... all possible values for parameter1) AND
parameter2 IN (... all possible values for parameter2)

然而,这会产生比你想要的更多的行。然后,您必须以编程方式应用自己的逻辑来过滤掉不属于该组唯一参数组合的结果集。