Skip to content

this repo is for my lecture about spring data specifications

Notifications You must be signed in to change notification settings

ozayduman/spring-data-specification

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This project shows how to use specification queries in spring data jpa. There are sample basic usages shown in CustomerSpecificationRepositoryTest.java

Sample Specification Usage:

 @Test
    void shouldExecuteSpecification() {
        final Optional<Customer> customer = customerRepository.findOne(Specification
            .where(notBornToday()
                .and(byEmail("od@gmail.com"))
                .and(byPhoneNumber("5555")))
         );

        Assertions.assertTrue(customer.isPresent());
  }

Sample Specification:

    public Specification<Customer> notBornToday() {
      return (root, criteriaQuery, criteriaBuilder) -> {
          return criteriaBuilder.lessThan(root.get(Customer_.birdDate), LocalDate.now());
      };
    }

SPECIFICATION-BUILDER SAMPLE

This section shows how to use Specification Builder library to write type-safe (client-oriented dynamic) queries for search screens in spring data jpa. The sample usage is shown in CustomerController.java

<dependency>
    <groupId>com.github.ozayduman</groupId>
    <artifactId>specification-builder</artifactId>
    <version>0.0.3</version>
</dependency>
@RestController
@RequestMapping("/customer")
@Transactional
@RequiredArgsConstructor
public class CustomerController {
    private final CustomerService customerService;

    @PostMapping("/query")
    public PageResultDTO query(@RequestBody PageRequestDTO pageRequestDTO){
        return PageResultDTO.from(customerService.query(pageRequestDTO), CustomerMapper.INSTANCE::toDTO);
    }
}

Then define as a Service class by injecting CustomerRepository class. In this class create a SpecificationBuilder and use bind method to allow whatever fields you want to be queryable. Also create a PageRequestBuilder and use bindSort method to allow which fields to be sortable as shown below:

@Service
@RequiredArgsConstructor
public class CustomerService {
    private final CustomerRepository customerRepository;

    public Page<Customer> query(PageRequestDTO pageRequestDTO) {
        final Specification<Customer> specification = createSpecification(pageRequestDTO);
        final PageRequest pageRequest = createPageRequest(pageRequestDTO);
        return customerRepository.findAll(specification, pageRequest);
    }

    private Specification<Customer> createSpecification(PageRequestDTO pageRequestDTO) {
        return SpecificationBuilder.<Customer>of(pageRequestDTO)
                .bind("name", Customer_.name)
                .bind("lastName", Customer_.surname)
                .bind("email", Customer_.email)
                .bindJoin("phoneNumber", Customer_.phones, Phone_.number)
                .build();
    }

    private PageRequest createPageRequest(PageRequestDTO pageRequestDTO) {
        return PageRequestDTO.PageRequestBuilder.of(pageRequestDTO)
                .bindSort("name", Customer_.name)
                .bindSort("lastName", Customer_.surname)
                .bindSort("email", Customer_.email)
                .build();
    }
}

Finally, define a repository interface that extends PagingAndSortingReporistory and JpaSpecificationExecutor interfaces as follows:

public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long>, JpaSpecificationExecutor<Customer> { }

H2 Console:

url:http://localhost:8080/h2-console/
username:ozay
password:ooo

Controller Health Url:

http://localhost:8080/customer/ping
username:ozay
password:ooo

http://localhost:8080/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config#/

About

this repo is for my lecture about spring data specifications

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages