簡體   English   中英

JDBCTemplate 可選參數

[英]JDBCTemplate optional parameters

我正在使用 spring JDBCTemplate。


我有一個場景,其中需要傳遞到我的查詢 function 中的參數是有條件的/可選的。 例如,我有以下代碼:

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

在代碼中,我傳入了custId, number, requestType, etc.但是, requestType是一個可選參數,它可能返回為null或為empty ,所以如果它是null ,我不希望它被傳遞到Object[]empty

我能做些什么來處理這種情況?

我可以引入我只將我想要的參數傳遞給Object[]的邏輯,但是,我想知道是否有一個已經內置的功能來處理這個而不是我重新發明輪子。

一種選擇是使用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 添加到 @Snozzlebert 的答案中。

如果要傳遞 null 值,則必須指定參數的類型,否則會出現 NullPointerException。

@Autowired
NamedParameterJdbcTemplate namedJdbcTemplate;



MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("name", name, Types.VARCHAR);
parameters.addValue("phone", null, Types.VARCHAR);
parameters.addValue("age", null, Types.SMALLINT);

List<RealTimeDTO> list = namedJdbcTemplate.query(
        "SELECT foo, bar\n" +
          " FROM FooBar\n" +
         " WHERE (:name IS NULL OR name = :name) AND \n" +
         " (:phone IS NULL OR phone = :phone) AND \n" +
         " (:age IS NULL OR age = :age)" +,
        parameters,
        new RealTimeDTOMapper());

您可以通過檢查條件來使用靜態 SQL ? IS NULL OR name = ? ? IS NULL OR name = ? . 但是您必須傳遞參數兩次並傳遞參數類型( 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 並不比使用條件更好。

要改進現有答案,請保留僅包含綁定參數的 static 查詢。 不要“構建”sql 以避免緩存問題和 sql 注入的陷阱。

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

    String sql = "SELECT foo, bar FROM FooBar" +
                 " WHERE (:name IS NULL OR name = :name)" +
                 " AND (:phone IS NULL OR phone = :phone)" +
                 " AND (:age = 0 OR age = :age)";
    params.put("name", name);
    params.put("phone", phone);
    params.put("age", age);
    return jdbcTemplate.query(sql, params, new CCCRowMapper());
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM