【问题标题】:How can I delete all values that have a specific column and row number?如何删除具有特定列号和行号的所有值?
【发布时间】:2020-11-07 08:38:55
【问题描述】:

这段代码耗时太长:

List<DataLogg> selectedLogger = dataLoggRepository.findByLoggerId(loggerId.getValue());
for(int i = firstIndex-1; i < lastIndex; i++) {
    try {
        DataLogg dataLogg = selectedLogger.get(i);
        if (dataLogg != null) {
            dataLoggRepository.delete(dataLogg);
        }
    } catch(Exception e1) {}
}

有什么办法可以避免这个for循环,并且仍然删除firstIndex-1lastIndex之间具有loggerId.getValue()列值的所有内容?

来自以下cmets的建议:

List<DataLogg> selectedLogger = dataLoggRepository.findByLoggerId(loggerId.getValue());
List<DataLogg> deleteThese = new ArrayList<DataLogg>();
for(int i = firstIndex-1; i < lastIndex; i++) {
    try {
        DataLogg dataLogg = selectedLogger.get(i);
        deleteThese.add(dataLogg);
    } catch(Exception e1) {}
}
dataLoggRepository.deleteInBatch(deleteThese);

【问题讨论】:

标签: java mysql sql spring-boot jpa


【解决方案1】:

使用java流API

selectedLogger
.stream()
.skip(firstIndex-2)
.limit(lastIndex-firstIndex+1)
.filter(loggerId.getValue()!=null)
.map(()->{dataLoggRepository.delete(dataLogg);});

【讨论】:

  • 这与他已经在另一种语法中所做的相同。为什么应该更快
  • 也许使用 parallelStream() 会更快
  • 没有。因为你会产生很多 Delete 语句。这应该在一个语句中完成
  • 哈哈哈哈,如果loop是ban,filter和deete逻辑应该写在DAO层,在findByLoggerId()方法中。
【解决方案2】:
    @Query(value = "Delete from dataLoggTable where dataLoggTable.id in " +
            "(select id from dataLoggTable offset :firstIndex)", 
            nativeQuery = true)
    @Modifying
    @Transactional
    void delete(int firstIndex);

【讨论】:

  • 谢谢,但有更好的解决方案 :)
【解决方案3】:

只是另一种写法。

List<DataLogg> selectedLogger = dataLoggRepository.findByLoggerId(loggerId.getValue());
List<DataLogg> deleteThese = IntStream.range(firstIndex - 1, lastIndex).mapToObj(i -> selectedLogger.get(i)).collect(Collectors.toList());
dataLoggRepository.deleteInBatch(deleteThese);

【讨论】:

  • 流比简单的for循环快吗?
  • 读起来更流畅,技术上说起来更快。但要小心,我的狙击手可能需要适应一下。
  • 好的。谢谢。我认为流看起来很奇怪,而 C 风格的 for 循环似乎也更容易阅读。
  • 是的,但是流更快并且可以并行化。
  • "DataLogg 无法转换为 int" 我遇到了错误。