【问题标题】:Hextoraw() not working with IN clause while using NamedParameterJdbcTemplate使用 NamedParameterJdbcTemplate 时,Hextoraw() 不能与 IN 子句一起使用
【发布时间】:2016-08-31 20:54:45
【问题描述】:

我正在尝试使用 RAW(255) 的 id 更新我的 oracle DB 中的某些行。 示例 ID 0BF3957A016E4EBCB68809E6C2EA8B80、1199B9F29F0A46F486C052669854C2F8...

@Autowired
private NamedParameterJdbcTemplate jdbcTempalte;

private static final String UPDATE_SUB_STATUS = "update SUBSCRIPTIONS set status = :status, modified_date = systimestamp where id in (:ids)";


public void saveSubscriptionsStatus(List<String> ids, String status) {

        MapSqlParameterSource paramSource = new MapSqlParameterSource();
        List<String> idsHexToRaw = new ArrayList<>();
        String temp =  new String();
        for (String id : ids) {
            temp = "hextoraw('" + id + "')";
            idsHexToRaw.add(temp);
        }
        paramSource.addValue("ids", idsHexToRaw);
        paramSource.addValue("status", status);
        jdbcTempalte.update(*UPDATE_SUB_STATUS*, paramSource);
    }

上面的代码块正在执行,没有任何错误,但更新不会反映到数据库中,而 如果我跳过使用 hextoraw() 并只传递 id 列表,它可以正常工作并更新数据表。见下面代码

public void saveSubscriptionsStatus(List<String> ids, String status) {

        MapSqlParameterSource paramSource = new MapSqlParameterSource();]
        paramSource.addValue("ids", ids);
        paramSource.addValue("status", status);
        jdbcTempalte.update(UPDATE_SUB_STATUS, paramSource);
    }

这段代码可以正常工作并更新表,但由于我没有使用 hextoraw(),它会扫描整个表以进行更新,因为我已经创建了索引。所以使用 hextoraw() 将使用索引来扫描表,但它不会更新值,这有点奇怪。

【问题讨论】:

  • 下面的更新答案

标签: spring oracle jdbc


【解决方案1】:

通过尝试所有不同的组合自己得到了解决方案:

@Autowired
private NamedParameterJdbcTemplate jdbcTempalte;

public void saveSubscriptionsStatus(List<String> ids, String status) {

    String UPDATE_SUB_STATUS = "update SUBSCRIPTIONS set status = :status, modified_date = systimestamp where id in (";
    MapSqlParameterSource paramSource = new MapSqlParameterSource();
    String subQuery = "";
    for (int i = 0; i < ids.size(); i++) {
        String temp = "id" + i;
        paramSource.addValue(temp, ids.get(i));
        subQuery = subQuery + "hextoraw(:" + temp + "), ";
    }
    subQuery = subQuery.substring(0, subQuery.length() - 2);
    UPDATE_SUB_STATUS = UPDATE_SUB_STATUS + subQuery + ")";
    paramSource.addValue("status", status);
    jdbcTempalte.update(UPDATE_SUB_STATUS, paramSource);
}

这样做是创建一个查询,其中所有 ids 到 hextoraw 为 id0、id1、id2...... 并且还在 MapSqlParameterSource 实例中添加了这些值,然后这工作正常,它还使用索引进行更新我的桌子。

  1. 运行我的新函数后,查询看起来像:update 订阅设置状态 = :status, modified_date = systimestamp 其中 id 在 (hextoraw(:id0), hextoraw(:id1), hextoraw(:id2)...)
  2. MapSqlParameterSource 实例如下所示:{("id0", "randomUUID"), ("id1", "randomUUID"), ("id2", "randomUUID").....}

【讨论】:

    【解决方案2】:

    不进行字符串操作,而是将列表转换为 ByteArray 列表

    List<byte[]> productGuidByteList = stringList.stream().map(item -> GuidHelper.asBytes(item)).collect(Collectors.toList());
    parameters.addValue("productGuidSearch", productGuidByteList);
    
    public static byte[] asBytes(UUID uuid) {
        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());
        return bb.array();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-29
      • 1970-01-01
      • 1970-01-01
      • 2019-09-05
      • 2010-09-07
      • 2020-05-06
      • 2012-12-01
      • 2022-12-31
      相关资源
      最近更新 更多