Explore spring data JPA in depth, from repository to specifications and querydsl
The data access layer, the so-called crud, is a required course for back-end programmers. Spring data JPA allows us to simplify the crud process. This article goes from simplicity to depth, from the basic usage of JPA to various advanced usage.
Repository
Spring data JPA can be used to simplify the implementation of data access. With the help of JPA, we can quickly implement some simple queries, paging and sorting.
public interface MovieRepository extends JpaRepository<Movie,Long> {
List<Movie> findByTitle(String title,Sort sort);
Page<Movie> findByYear(Int year,Pageable pageable);
}
JPA will name according to the method, and automatically generate SQL through JPA query generator, cool!
Criteria API
However, simplicity is not everything. Sometimes you need to face some complex queries and can't enjoy the convenience brought by JPA query generator. Jpq provides the criteria API and
The criteria API can dynamically build queries programmatically, and strong type checking can avoid errors. The core principle is to construct a predicate
LocalDate today = new LocalDate();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Movie> query = builder.createQuery(Movie.class);
Root<Movie> root = query.from(Movie.class);
Predicate isComedy = builder.equal(root.get(Movie.genre),Genre.Comedy);
Predicate isReallyOld = builder.lessThan(root.get(Movie.createdAt),today.minusYears(25));
query.where(builder.and(isComedy,isReallyOld));
em.createQuery(query.select(root)).getResultList();
Predict can well meet some complex queries, but its problem is that it is not easy to reuse, because you need to build criteriabuilder, criteriaquery and root first At the same time, the code readability is also relatively general.
Specifications
Can you define a reusable predicate? JPA provides a specification interface to solve this problem.
Let's first look at the interface definition:
public interface Specification<T> {
Predicate toPredicate(Root<T> root,CriteriaQuery query,CriteriaBuilder cb);
}
Didn't the above say that you need to build criteriabuilder and root first, so the specification interface provides you with these three parameters to build your own predict and get what you want.