JPA 2
introduces a criteria API that you can use to build queries programmatically.
By writing a criteria, you define the where clause of a query for a domain
class. Taking another step back, these criteria can be regarded as a predicate
over the entity that is described by the JPA criteria API constraints.
Spring
Data JPA takes the concept of a specification from Eric Evans' book, “Domain
Driven Design”, following the same semantics and providing an API to define
such specifications with the JPA criteria API. To support specifications, you
can extend your repository interface with the JpaSpecificationExecutor
interface, as follows:
public interface EmployeeRepository extends JpaSpecificationExecutor<Employee>, PagingAndSortingRepository<Employee, Integer>{ }
Implement Specification
interface. I created Specification object using anonymous class.
public static Specification<Employee> getByFirstAndLastName(String firstName, String lastName) {
return new Specification<Employee>() {
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
Path firstNameExpression = root.get("firstName");
Path lastNameExpression = root.get("lastName");
predicates.add(criteriaBuilder.equal(firstNameExpression, firstName));
predicates.add(criteriaBuilder.equal(lastNameExpression, lastName));
if (predicates.isEmpty()) {
return criteriaBuilder.conjunction();
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
}
};
}
Use the
specification to query for the results.
List<Employee>
emps = employeeRepository.findAll(EmployeeSpecifications.getByFirstAndLastName("Gopi",
"Battu"));
Find the
below working example.
Employee.java
package com.sample.app.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@Entity
@Table(name = "my_employee")
@EntityListeners(AuditingEntityListener.class)
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "age")
private Integer age;
@Column(name = "salary")
private Double salary;
@CreatedDate
@Column(name = "created_date")
private Date createdTime;
@LastModifiedDate
@Column(name = "last_modified_date")
private Date lastModifiedTime;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String modifiedBy;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public static EmployeeBuilder builder() {
return new EmployeeBuilder();
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public Date getLastModifiedTime() {
return lastModifiedTime;
}
public void setLastModifiedTime(Date lastModifiedTime) {
this.lastModifiedTime = lastModifiedTime;
}
public static class EmployeeBuilder {
private Employee emp;
public EmployeeBuilder() {
emp = new Employee();
}
public EmployeeBuilder firstName(String firstName) {
emp.setFirstName(firstName);
return this;
}
public EmployeeBuilder lastName(String lastName) {
emp.setLastName(lastName);
return this;
}
public EmployeeBuilder age(int age) {
emp.setAge(age);
return this;
}
public EmployeeBuilder salary(double salary) {
emp.setSalary(salary);
return this;
}
public Employee build() {
return emp;
}
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Employee [id=").append(id).append(", firstName=").append(firstName).append(", lastName=")
.append(lastName).append(", age=").append(age).append(", salary=").append(salary)
.append(", createdTime=").append(createdTime).append(", lastModifiedTime=").append(lastModifiedTime)
.append(", createdBy=").append(createdBy).append(", modifiedBy=").append(modifiedBy).append("]");
return builder.toString();
}
}
EmployeeRepository.java
package com.sample.app.repository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.sample.app.model.Employee;
public interface EmployeeRepository extends JpaSpecificationExecutor<Employee>, PagingAndSortingRepository<Employee, Integer>{
}
Employeespecifications.java
package com.smaple.app.jpa.specification;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.data.jpa.domain.Specification;
import com.sample.app.model.Employee;
public class EmployeeSpecifications {
public static Specification<Employee> getByFirstAndLastName(String firstName, String lastName) {
return new Specification<Employee>() {
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
Path firstNameExpression = root.get("firstName");
Path lastNameExpression = root.get("lastName");
predicates.add(criteriaBuilder.equal(firstNameExpression, firstName));
predicates.add(criteriaBuilder.equal(lastNameExpression, lastName));
if (predicates.isEmpty()) {
return criteriaBuilder.conjunction();
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
}
};
}
}
App.java
package com.sample.app;
import java.util.List;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.sample.app.model.Employee;
import com.sample.app.repository.EmployeeRepository;
import com.smaple.app.jpa.specification.EmployeeSpecifications;
@SpringBootApplication
public class App {
public static void main(String args[]) {
SpringApplication.run(App.class, args);
}
@Bean
public CommandLineRunner demo(EmployeeRepository employeeRepository) {
return (args) -> {
Employee emp1 = Employee.builder().firstName("Ram").lastName("Gurram").age(32).salary(100000.23).build();
Employee emp2 = Employee.builder().firstName("Joel").lastName("Chelli").age(43).salary(60000).build();
Employee emp3 = Employee.builder().firstName("Gopi").lastName("Battu").age(32).salary(1000000).build();
Employee emp4 = Employee.builder().firstName("Bomma").lastName("Srikanth").age(39).salary(60000).build();
Employee emp5 = Employee.builder().firstName("Surendra").lastName("Sami").age(32).salary(100000.23).build();
Employee emp6 = Employee.builder().firstName("Bhadri").lastName("Venakata RamaRao").age(32)
.salary(100000.23).build();
Employee emp7 = Employee.builder().firstName("Sushmithaa").lastName("Kulakarni").age(39).salary(100000.23)
.build();
employeeRepository.save(emp1);
employeeRepository.save(emp2);
employeeRepository.save(emp3);
employeeRepository.save(emp4);
employeeRepository.save(emp5);
employeeRepository.save(emp6);
employeeRepository.save(emp7);
for (Employee emp : employeeRepository.findAll()) {
System.out.println(emp);
}
System.out.println("***************************");
List<Employee> emps = employeeRepository
.findAll(EmployeeSpecifications.getByFirstAndLastName("Gopi", "Battu"));
for (Employee emp : emps) {
System.out.println(emp);
}
};
}
}
application.properties
logging.level.root=WARN logging.level.org.hibernate=ERROR ## H2 specific properties spring.h2.console.enabled=true spring.h2.console.path=/h2 spring.datasource.url=jdbc:h2:file:~/db/myOrg.db;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1; spring.datasource.username=krishna spring.datasource.password=password123 spring.datasource.driverClassName=org.h2.Driver ## JPA specific properties # Creates the schema, destroying previous data. spring.jpa.hibernate.ddl-auto=create spring.jpa.database-platform=org.hibernate.dialect.H2Dialect #spring.jpa.show-sql=true #spring.jpa.properties.hibernate.format_sql=true ## Database connection pooling properties # Number of ms to wait before throwing an exception if no connection is available. spring.datasource.max-wait=10000 # Maximum number of active connections that can be allocated from this pool at the same time. spring.datasource.tomcat.max-active=10 spring.datasource.tomcat.max-idle=5 spring.datasource.tomcat.min-idle=3
Total
project structure looks like below.
Run
App.java, you can get below messages in console.
Employee [id=1, firstName=Ram, lastName=Gurram, age=32, salary=100000.23, createdTime=null, lastModifiedTime=null, createdBy=null, modifiedBy=null] Employee [id=2, firstName=Joel, lastName=Chelli, age=43, salary=60000.0, createdTime=null, lastModifiedTime=null, createdBy=null, modifiedBy=null] Employee [id=3, firstName=Gopi, lastName=Battu, age=32, salary=1000000.0, createdTime=null, lastModifiedTime=null, createdBy=null, modifiedBy=null] Employee [id=4, firstName=Bomma, lastName=Srikanth, age=39, salary=60000.0, createdTime=null, lastModifiedTime=null, createdBy=null, modifiedBy=null] Employee [id=5, firstName=Surendra, lastName=Sami, age=32, salary=100000.23, createdTime=null, lastModifiedTime=null, createdBy=null, modifiedBy=null] Employee [id=6, firstName=Bhadri, lastName=Venakata RamaRao, age=32, salary=100000.23, createdTime=null, lastModifiedTime=null, createdBy=null, modifiedBy=null] Employee [id=7, firstName=Sushmithaa, lastName=Kulakarni, age=39, salary=100000.23, createdTime=null, lastModifiedTime=null, createdBy=null, modifiedBy=null] *************************** Employee [id=3, firstName=Gopi, lastName=Battu, age=32, salary=1000000.0, createdTime=null, lastModifiedTime=null, createdBy=null, modifiedBy=null]
You can
download the complete working application from this link.
No comments:
Post a Comment