Java NamedParameterJdbcTemplate和复合键

Java NamedParameterJdbcTemplate和复合键,java,spring-data,jdbctemplate,named-parameters,Java,Spring Data,Jdbctemplate,Named Parameters,我编写了一个方法来检索名为ParameterJDBCTemplate的条目列表: public final Map<K,V> findAll(final Collection<K> keys) { if (keys == null) { return null; } MapSqlParameterSource parameters = new MapSqlParameterSource(); parameters.addVa

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

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;
}

如何使用复合键使findAll()方法工作?

您的问题应该分部分回答:

  • 如何在和元组比较中组合
    ,编写
    选择
  • 如何编写这样的
    使用
    NamedParameterJdbcTemplate选择
如何使用compund PK查询多个对象 PostgreSQL/MySQL(可能还有Oracle):

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

如何使用NamedParameterJdbcTemplate进行查询 使用
List
作为参数类型。有关此主题,请参阅或

使用贴图参数的示例
公共列表findByIds(集合键){
List keyTuples=newarraylist(keys.size());
用于(MyKey:keys){
添加(新对象[]{key.getField1(),key.getField2()});
}
jdbcTemplate.query(“从(:keys)中的(field1,field2)my_表中选择*”,
singletonMap(“key”,keyTuples),新的MyObjectRowMapper();
}

我不得不使用一种我并不完全满意的变通方法,但它确实有效。 我必须手动转换列表数组对象中的bean列表,然后将数组对象列表传递给NamedParameterJdbcTemplate

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

findAll方法的最终实现
公共最终映射findAll(最终集合键)抛出DaoMethodNotSupportedException{
List keyObjsList=新建ArrayList();
ParsedSql ParsedSql=NamedParameterUtils.parseSqlStatement(“:field1:field2”);
用于(K键:键){
SqlParameterSource paramSource=新BeanPropertySqlParameterSource(键);
Object[]keyParams=NamedParameterUtils.buildValueArray(parsedSql,paramSource,null);
keyObjsList.add(keyParams);
}
MapSqlParameterSource参数=新的MapSqlParameterSource();
parameters.addValue(“primaryKeys”,keyObjsList);
List values=new NamedParameterJdbcTemplate(数据源)。查询(“从(:primaryKeys)中的(field1,field2)表中选择*”,参数,valueMapper);
对于(V:值){
结果.put((K)v.getPrimaryKey(),v);
}        
返回结果;
}

感谢大家

您没有问任何问题。这不是关于Java或Spring JDBC的问题。这是关于一般SQL语法和元组比较的。请更新您的问题并包括您正在使用的数据库的类型。另一方面,您在使用
NamedParameterJdbcTemplate
构造查询时会遇到问题。。。因此,问题的两个方面都是有效的。但是您需要知道要构造的SQL查询应该是什么样子的。我的问题不是SQL。指令
:ids
仅对NamedParameterJdbcTemplate有效,我想知道如何处理复合主键。这与SQL无关。@pavel coral谢谢。这肯定是正确的答案,无论如何,我无法清楚地理解如何用代码翻译您的解释。我在(:field1,:field2)
中定义了一个sql字符串,如
select*from TABLE where(field1,field2)
,然后如果我执行方法
BeanPropertySqlParameterSource parameters=new BeanPropertySqlParameterSource(key);字符串sql=NamedParameterUtils.substituteNamedParameters(sql,参数)我从(?,)中(field1,field2)的表中得到了sql
select*。现在我一直在翻译复合键的集合
Collecion key
@patrizio.munzi我添加了使用单个map参数的简单示例。你自己的答案有点复杂。如果您真的想使用反射,那么使用Spring的
BeanWrapperImpl
。但我建议使用接口(例如,在某些
CompoundKey
接口上实现
Object[]getTuples()
方法)或公共实体/键超类,而不是使用泛型方法/类型。
public class CompositeKey implements Serializable {

    private long field1;
    private long field2;
}
 SELECT * FROM foo WHERE (field1, field2) IN ((1, 1), (1, 3));
SELECT * FROM foo 
INNER JOIN (VALUES (1, 1), (1, 3)) AS _CONDITION(field1, field2) ON
        foo.field1 = _CONDITION.field1 AND foo.field2 = _CONDITION.field2;
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());
}
    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;
}