NamedParameterJdbcTemplate和复合键

时间:2013-11-20 17:57:56

标签: java spring-data jdbctemplate named-parameters

我编写了一个方法来检索NamedParameterJdbcTemplate的条目列表:

public final Map<K,V> findAll(final Collection<K> keys) {
    if (keys == null) {
        return null;
    }
    MapSqlParameterSource parameters = new MapSqlParameterSource();
    parameters.addValue("ids", keys);
    List<V> values = new NamedParameterJdbcTemplate(datasource).query("select * from TABLE where id in ( :ids )", parameters, mapper);          

    Map<K,V> results = new HashMap<K, V>();
    for (V v : values) {
        results.put((K) v.getId(), v);              
    }        
    return results;
}

但仅当密钥是简单类型时才有效。 我无法使用主键,如:

public class CompositeKey implements Serializable {

    private long field1;
    private long field2;
}

如何使用复合键创建findAll()方法?

2 个答案:

答案 0 :(得分:4)

您的问题应该部分回答:

  • 如何使用SELECT和元组比较
  • 来编写IN
  • 如何使用SELECT
  • 撰写此类NamedParameterJdbcTemplate

如何使用compund PK

查询多个对象

PostgreSQL / MySQL(也可能是Oracle):

 SELECT * FROM foo WHERE (field1, field2) IN ((1, 1), (1, 3));

SQL Server(有点黑客;也适用于PostgreSQL):

SELECT * FROM foo 
INNER JOIN (VALUES (1, 1), (1, 3)) AS _CONDITION(field1, field2) ON
        foo.field1 = _CONDITION.field1 AND foo.field2 = _CONDITION.field2;

如何使用NamedParameterJdbcTemplate

进行查询

使用List<Object[]>作为参数类型。有关此主题的信息,请参阅JavaDoc for NamedParameterUtilsofficial documentation

使用地图参数的示例

public List<MyObject> findByIds(Collection<MyKey> keys) {
    List<Object[]> keyTuples = new ArrayList<Object[]>(keys.size());
    for (MyKey key : keys) {
        keyTuples.add(new Object[] { key.getField1(), key.getField2() });
    }
    jdbcTemplate.query("SELECT * FROM my_table WHERE (field1, field2) IN (:keys)", 
            Collections.singletonMap("keys", keyTuples), new MyObjectRowMapper());
}

答案 1 :(得分:0)

我不得不使用一种我并不完全满意的解决方法,但它有效。 我不得不手动翻译列表数组对象中的bean列表,然后将数组对象列表传递给NamedParameterJdbcTemplate。

如果有人有更优雅的解决方案,请与我分享。

最终的findAll方法实现

    public final Map<K,V> findAll(final Collection<K> keys) throws DaoMethodNotSupportedException {

    List<Object[]> keyObjsList = new ArrayList<Object[]>();
    ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(":field1 :field2");
    for (K key : keys) {
        SqlParameterSource paramSource = new BeanPropertySqlParameterSource(key);
        Object[] keyParams = NamedParameterUtils.buildValueArray(parsedSql, paramSource, null);
        keyObjsList.add(keyParams);
    }

    MapSqlParameterSource parameters = new MapSqlParameterSource();
    parameters.addValue("primaryKeys", keyObjsList);

    List<V> values = new NamedParameterJdbcTemplate(datasource).query("select * from TABLE where (field1, field2) in ( :primaryKeys )", parameters, valueMapper);          

    for (V v : values) {
        results.put((K) v.getPrimaryKey(), v);
    }        
    return results;
}

感谢所有人