JPQL 中的 LIMIT 子句替代项是什么?

What is the LIMIT clause alternative in JPQL?

我正在使用 JPQL 中实现的 PostgreSQL 查询。

这是一个工作正常的示例本机 psql 查询,

SELECT * FROM students ORDER BY id DESC LIMIT 1;

JPQL 中的相同查询不起作用,

@Query("SELECT s FROM Students s ORDER BY s.id DESC LIMIT 1")

Students getLastStudentDetails();

似乎 LIMIT 子句在 JPQL 中不起作用。

根据 JPA 文档我们可以使用 setMaxResults/setFirstResult,谁能告诉我如何在上述查询中使用它?

如评论中所述,JPQL 不支持 LIMIT 关键字。

您可以使用 setMaxResults 实现,但如果您只需要一个项目,则使用 getSingleResult - 如果找不到任何项目,它会抛出异常。

因此,您的查询类似于:

TypedQuery<Student> query = entityManager.createQuery("SELECT s FROM Students s ORDER BY s.id DESC", Student.class);    
query.setMaxResults(1);

如果要设置特定的起始偏移量,请使用query.setFirstResult(initPosition);太

您使用的 JPQL 不支持像这样限制结果。使用本机 JPQL 时,您应该使用 setMaxResults 来限制结果。

但是您使用的是 Spring Data JPA,这基本上使它变得非常容易。请参阅参考指南中的 here,了解如何根据查询限制结果。在您的情况下,find 方法将完全满足您的要求。

findFirstByOrderById();

您还可以在查询中使用 Pageable 参数而不是 LIMIT 子句。

@Query("SELECT s FROM Students s ORDER BY s.id DESC")
List<Students> getLastStudentDetails(Pageable pageable);

然后在您的调用代码中执行类似的操作(如参考指南中 here 所述)。

getLastStudentDetails(PageRequest.of(0,1));

两者应该产生相同的结果,无需求助于普通 SQL。

你可以这样使用:

 @Repository
 public interface ICustomerMasterRepository extends CrudRepository<CustomerMaster, String> 
 {
    @Query(value = "SELECT max(c.customer_id) FROM CustomerMaster c ")
    public String getMaxId();
 }

你好,在 jpql 中获取单行并使用 LIMIT 我们可以告诉 jpql 它是否是本机查询。

(使用 - nativeQuery=true)

下面是使用

@Query("SELECT s FROM Students s ORDER BY s.id DESC LIMIT 1", nativeQuery=true)
Students getLastStudentDetails();

硬编码分页(new PageRequest(0, 1))以实现只获取一条记录。

    @QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value = "true") })
    @Query("select * from a_table order by a_table_column desc")
    List<String> getStringValue(Pageable pageable);

您必须通过 new PageRequest(0, 1) 来获取记录,并且 从列表中获取第一条记录。

JPQL 不允许将 limit 关键字添加到 HQL 生成的查询中。你会得到以下异常。

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: LIMIT near line 1

但是不用担心,可以通过以下步骤在 HQL 生成的查询中使用 limit 关键字。

Sort.by(sortBy).descending() // fetch the records in descending order

pageSize = 1 // fetch the first record from the descending order result set.

参考以下服务class

服务:

@Autowired
StudentRepository repository; 

public List<Student> getLastStudentDetails(Integer pageNo, Integer pageSize, String sortBy)
{
    Integer pageNo = 0;
    Integer pageSize = 1;
    String sortBy = "id";
    Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by(sortBy).descending());

    Slice<Student> pagedResult = repository.findLastStudent(paging);

    return pagedResult.getContent();
}

您的存储库接口应实现 PagingAndSortingRepository

存储库:

public interface StudentRepository extends JpaRepository<Student,Long>, PagingAndSortingRepository<Student,Long>{

    @Query("select student from Student student")
    Slice<Student> findLastStudent(Pageable paging);
}

这会将 limit 关键字添加到您可以在控制台中看到的查询中。希望这有帮助。

您不能在 HQL 中使用 Limit,因为 Limit 依赖于数据库供应商,因此 Hibernate 不允许通过 HQL 查询。

您可以实现的一种方法是使用子查询:

@Query("FROM Students st WHERE st.id = (SELECT max(s.id) FROM Students s)")
Students getLastStudentDetails();

这里是十大服务(这是一个有用的例子)

存储库
(在查询中,我通过构造函数将分数实体解析为 ScoreTo(DTO class))

@Repository
public interface ScoreRepository extends JpaRepository<Scores, UUID> {     
  @Query("SELECT new com.example.parameters.model.to.ScoreTo(u.scoreId , u.level, u.userEmail, u.scoreLearningPoints, u.scoreExperiencePoints, u.scoreCommunityPoints, u.scoreTeamworkPoints, u.scoreCommunicationPoints, u.scoreTotalPoints) FROM Scores u "+
            "order by u.scoreTotalPoints desc")
    List<ScoreTo> findTopScore(Pageable pageable);
}

服务

@Service
public class ScoreService {
    @Autowired
    private ScoreRepository scoreRepository;    
  
    public List<ScoreTo> getTopScores(){
        return scoreRepository.findTopScore(PageRequest.of(0,10));
    }
}

正确的方法是这样写你的JPA接口方法

public interface MyRepository extends PagingAndSortingRepository<EntityClass, KeyClass> {

List<EntityClass> findTop100ByOrderByLastModifiedDesc();
}

在方法名称中,“100”表示您想要的行数,否则您将在 limit 子句中放入这些行。 “LastModified”也是您要作为排序依据的列。

PagingAndSortingRepository 或 CrudRepository,两者都适用。

为了完整起见,OP的接口方法是

List<Students> findTop1ByIdDesc();