In Spring Data JPA, a query projection can also be defined as a DTO (Data Transfer Object). Such classes hold properties for the fields that are supposed to be retrieved. In this case no proxies are created. Also nested projections are not possible.
Example
Entity
@Entity
public class Employee{
private @Id
@GeneratedValue
Long id;
private String name;
private String dept;
private int salary;
.............
}
Defining class-based projection
public class EmployeeInfo {
private String name;
private int salary;
public EmployeeInfo(String name, int salary) {
this.name = name;
this.salary = salary;
}
.............
}
As seen in above example, the projection class should have a constructor with properties parameters that should be loaded via query execution. Also If the store optimizes the query execution by limiting the fields to be loaded, the fields to be loaded are determined from the parameter names of the constructor that is exposed.
Repository
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
List<EmployeeInfo> findBy();
List<EmployeeInfo> findByDept(String dept);
}
Example Client
@Component
public class ExampleClient {
@Autowired
private EmployeeRepository repo;
public void run() {
List<Employee> employees = createEmployees();
repo.saveAll(employees);
System.out.println(" -- finding all employees --");
Iterable<Employee> all = repo.findAll();
all.forEach(System.out::println);
System.out.println(" -- finding all EmployeeInfo --");
List<EmployeeInfo> list = repo.findBy();
for (EmployeeInfo es : list) {
System.out.printf("Name: %s, Salary: %s%n", es.getName(), es.getSalary());
}
System.out.println(" -- finding the EmployeeInfo in IT dept --");
list = repo.findByDept("IT");
for (EmployeeInfo es : list) {
System.out.printf("Name: %s, Salary: %s%n", es.getName(), es.getSalary());
}
}
private List<Employee> createEmployees() {
return Arrays.asList(
Employee.create("Diana", "Admin", 3000),
Employee.create("Mike", "IT", 1000),
Employee.create("Rose", "Admin", 4000),
Employee.create("Sara", "Admin", 3500),
Employee.create("Tanaka", "IT", 3000),
Employee.create("Charlie", "IT", 4500)
);
}
}
Main class
public class ExampleMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
ExampleClient exampleClient = context.getBean(ExampleClient.class);
exampleClient.run();
EntityManagerFactory emf = context.getBean(EntityManagerFactory.class);
emf.close();
}
} -- finding all employees -- Employee{id=1, name='Diana', dept='Admin', salary=3000} Employee{id=2, name='Mike', dept='IT', salary=1000} Employee{id=3, name='Rose', dept='Admin', salary=4000} Employee{id=4, name='Sara', dept='Admin', salary=3500} Employee{id=5, name='Tanaka', dept='IT', salary=3000} Employee{id=6, name='Charlie', dept='IT', salary=4500} -- finding all EmployeeInfo -- Name: Diana, Salary: 3000 Name: Mike, Salary: 1000 Name: Rose, Salary: 4000 Name: Sara, Salary: 3500 Name: Tanaka, Salary: 3000 Name: Charlie, Salary: 4500 -- finding the EmployeeInfo in IT dept -- Name: Mike, Salary: 1000 Name: Tanaka, Salary: 3000 Name: Charlie, Salary: 4500
Example ProjectDependencies and Technologies Used: - spring-data-jpa 2.0.9.RELEASE: Spring Data module for JPA repositories.
Uses org.springframework:spring-context version 5.0.8.RELEASE - hibernate-core 5.3.6.Final: Hibernate's core ORM functionality.
Implements javax.persistence:javax.persistence-api version 2.2 - h2 1.4.197: H2 Database Engine.
- JDK 1.8
- Maven 3.5.4
|
|