NamedParameterJdbcTemplate.batchUpdate()采用Map <String,Object>的数组,如何实例化参数数组,以免收到警告?

时间:2019-08-22 13:13:43

标签: java arrays spring-batch

NamedParameterJdbcTemplate.batchUpdate()使用Map<String,Object>[]作为参数列表。我无法弄清楚如何以不带有“泛型实例化”错误或“未经检查的分配”警告的标记方式来实例化数组。我真的希望Spring接受Maps列表而不是数组。

是的,我读过:How does one instantiate an array of maps in Java?

但是,我无法控制spring-batch的NamedParameterJdbcTemplate接口,因此无法更改batchUpdate()方法的签名。

我有一个名为List<Map<String,Object>>的params。

我尝试了以下方法:

namedParameterJdbcTemplate.batchUpdate(
    sql,
    params.toArray(new Map<String,Object[0]) //generic instantiation error
); 

namedParameterJdbcTemplate.batchUpdate(
    sql,
    params.toArray(new Map[0]) //unchecked assignment warning
); 

完整代码:

class MyItemWriter implements ItemWriter<MyRecord> {
   @Autowired
   private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

   public void write(List<? extends MyRecord> items) {
      String sql = MyRecord.UPDATE_SQL;
      List<Map<String,Object>> params 
      = items.stream()
             .map(record->new MapBuilder<String,Object>()
                   .put("param1",record.getField1())
                   .put("param2",record.getField2())
                   .build())
             .collect(Collectors.toList());
      namedParameterJdbcTemplate.batchUpdate(
          sql,
          params.toArray(new Map<String,Object>[0]) //generic instantiation error
      );
      namedParameterJdbcTemplate.batchUpdate(
          sql,
          params.toArray(new Map[0]) //unchecked assignment warning.
      );
   }
}

2 个答案:

答案 0 :(得分:0)

地图是一个界面。您无法创建接口实例。但是,您可以创建实现该接口的类的实例。您可以检查JavaDoc来找到一些实现:

https://docs.oracle.com/javase/8/docs/api/java/util/Map.html https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Map.html

答案 1 :(得分:0)

在Java中,您无法创建Map<String, Object>的数组。

REF:https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createArrays

因此,您创建一个Map[],然后使用“ unchecked cast”警告将其强制转换为Map<String, Object>[]。这样的警告是可以抑制的。 JDK示例:https://github.com/AdoptOpenJDK/openjdk-jdk14/blob/master/src/java.base/share/classes/java/util/Map.java#L1682:L1689

  namedParameterJdbcTemplate.batchUpdate(sql, toArray(params));


@SuppressWarnings("unchecked")
private static Map<String, ?>[] toArray(List<Map<String, ?>> params) {
    return params.toArray(new Map[0]);
}

注意:在您的“完整代码”示例中,无需收集到中间列表。您可以直接将流分配给数组。不幸的是,Stream的toArray()的无参数版本仍然不是通用的。因此,再次,您必须使用带有不可避免但可抑制的警告的重载toArray(n->new Map[n])版本:

  Map<String,?>[] params = items.stream()
      .map(record -> Map.of(
          "param1",record.getField1(),
          "param2",record.getField2()))
      .toArray(this::newArray);


  @SuppressWarnings("unchecked")
  private Map<String,?>[] newArray(int n) {
    return new Map[n];
  }