Toggle Theme Editor
Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Charcoal

[series Spring Boot] 15. Spring Data Jpa 3

Discussion in 'Spring Framework' started by quydtkt, 19/12/19.

  1. quydtkt

    quydtkt Administrator

    Trong bài này, chúng ta sẽ cùng tìm hiểu về các loại repository của Spring Data Jpa.
    1. Các loại Repository trong Spring Data Jpa
    a. Giới thiệu
    - Trong bài viết trước, mình đã giới thiệu và Repository trong Spring Data Jpa. Repository là tập hợp một số class (interface) tiên ích của Spring Data Jpa giúp chúng ta bỏ qua công việc viết sql query nhàm chán bằng cơ chế Query creation (tự động sinh code sql) thông qua cách đặt tên cho method.​
    - Ngoài interface Repository, Spring Data Jpa còn cung cấp cho chúng ta một số interface khác là con của interface Repository.​
    - Các lớp interface là con của interface Repository trong Spring Data Jpa là: CrudRepository, PagingAndSortingRepository, JpaRepository.​
    b. CrudRepository
    - CrudRepository là interface kế thừa từ interface Repository.​
    - Cung cấp thêm các phương thức căn bản cho công việc save, get, update, delete dữ liệu tại database​
    CrudRepository.java
    PHP:
    package org.springframework.data.repository;
     
    import java.util.Optional;
     
    @NoRepositoryBean
    public interface CrudRepository<T, ID> extends Repository<T, ID> {
        <S extends T> S save(S var1);
     
        <S extends T> Iterable<S> saveAll(Iterable<S> var1);
     
        Optional<T> findById(ID var1);
     
        boolean existsById(ID var1);
     
        Iterable<T> findAll();
     
        Iterable<T> findAllById(Iterable<ID> var1);
     
        long count();
     
        void deleteById(ID var1);
     
        void delete(T var1);
     
        void deleteAll(Iterable<? extends Tvar1);
     
        
    void deleteAll();
    }
    - Công dụng các các method​
    • save: Lưu một dòng.
    • saveAll: Lưu nhiều dòng.
    • findById: Get 1 dòng thông qua id.
    • existsById: Kiểm tra dòng có tồn tại hay không thông qua id.
    • findAll: Get tất cả các dòng.
    • findAllById: Get danh sách dòng thông qua danh sách các id.
    • count: Đếm số lượng dòng của bảng.
    • deleteById: Xóa dòng thông qua id.
    • delete: Xóa chính dòng truyền vào.
    • deleteAll(Iterable<? extends T> var1): Xóa nhiều dòng thông qua id.
    • deleteAll(): Xóa tất cả các dòng.
    c. PagingAndSortingRepository
    - PagingAndSortingRepository là interface kế thừa từ interface CrudRepository.​
    - Cung cấp thêm các phương thức để get dữ liệu có sắp xếp và phân trang.​
    PagingAndSortingRepository.java
    PHP:
    package org.springframework.data.repository;
     
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.Sort;
     
    @
    NoRepositoryBean
    public interface PagingAndSortingRepository<TID> extends CrudRepository<TID> {
        
    Iterable<TfindAll(Sort var1);
     
        
    Page<TfindAll(Pageable var1);
    }
    - Công dụng các các method​
    • findAll(Sort var1): Get tất cả các record của bảng có sắp xếp theo một cột nào đó.
    • findAll(Pageable var1): Giống như phương thức trên và có thêm tùy chọn phân trang.
    d. JpaRepository
    - JpaRepositorylà interface kế thừa từ interface PagingAndSortingRepository.​
    - Cung cấp thêm các phương thức theo chuẩn Jpa như là xóa theo lô, hoặc đồng bộ từ Persistence Context vào database.​
    - Ngoài ra, JpaRepository còn override lại một số phương thức các các interface cha để giúp cho việc theo tác với dữ liệu trả về đơn giản hơn.​
    JpaRepository.java
    PHP:
    package org.springframework.data.jpa.repository;
     
    import java.util.List;
    import org.springframework.data.domain.Example;
    import org.springframework.data.domain.Sort;
    import org.springframework.data.repository.NoRepositoryBean;
    import org.springframework.data.repository.PagingAndSortingRepository;
    import org.springframework.data.repository.query.QueryByExampleExecutor;
     
    @
    NoRepositoryBean
    public interface JpaRepository<TID> extends PagingAndSortingRepository<TID>, QueryByExampleExecutor<T> {
        List<
    TfindAll();
     
        List<
    TfindAll(Sort var1);
     
        List<
    TfindAllById(Iterable<IDvar1);
     
        <
    extends T> List<SsaveAll(Iterable<Svar1);
     
        
    void flush();
     
        <
    extends TS saveAndFlush(S var1);
     
        
    void deleteInBatch(Iterable<Tvar1);
     
        
    void deleteAllInBatch();
     
        
    T getOne(ID var1);
     
        <
    extends T> List<SfindAll(Example<Svar1);
     
        <
    extends T> List<SfindAll(Example<Svar1Sort var2);
    }
    - Công dụng các các method​
    • findAll(): Giống với phương thức findAll của CrudRepository, nhưng có kiểu trả về là List thay cho Iterable
    • findAll(Sort var1): Giống với phương thức fillAll của PagingAndSortingRepository, nhưng có kiểu trả về là List thay cho Iterable
    • findAllById: Giống với phương thức findAllById của CrudRepository, nhưng có kiểu trả về là List thay cho Iterable.
    • saveAll: Giống với phương thức saveAll của CrudRepository, nhưng có kiểu trả về là List thay cho Iterable
    • flush: Đẩy dữ liệu xuống database
    • saveAndFlush: Lưu và đẩy dữ liệu xuống database
    • deleteInBatch: Xóa nhiều dòng trong bảng
    • deleteAllInBatch: Xóa tất cả dòng trong một lần gọi batch
    • getOne: Get ra 1 dòng thông qua id. Nếu không tìm được dữ liệu thì sẽ quăng ra Exception
    • findAll(Example<S> var1): Get dữ liệu theo điều kiện
    • findAll(Example<S> var1, Sort var2): Get dữ liệu theo điều kiện và sắp xếp kết quả tìm được.
    2. Demo
    User.java
    PHP:
    package vn.congdongjava.entity;
     
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    import java.util.Date;
     
    @
    Entity
    @Table(name "MR_USER")
    public class 
    User {
     
        @
    Id
        
    @GeneratedValue(strategy GenerationType.IDENTITY)
        private 
    Long id;
     
        @
    Column(name "USERNAME")
        private 
    String username;
     
        @
    Column(name "PASSWORD")
        private 
    String password;
     
        @
    Column(name "BIRTH_DATE")
        private 
    Date birthDate;
     
        public 
    Long getId() {
            return 
    id;
        }
     
        public 
    void setId(Long id) {
            
    this.id id;
        }
     
        public 
    String getUsername() {
            return 
    username;
        }
     
        public 
    void setUsername(String username) {
            
    this.username username;
        }
     
        public 
    String getPassword() {
            return 
    password;
        }
     
        public 
    void setPassword(String password) {
            
    this.password password;
        }
     
        public 
    Date getBirthDate() {
            return 
    birthDate;
        }
     
        public 
    void setBirthDate(Date birthDate) {
            
    this.birthDate birthDate;
        }
    }
    - Bảng MR_USER lưu 3 thông tin của user: USERNAME, PASSWORD, BIRTH_DATE​
    UserRepository.java
    PHP:
    package vn.congdongjava.dao;
     
    import org.springframework.data.jpa.repository.JpaRepository;
    import vn.congdongjava.entity.User;
     
    public interface 
    UserRepository extends JpaRepository<UserLong> {
    }
    - Interface UserRepository extends từ interface JpaRepository để sử dụng các hàm có sẵn do Spring Data Jpa cung cấp​
    PagingSco.java
    PHP:
    package vn.congdongjava.sco;
     
    import java.io.Serializable;
     
    public class 
    PagingSco implements Serializable {
     
        private static final 
    long serialVersionUID 4512906127827333037L;
     
        private 
    Integer offset;
     
        private 
    Integer limit;
     
        private 
    String sortColumn;
     
        private 
    String sortOrder;
     
        public 
    Integer getOffset() {
            return 
    offset;
        }
     
        public 
    void setOffset(Integer offset) {
            
    this.offset offset;
        }
     
        public 
    Integer getLimit() {
            return 
    limit;
        }
     
        public 
    void setLimit(Integer limit) {
            
    this.limit limit;
        }
     
        public 
    String getSortColumn() {
            return 
    sortColumn;
        }
     
        public 
    void setSortColumn(String sortColumn) {
            
    this.sortColumn sortColumn;
        }
     
        public 
    String getSortOrder() {
            return 
    sortOrder;
        }
     
        public 
    void setSortOrder(String sortOrder) {
            
    this.sortOrder sortOrder;
        }
    }
    - Class PagingSco chứa các thông tin để sử dụng cho việc phân trang tại server​
    • offset: Vị trí dòng đầu tiên
    • limit: Số lượng dòng lấy ra
    • sortColumn: Cột sắp xếp
    • ssortOrder: Hướng sắp xếp (tang dần/giảm dần)
    CompanyService.java
    PHP:
    package vn.congdongjava.service;
     
    import vn.congdongjava.entity.User;
    import vn.congdongjava.sco.PagingSco;
     
    import java.util.List;
     
    public interface 
    CompanyService {
     
        
    User getUser(Long id);
     
        List<
    UsergetListUser(PagingSco sco);
     
        
    void saveUser(User user);
    }
    - Interface CompanyService cung cấp 3 method​
    • getUser: Lấy ra 1 dòng của bảng MR_USER thông qua id
    • getListUser: Lấy ra nhiều dòng của bảng MR_USER, có hỗ trợ phân trang và sắp xếp.
    • saveUser: Thêm mới 1 dòng vào bảng MR_USER.
    CompanyServiceImpl.java
    PHP:
    package vn.congdongjava.service.impl;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.Sort;
    import org.springframework.stereotype.Service;
    import vn.congdongjava.dao.UserRepository;
    import vn.congdongjava.entity.User;
    import vn.congdongjava.sco.PagingSco;
    import vn.congdongjava.service.CompanyService;
     
    import java.util.Collections;
    import java.util.List;
     
    @
    Service
    public class CompanyServiceImpl implements CompanyService {
     
        @
    Autowired
        
    private UserRepository userRepository;
     
        @
    Override
        
    public User getUser(Long id) {
            return 
    userRepository.getOne(id);
        }
     
        @
    Override
        
    public List<UsergetListUser(PagingSco sco) {
            
    Sort sort;
            
    Sort.Order order;
            
    Pageable pageable;
            
    Sort.Direction direction;
     
            
    direction "asc".equals(sco.getSortOrder()) ? Sort.Direction.ASC Sort.Direction.DESC;
            
    order = new Sort.Order(directionsco.getSortColumn());
            
    sort Sort.by(Collections.singletonList(order));
            
    pageable PageRequest.of(sco.getOffset(), sco.getLimit(), sort); ;
     
            return 
    userRepository.findAll(pageable).getContent();
        }
     
        @
    Override
        
    public void saveUser(User user) {
            
    userRepository.save(user);
        }
    }
    - Class CompanyServiceImpl là hiện thực của interface CompanyService​
    • userRepository: Dùng để tương tác với bản MR_USER
    • getUser: Gọi method getOne của repository để lấy ra 1 dòng của bảng MR_USER
    • getListUser: Lấy ra nhiều dòng tại bảng MR_USER thông qua các thông tin phân trang
      • direction: Nếu hướng sortOrder là asc là sắp xếp theo chiều tăng dần (Sort.Direction.ASC). Ngược lại thì sắp xếp theo chiều giảm dần (Sort.Direction.DESC).
      • order: Thông tin sắp xếp. Bao gồm cột và hướng sắp xếp
      • sort: Chứa một hoặc nhiều order
      • pageable: Thông tin trang lấy ra. Bao gồm dòng bắt đầu, số lượng dòng và thông tin sắp xếp
      • Cuối cùng là gọi method findAll để lấy ra các dòng của bảng MR_USER. Method findAll trả về kiểu Page chứa các thông tin phân trang khác như: Số lượng dòng, trang đầu, trang trước, trang kế, trang cuối, … Ta có thể gọi method getContent để lấy ra danh sách các dòng của trang
    • saveUser: Gọi method save của repository để thêm mới ra 1 dòng tại bảng MR_USER
    UserController.java
    PHP:
    package vn.congdongjava.controller;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import vn.congdongjava.entity.User;
    import vn.congdongjava.sco.PagingSco;
    import vn.congdongjava.service.CompanyService;
     
    import java.util.Date;
    import java.util.List;
     
    @
    RestController
    public class UserController {
     
        @
    Autowired
        
    private CompanyService companyService;
     
        @
    GetMapping("user/save")
        public 
    void save() {
            
    User user;
     
            
    user = new User();
     
            
    user.setUsername("quydtkt");
            
    user.setPassword("1111111");
            
    user.setBirthDate(new Date());
     
            
    companyService.saveUser(user);
        }
     
        @
    GetMapping("user/{id}")
        public 
    User get(@PathVariable Long id) {
            return 
    companyService.getUser(id);
        }
     
        @
    GetMapping("user")
        public List<
    UsergetList(@RequestParam Integer offset, @RequestParam Integer limit, @RequestParam String sortColumn, @RequestParam String sortOrder) {
            
    PagingSco sco;
     
            
    sco = new PagingSco();
            
    sco.setOffset(offset);
            
    sco.setLimit(limit);
            
    sco.setSortColumn(sortColumn);
            
    sco.setSortOrder(sortOrder);
     
            return 
    companyService.getListUser(sco);
        }
    }
    - Cung cấp 3 request mapper để tạo mới và lấy ra thông tin user​
    • save: Lưu user vào database
    • get: Lấy ra 1 user
    • getList: Nhận thông tin phân trang và lấy ra danh sách các user tương ứng
    Cám ơn các bạn đã theo dõi. Hẹn gặp lại trong bài viết tiếp theo :)
     

    Attached Files:

    Joe likes this.
  2. Joe

    Joe Thành viên VIP

    Sprint Boot is a big package. I just wonder how the developer team work together...
     
  3. quydtkt

    quydtkt Administrator

    Can you explain this question more clearly?
     
  4. Joe

    Joe Thành viên VIP

    Of course. The problem of Spring Boot is not the functionality, but the generated size of the app. The reason why the generated size is so "immense" is its included SPRING package so that the app could run. You know, as I started to build the SWING-MVC for CongdongJava I was aware about this problem and tried so far as I could to keep the "included" size small. And the result of the SWING-MVC package is 21.7 KB (jar) or 40 KB (in class) while Spring Boot package is roughly 250 MB. The big size usually slowdowns the process and at the end: bad performance.

    The famous Russian Gun inventor Kalashnikov said:
    [​IMG]
    and that is what I have in mind. Nothing against your series, NOR against Spring Boot.
    Example about the size problem: click HERE
     
  5. quydtkt

    quydtkt Administrator

    I think, given the current capacity of computers, this is not a problem. I usually care more about the amount of data stored in Ram than in the hard drive. Of course, I don't use dependency excessively, only the dependencies I really need for my project.
     
  6. Joe

    Joe Thành viên VIP

    Probably you misunderstood me :( I don't mind anything about you or your work. It's about the Spring-Boot development team that created this quite complex framework and that is what I think the biggest problem for its users to comprehend it thoroughly, and to work with it optimally.
     
  7. quydtkt

    quydtkt Administrator

    Sorry Joe. I have been working with Spring Boot for over 1 year. Spring Boot helped me a lot at work by minimizing the configuration for the project. Of course, to get this, the Spring Boot base project must become more complex and cumbersome. I think this is acceptable.
     
    Joe likes this.

Chia sẻ trang này

Loading...