org.springframework.data.jpa.domain.Specification interface
The objective of Specification interface is to let developers make reusable Predicates objects to append into a query when needed.
For example, to create a query of this entity.
@Entity
@Table(name = "Customer")
public class Customer {
@Id
@Column(name = "custId")
private Integer custId;
@Column(name = "companyName", length = 40, nullable = false)
private String companyName;
@Column(name = "contactName", length = 30)
private String contactName;
@Column(name = "contactTitle", length = 30)
private String contactTitle;
@Column(name = "address", length = 60)
private String address;
@Column(name = "city", length = 15)
private String city;
@Column(name = "region", length = 15)
private String region;
@Column(name = "postalCode", length = 10)
private String postalCode;
@Column(name = "country", length = 15)
private String country;
@Column(name = "phone", length = 24)
private String phone;
@Column(name = "mobile", length = 24)
private String mobile;
@Column(name = "email", length = 225)
private String email;
@Column(name = "fax", length = 24)
private String fax;
// ignore getter and setter
}
In order to pass Specification criteria, please add org.springframework.data.jpa.repository.JpaSpecificationExecutor into the Repository interface.
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer>, JpaSpecificationExecutor<Customer> {
}
null Specification
null Specification means no criteria.
customerRepository.findAll((root, query, criteriaBuilder) -> null);
// it is equal to customerRepository.findAll();
To get entities when a field is equal to something
To get entities whose "city" is equal to the value of the String variable "city".
String city;
// ...
Specification<Customer> s = (root, query, criteriaBuilder) -> null;
if (Objects.nonNull(city)) {
s = s.and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("city"), city));
}
customerRepository.findAll(s);
and() This is used for joining two Specification with AND clauses. The other one is or().
Add one more Specification
In addition to "city", "companyName" wants to look up also.
String city;
String companyName;
// ...
Specification<Customer> s = (root, query, criteriaBuilder) -> null;
if (Objects.nonNull(city)) {
s = s.and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("city"), city));
}
if (Objects.nonNull(companyName)) {
s = s.and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("companyName"), companyName));
}
customerRepository.findAll(s);
Code about can work on cases from no query criteria to with "city" and "companyName" criteria.
Other unnormal usage of Specification interface
You may do following
- to JOIN other entity
- to define complex sort if JpaSpecificationExecutor.findAll(Specification , Sort) cannot suit your need
Top comments (0)