【问题标题】:Using Spring DAO's NamedParameterJDBCTemplate, how can I code for multi column IN statement?使用 Spring DAO 的 NamedParameterJDBCTemplate,如何为多列 IN 语句编写代码?
【发布时间】:2015-07-29 10:26:18
【问题描述】:

NamedParameterJDBTemplate 如何用于检索如下 sql 查询?

SELECT * FROM TABLE_1 
WHERE
    (COLUMN_1, COLUMN2) IN
    ((Val1, val2), (Val3, Val4));

单列 IN 语句在 Spring DAO 中易于编码;但一直没能找到多列 IN 的解决方案。

【问题讨论】:

    标签: sql spring jdbctemplate multiple-columns


    【解决方案1】:

    通过这种方式添加参数,可以在IN中添加多个值:

    NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
    MapSqlParameterSource parameters = new MapSqlParameterSource();
    parameters.addValue("column1", Arrays.asList("Val1", "val2"));
    parameters.addValue("column2", Arrays.asList("Val3", "Val4"));
    namedParameterJdbcTemplate.query("select * from TABLE_1 where (COLUMN_1, COLUMN2) in (:column1,:column2)",parameters,new Mapper());
    

    也看看这个tuts

    【讨论】:

      【解决方案2】:

      Akash Rajbanshi 的答案是错误的,因为它会创建类似的查询

      select * from TABLE_1 where (COLUMN_1, COLUMN2) in ("Val1","val2"), ("Val3", "Val4")
      but we need 
      select * from TABLE_1 where (COLUMN_1, COLUMN2) in ("Val1","Val3"), ("val2", "Val4")
      

      另外,如果我们想要超过 2 个参数,它会失败并抛出异常

      错误:行表达式中的条目数不相等。它试图使 ((?, ?, ?), (?, ?, ?))

      所以我用我自己的实现来解决声明中的 2 列。它生成一对参数并附加到StringBuilder 构造,如((?,?),(?,?),...,(?,?))

      public static <K, V> Pair<StringBuilder, Object[]> makeInQuery(StringBuilder sqlBuilder , Collection<Pair<K, V>> pairs) {
      sqlBuilder.append("(");
      Object[] params = new Object[pairs.size() * 2];
      int i = 0;
      for (Pair<K, V> pair : pairs) {
          if (i > 0) {
              sqlBuilder.append(",");
          }
      
          sqlBuilder.append("(?,?)");
          params[i] = pair.getFirst();
          params[i + 1] = pair.getSecond();
          i = i + 2;
      }
      sqlBuilder.append(")");
      
      return new Pair<>(sqlBuilder, params);
      }
      

      比我们使用jdbcTemplate

      public ReturnSomething findByNodes(Collection<Pair<UUID,UUID>> fromToPairs) {
          StringBuilder sqlBuilder = new StringBuilder(BEFORE_IN_STATEMENT);
          Pair<StringBuilder, Object[]> sqlParamsPair = makeInQuery(sqlBuilder, fromToPairs);
          return jdbcTemplate.query(sqlParamsPair.getFirst().toString(), sqlParamsPair.getSecond(), entityMapper);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多