JDBCTemplate 可选参数

Posted

技术标签:

【中文标题】JDBCTemplate 可选参数【英文标题】:JDBCTemplate optional parameters 【发布时间】:2018-07-03 17:55:27 【问题描述】:

我正在使用spring JDBCTemplate。


我有一个场景,需要传递给我的查询函数的参数是有条件的/可选的。例如,我有以下代码:

List<RealTimeDTO> result = jdbcTemplate.query(sql, new Object[] custId, 
number, requestType, startDate, endDate, new CCCRowMapper());

在代码中,我传入了custId, number, requestType, etc. 但是,requestType 是一个可选参数,可能会以nullempty 的形式返回,所以我不希望它传入Object[] if它是nullempty

我能做些什么来处理这种情况?

我可以引入逻辑,我只将我想要的参数传递给Object[],但是,我想知道是否有一个已经内置的功能可以处理这个而不是我重新发明***。

【问题讨论】:

“我该如何处理这种情况?” if声明!! @Andreas 是的天才,我知道。阅读最后一句话。 不将 null requestType 传递给 Object[] 数组很简单。如何动态删除 where 条件 AND requestType = ? 当我面对动态 sql 时,我创建列表并将参数添加到 if 语句中的列表中,并将列表作为 jdbctemplate 的参数传递。 @Maxim 这正是我正在做的,但结果却太乱了。想知道是否有更清洁的方法。 【参考方案1】:

一种选择是使用NamedParameterJdbcTemplate,这样就不需要修改参数“list”(现在是Map),只需要修改SQL即可:

List<RealTimeDTO> query(String name) 
    NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);

    String sql = "SELECT foo, bar" +
                  " FROM FooBar" +
                 " WHERE name" + (name == null ? " IS NULL" : "= :name");
    Map<String, Object> params = new HashMap<>();
    params.put("name", name);
    return jdbcTemplate.query(sql, params, new CCCRowMapper());

更新

如果您有许多可能需要跳过的条件,并且可能会消除所有条件,则使用StringJoiner 构建WHERE 子句:

List<RealTimeDTO> query(String name, String phone, int age) 
    NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);

    StringJoiner where = new StringJoiner(" AND ", " WHERE ", "").setEmptyValue("");
    if (name != null)
        where.add("name = :name");
    if (phone != null)
        where.add("phone = :phone");
    if (age != 0)
        where.add("age = :age");
    String sql = "SELECT foo, bar" +
                  " FROM FooBar" +
                  where;
    Map<String, Object> params = new HashMap<>();
    params.put("name", name);
    params.put("phone", phone);
    params.put("age", age);
    return jdbcTemplate.query(sql, params, new CCCRowMapper());

【讨论】:

嗯,我明白了,我之前使用过 NamedParameter 但不适用于这种情况。 K 将尝试此操作并报告。 @Robin 当您将 name 传递为 null 时,您是要检查“name is null”还是不想按名称过滤?你的要求是什么?因此,在上面的示例中,对于后一种情况,查询应该没有 where 条件。 @gagansingh 正确,如果名称为空,则不应对名称进行任何过滤。 'name' 的 where 语句不应该发生 那么这个答案将不起作用。如果您坚持使用 jdbc 模板,则必须动态生成 sql。如果你切换到 jpa 或 hibernate 之类的东西,你可以使用适合这种用例的条件查询。 @gagansingh 你是什么意思“这个答案不起作用”?当然可以,您只需更改 SQL 以排除您不想要的条件,就像现在动态更改 name 条件一样。【参考方案2】:

您可以通过检查? IS NULL OR name = ? 之类的条件来使用静态SQL。但是您必须两次传递参数并传递参数类型 (at.sql.Types) 两次。

String sql = "SELECT foo, bar" +
              " FROM FooBar" +
             " WHERE (? IS NULL OR name = ?) ";
jdbcTemplate.query(sql, new Object[]name, name, new int[]Types.VARCHAR, Types.VARCHAR, new CCCRowMapper());

IMO 并不比使用条件更好。

【讨论】:

某些类型的数据有错误(而不是 varchar(name)) 什么意思? “某种类型的数据”有什么错误? 这不会给出正确的结果,如果参数在 db 中有 null 但您检查值仍然选择了该行。选择的答案只会给出正确的结果。

以上是关于JDBCTemplate 可选参数的主要内容,如果未能解决你的问题,请参考以下文章

Spring--JdbcTemplate

Spring框架JDBC Template使用教程

sqlserver的查询语句和插入更新语句怎么用

jdbcTemplate:包含占位符的SQL无法打印参数信息

JdbcTemplate 批量向多条语句发送参数

如何使用 spring 的 jdbcTemplate 在 SQL 查询中指定参数