java—SpringJPA中的属性应该有什么限制?sql语句

ie3xauqp  于 2021-06-27  发布在  Java
关注(0)|答案(2)|浏览(370)

我试着限制自己 nativeQuery = true 但是springjpa找不到这个查询。
我的错误是:

Caused by: java.lang.IllegalStateException: Using named parameters for method public abstract void se.danielmartensson.repositories.DataRepository.deleteByJobNameOrderByDateTimeLimit(java.lang.String,long,long) but parameter 'Optional[jobName]' not found in annotated query 'DELETE FROM Data data ORDER BY data.dateTime WHERE data.jobName =: jobName LIMIT firstIndex = :firstIndex, selectedSamples = :selectedSamples'!

所以我猜 LIMIT 应该有不同的属性,而不是 firstIndex 以及 selectedSamples ? 那会是什么呢?
我的问题从哪里来 Repository Spring Boot

@Query(value = "SELECT * FROM Data data ORDER BY data.dateTime WHERE data.jobName = :jobName LIMIT firstIndex = :firstIndex, selectedSamples = :selectedSamples", nativeQuery = true)
List<Data> findByJobNameOrderByDateTimeLimit(@Param("jobName") String jobName, @Param("firstIndex") long firstIndex, @Param("selectedSamples") long selectedSamples);

@Modifying
@Query(value = "DELETE FROM Data data ORDER BY data.dateTime WHERE data.jobName =: jobName LIMIT firstIndex = :firstIndex, selectedSamples = :selectedSamples", nativeQuery = true)
void deleteByJobNameOrderByDateTimeLimit(@Param("jobName") String jobName, @Param("firstIndex") long firstIndex, @Param("selectedSamples") long selectedSamples);
4ioopgfo

4ioopgfo1#

如果你只是想知道 jobName 以及 firstIndex 以及 selectedSamples 匹配参数。您应该使用正确的sql语法并将它们放入 where .

SELECT * FROM Data data
WHERE data.jobName = :jobName AND firstIndex = :firstIndex AND selectedSamples = :selectedSamples
ORDER BY data.dateTime

正确的语法如下:

select *
from [table]
where 'condiction'
order by [column]
limit [int]
``` `LIMIT` 但是,用于设置sql返回的最大元组数,例如,如果查询返回10k行,但您只想查看前5行,则可以使用 `limit 5` 告诉sql只返回前5个fetch。
另外,在不同的dbms中,可能需要使用不同的语法或方法来实现相同的事情,比如在oracle中,我们没有得到任何结果 `limit` 相反,我们得到了 `FETCH` 或者只是使用 `ROWNUM` .
vngu2lb8

vngu2lb82#

我创建了一个使用 H2 . 你必须改变 limit 以及 offset 您正在使用的数据库的一部分。对于delete操作,有 delete from table where id in (select id from table where .. order by .. limit .. offset ..) 已定义。
注: Lombok 用于 getter , setter 以及 toString . 它不是必需的。
数据存储库.java

public interface DataRepository extends JpaRepository<Data, Integer> {
    @Query(value = "SELECT * FROM Data data WHERE data.jobName = :jobName ORDER BY data.dateTime limit :selectedSamples offset :firstIndex"
            , nativeQuery = true)
    List<Data>findByJobNameOrderByDateTimeLimit(@Param("jobName") String jobName, @Param("firstIndex") Integer firstIndex, @Param("selectedSamples") Integer selectedSamples);

    @Transactional
    @Modifying
    @Query(value = "DELETE FROM Data data WHERE data.id in (select id from Data d where d.jobName = :jobName order by d.dateTime limit :selectedSamples offset :firstIndex)"
            , nativeQuery = true)
    void deleteByJobNameOrderByDateTime(@Param("jobName") String jobName, @Param("firstIndex") Integer firstIndex, @Param("selectedSamples") Integer selectedSamples);
}

数据.java

@lombok.Data
@Entity
@Table
public class Data {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "jobName")
    private String jobName;

    @Column(name = "dateTime")
    private LocalDateTime dateTime;

    public Data() {
    }

    public Data(String jobName, LocalDateTime dateTime) {
        this.jobName = jobName;
        this.dateTime = dateTime;
    }
}

试验

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDateTime;
import java.util.List;

@SpringBootTest
class DemoApplicationTests {
    @Autowired
    private DataRepository dataRepository;

    @Test
    void test1() {
        // insert dummy records
        dataRepository.save(new Data("job1", LocalDateTime.now().minusMinutes(1)));
        dataRepository.save(new Data("job1", LocalDateTime.now().minusMinutes(2)));
        dataRepository.save(new Data("job1", LocalDateTime.now().minusMinutes(3)));
        dataRepository.save(new Data("job1", LocalDateTime.now().minusMinutes(4)));

        // get records
        List<Data> dataList = dataRepository.findByJobNameOrderByDateTimeLimit("job1", 0, 4);
        for (Data data : dataList) {
            System.out.println(data);
        }

        // delete
        dataRepository.deleteByJobNameOrderByDateTime("job1", 1, 2);

        // get records
        dataList = dataRepository.findByJobNameOrderByDateTimeLimit("job1", 0, 4);
        for (Data data : dataList) {
            System.out.println(data);
        }
    }
}

输出

Hibernate: SELECT * FROM Data data WHERE data.jobName = ? ORDER BY data.dateTime limit ? offset ?

Data(id=4, jobName=job1, dateTime=2021-01-08T05:25:31.830)
Data(id=3, jobName=job1, dateTime=2021-01-08T05:26:31.829)
Data(id=2, jobName=job1, dateTime=2021-01-08T05:27:31.827)
Data(id=1, jobName=job1, dateTime=2021-01-08T05:28:31.756)

Hibernate: DELETE FROM Data data WHERE data.id in (select id from Data d where d.jobName = ? order by d.dateTime limit ? offset ?)

Hibernate: SELECT * FROM Data data WHERE data.jobName = ? ORDER BY data.dateTime limit ? offset ?

Data(id=4, jobName=job1, dateTime=2021-01-08T05:25:31.830)
Data(id=1, jobName=job1, dateTime=2021-01-08T05:28:31.756)

mysql数据库

为了 mysql 删除操作成功,脚本如下。
参考:mysql delete from with subquery as condition-answer

@Transactional
    @Modifying
    @Query(value = "DELETE FROM Data WHERE id in (select id from (select id from Data where jobName = :jobName order by dateTime limit :selectedSamples offset :firstIndex) x)"
            , nativeQuery = true)
    void deleteByJobNameOrderByDateTime(@Param("jobName") String jobName, @Param("firstIndex") Integer firstIndex, @Param("selectedSamples") Integer selectedSamples);

相关问题