1.Tổng quan
Khi sử dung Spring data jpa . Repository thường trả về một hay nhiều root class chưa tất cả các trường được định nghĩa , thực tế thì nhiều trường hợp chúng ta chỉ cần trả về một vài trường là đủ.
Vậy làm thế nào để có thể khiến cho repository chỉ trả về những trường mà chúng ra muốn ? Projections có thể giúp chúng ta làm việc đó
2. Entity class và Repository
public class CategoryEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String slug;
private String name;
private String description;
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
private Date updatedAt;
}
public interface CategoryRepository extends JpaRepository<CategoryEntity, Long> {
}
3. Interface-Based Projections
Đầu tiên hay định nghĩa một interface
public interface CategoryView {
Long getId();
String getSlug();
String getName();
}
Định nghĩa một method trong repository
public interface CategoryRepository extends JpaRepository<CategoryEntity, Long> {
List<CategoryView> findBy();
}
Tạo controller để test nhé :
@Controller
@RequestMapping(value = "/categories")
public class CategoryController {
@Autowired
private CategoryRepository categoryRepository;
@GetMapping("/no-projections")
public ResponseEntity<?> findAllNoProjections() {
return ResponseEntity.ok(categoryRepository.findAll());
}
@GetMapping("/projections")
public ResponseEntity<?> findAllProjections() {
return ResponseEntity.ok(categoryRepository.findBy());
}
}
Kết quả :
Khi không sử projections
Bạn có thể thấy khi không sử dụng projections . Jpa sẽ select tất cả các trường trong entity và và trả về tất cả chúng
**** Khi sử dụng projections****
Lúc này jpa chỉ select ba trường mà ta đã định nghĩa trong interface CategoryView
Một thứ khá hay ho là chúng ta có thể trường mà giá trị của nó được tạo ra bởi biểu thưc ví dụ
public interface CategorySummaryView {
Long getId();
String getSlug();
String getName();
@Value("#{target.name + ' ' + target.slug}")
String getNameAndSlug();
}
nameAndSlg là trường được tạo ra bằng cách nối hai giá trị name và sluf=g
Kết quả :
4. Dynamic Projections
Bạn có thể dynamic kiểu trả về bằng cách viết như sau :
public interface CategoryRepository extends JpaRepository<CategoryEntity, Long> {
<T> List<T> findBy(Class<T> tClass);
}
và gọi nó bằng cách categoryRepository.findBy(CategorySummaryView.class)
Cảm ơn các bạn đã đọc bài viết này và hẹn gặp lại ở các bài viết tiếp theo !