Giter Site home page Giter Site logo

jpa-spec's Introduction

Build Status

jpa-spec

Inspired by Legacy Hibernate Criteria Queries, while this should be considered deprecated vs JPA APIs,

but it still productive and easily understandable.

Features

  • Compatible with JPA 2 interface.
  • Equal/NotEqual/Like/In support multiple values, Equal/NotEqual support Null value.
  • Builder style specification creator.
  • Support pagination and sort builder.

JPA 2 criteria API introduction

JPA 2 introduces a criteria API that can be used to build queries programmatically.

Writing a criteria you actually define the where-clause of a query for a domain class.

Taking another step back these criteria can be regarded as predicate over the entity that is described by the JPA criteria API constraints.

public interface JpaSpecificationExecutor<T> {

	T findOne(Specification<T> spec);

	List<T> findAll(Specification<T> spec);

	Page<T> findAll(Specification<T> spec, Pageable pageable);

	List<T> findAll(Specification<T> spec, Sort sort);

	long count(Specification<T> spec);
}

Gradle

repositories {
    jcenter()
}

dependencies {
    compile 'com.github.wenhao:jpa-spec:2.0.7'
}

Maven

add repository http://jcenter.bintray.com to maven settings.xml file.

<dependency>
    <groupId>com.github.wenhao</groupId>
    <artifactId>jpa-spec</artifactId>
    <version>2.0.7</version>
</dependency>

Specification By Examples:

####Each specification support three parameters:

  1. condition: if true(default), apply this specification.
  2. property: field name.
  3. values: compare value with model, eq/ne/like support multiple values.

####General Example

every Repository class should extends from two super class JpaRepository and JpaSpecificationExecutor.

public interface PersonRepository extends JpaRepository<Person, Long>, JpaSpecificationExecutor<Person> {
}    
public Page<Person> findAll(SearchRequest request) {
    Specification<Person> specification = new Specifications<Person>()
            .eq(StringUtils.isNotBlank(request.getName()), "name", request.getName())
            .gt(Objects.nonNull(request.getAge()), "age", 18)
            .between("birthday", new Range<>(new Date(), new Date()))
            .like("nickName", "%og%", "%me")
            .build();
            
    return personRepository.findAll(specification, new PageRequest(0, 15)); 
}

####Equal/NotEqual Example

find any person nickName equals to "dog" and name equals to "Jack"/"Eric" or null value.

public Persons findAll(SearchRequest request) {
    Specification<Person> specification = new Specifications<Person>()
            .eq("nickName", "dog")
            .eq(StringUtils.isNotBlank(request.getName()), "name", "Jack", "Eric", null)
            .build();
            
    return personRepository.findAll(specification); 
}

####In Example

find any person name in "Jack" or "Eric".

public Persons findAll(SearchRequest request) {
    Specification<Person> specification = new Specifications<Person>()
            .in("name", request.getNames.toArray())// in("name", "Jack", "Eric")
            .build();
            
    return personRepository.findAll(specification); 
}

####Numerical Example

find any people age bigger than 18.

public Persons findAll(SearchRequest request) {
    Specification<Person> specification = new Specifications<Person>()
            .gt(Objects.nonNull(request.getAge()), "age", 18)
            .build();
            
    return personRepository.findAll(specification); 
}

####Between Example

find any person age between 18 and 25, birthday between someday and someday.

public Persons findAll(SearchRequest request) {
    Specification<Person> specification = new Specifications<Person>()
            .between(Objects.nonNull(request.getAge(), "age", new Range<>(18, 25))
            .between("birthday", new Range<>(new Date(), new Date()))
            .build();
            
    return personRepository.findAll(specification); 
}  

####Pagination and Sort

public Page<Person> findAll(SearchRequest request) {
    Specification<Person> specification = new Specifications<Person>()
            .eq(StringUtils.isNotBlank(request.getName()), "name", request.getName())
            .gt("age", 18)
            .between("birthday", new Range<>(new Date(), new Date()))
            .like("nickName", "%og%")
            .build();
            
    Sort sort = new Sorts()
        .desc(StringUtils.isNotBlank(request.getName()), "name")
        .asc("birthday")
        .build();
            
    return personRepository.findAll(specification, new PageRequest(0, 15, sort));
}

####ManyToOne Query

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private Integer age;
    private String name;
    private String nickName;
    private String company;
    private Date birthday;
    @OneToMany(cascade = ALL)
    private Set<Phone> phones= new HashSet<>();
    
    // getter and setter
@Entity
public class Phone {
    @Id
    @GeneratedValue
    private Long id;

    private String number;
    private String brand;
    @ManyToOne
    private Person person;
    
    // getter and setter
public interface PhoneRepository extends JpaRepository<Phone, Long>, JpaSpecificationExecutor<Phone> {
}
public List<Phone> findAll(SearchRequest request) {
    Specification<Phone> specification = new Specifications<Phone>()
        .eq(StringUtils.isNotBlank(request.getBrand()), "brand", request.getBrand())
        .and(StringUtils.isNotBlank(request.getPersonName()), (root, query, cb) -> {
            Path<Person> person = root.get("person");
            return cb.equal(person.get("name"), request.getPersonName());
        })
        .build();

    return phoneRepository.findAll(specification);
}

jpa-spec's People

Contributors

wenhao avatar

Watchers

James Cloos avatar JackCheng avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.