What is the LIMIT clause alternative in JPQL?

前端 未结 7 672
不思量自难忘°
不思量自难忘° 2020-12-13 03:26

I\'m working with PostgreSQL query implementing in JPQL.

This is a sample native psql query which works fine,

SELECT * FROM students ORDER BY id DESC         


        
相关标签:
7条回答
  • 2020-12-13 03:56

    You can not use Limit in HQL because Limit is database vendor dependent so Hibernate doesn't allow it through HQL query.

    A way you can implement is using a subquery:

    @Query("FROM Students st WHERE st.id = (SELECT max(s.id) FROM Students s)")
    Students getLastStudentDetails();
    
    0 讨论(0)
  • 2020-12-13 03:56

    JPQL does not allow to add the limit keyword to the query generated by the HQL. You would get the following exception.

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

    But don't worry there is an alternative to use the limit keyword in the query generated by the HQL by using the following steps.

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

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

    Refer the following service class

    Service:

    @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();
    }
    

    Your repository interface should implement the PagingAndSortingRepository

    Repository:

    public interface StudentRepository extends JpaRepository<Student,Long>, PagingAndSortingRepository<Student,Long>{
    
        @Query("select student from Student student")
        Slice<Student> findLastStudent(Pageable paging);
    }
    

    This will add the limit keyword to you query which you can see in the console. Hope this helps.

    0 讨论(0)
  • 2020-12-13 03:58

    Hardcode the pagination(new PageRequest(0, 1)) to achieve fetch only one record.

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

    you have to pass new PageRequest(0, 1)to fetch records and from the list fetch the first record.

    0 讨论(0)
  • 2020-12-13 03:59

    You can use something like this:

     @Repository
     public interface ICustomerMasterRepository extends CrudRepository<CustomerMaster, String> 
     {
        @Query(value = "SELECT max(c.customer_id) FROM CustomerMaster c ")
        public String getMaxId();
     }
    
    0 讨论(0)
  • 2020-12-13 04:15

    As stated in the comments, JPQL does not support the LIMIT keyword.

    You can achieve that using the setMaxResults but if what you want is just a single item, then use the getSingleResult - it throws an exception if no item is found.

    So, your query would be something like:

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

    If you want to set a specific start offset, use query.setFirstResult(initPosition); too

    0 讨论(0)
  • 2020-12-13 04:16

    You are using JPQL which doesn't support limiting results like this. When using native JPQL you should use setMaxResults to limit the results.

    However you are using Spring Data JPA which basically makes it pretty easy to do. See here in the reference guide on how to limit results based on a query. In your case the following, find method would do exactly what you want.

    findFirstByOrderById();
    

    You could also use a Pageable argument with your query instead of a LIMIT clause.

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

    Then in your calling code do something like this (as explained here in the reference guide).

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

    Both should yield the same result, without needing to resort to plain SQL.

    0 讨论(0)
提交回复
热议问题