Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

Page , Query By Example(QBE) 본문

JPA

Page , Query By Example(QBE)

Seung__ 2021. 5. 23. 21:36

1. Page


Paging : DB에 저장된 entity를 page로 나누는 것.
page에 대한 설명은 아래와 같다. slice에 대한 정보와 전체에 대한 정보를 가지고 있다.
A page is a sublist of a list of objects.
It allows gain information about the position of it in the containing entire list.
public interface Page<T> extends Slice<T> 
Slice : data 묶음의 일부 덩어리. slice에서 제공하는 정보는 현재 slice에 대한 정보만을 준다.

slice에서 제공하는 method

  • int getNumber();
  • List<T> getContent();
  • int getNumberOfElements() 등등 
getNumberOfElements() : 현재 페이지의 element 수
Pageable :  Paging을 위해 spring에서 parameter를 추상화 한 interface, paging에 대한 요청
PageRequest.of(생성 후 가져올 페이지, size) : 가져올 페이지 index(0 시작), page당 element 수
getContent() : page내부에 있는 elements에 대한 정보를 가져옴.
 @Test
    void crud(){//create, read, update, delete
		
      //생성 후 1페이지 보여줄 예정(1/2)
      Page<User> userPage = userRepository.findAll(PageRequest.of(1, 3));

        System.out.println("page : " + userPage);
        System.out.println("total elements : " + userPage.getTotalElements()); //모든 elements 수
        System.out.println("total pages : " + userPage.getTotalPages()); //전체 몇 페이지?
        System.out.println("number of elements : " + userPage.getNumberOfElements()); //현재 페이지 element수
        System.out.println("sort : " + userPage.getSort());
        System.out.println("size : " + userPage.getSize()); //page나눌 때 크기

        //내부에 있는 user에 대한 정보를 가져오기 위해 .getcontent()
        userPage.getContent().forEach(System.out::println);

    }

 

Hibernate: 
    select
        user0_.id as id1_0_,
        user0_.created_at as created_2_0_,
        user0_.email as email3_0_,
        user0_.name as name4_0_,
        user0_.updated_at as updated_5_0_ 
    from
        user user0_ limit ? offset ?
page : Page 2 of 2 containing com.jpa.bookmanager.domain.User instances
total elements : 5 //총 element 수
total pages : 2 //총 page 수, 3개/2개로 나뉨
number of elements : 2 //2page
sort : UNSORTED
size : 3
//2page에는 element가 2개임
User(name=kim, email=kim@google.com, createdAt=2021-05-23T17:48:57.467827, updatedAt=2021-05-23T17:48:57.467827, id=4)
User(name=hyun, email=hyun@google.com, createdAt=2021-05-23T17:48:57.467827, updatedAt=2021-05-23T17:48:57.467827, id=5)

 

그러면 pageRequest에서 page index를 0으로 바꾸면??

 Page<User> userPage = userRepository.findAll(PageRequest.of(0, 3));
page : Page 1 of 2 containing com.jpa.bookmanager.domain.User instances
total elements : 5
total pages : 2
number of elements : 3
sort : UNSORTED
size : 3
User(name=hyun, email=hyun@naver.com, createdAt=2021-05-23T20:28:19.479893, updatedAt=2021-05-23T20:28:19.479893, id=1)
User(name=park, email=park@google.com, createdAt=2021-05-23T20:28:19.479893, updatedAt=2021-05-23T20:28:19.479893, id=2)
User(name=lee, email=lee@naver.com, createdAt=2021-05-23T20:28:19.479893, updatedAt=2021-05-23T20:28:19.479893, id=3)

1/2 page를 보여주고 있다!

 

 

 

 

2. Query By Example(QBE)


Entity를 example로 만들고, matcher를 추가하여 필요한 query를 만드는 방법

 

ExampleMatcher : Specification for property path matching to use in query by example (QBE).
                         example에서 사용된 query와 매칭되는 property path에 관한 정의.
                         
probe : 어떤 값들을 가지고 있는 도메인 객체?
Example = Probe + ExampleMatcher
Query : database에 정보를 요청하는 것.
Example.of(Probe, Matcher)
withIgnorePaths(ignored path) : 해당 요소(경로)를 무시하겠다. withIgnorePath("name") 이름은 무시하겠다.
withMatcher(확인할 요소(path), GenericPropertyMatcher) : property Matcher에 따라 해당 요소를 확인. 

 

@Test
    void crud(){//create, read, update, delete

        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withIgnorePaths("name") //해당 요소를 무시하겠다. name무시하겠다
                .withMatcher("email", endsWith()); //email이 어떻게 끝나는지 확인.

        Example<User> userExample = Example.of(new User("ma", "naver.com"), exampleMatcher);
        //probe에 user class를 넣으면 되는데, probe는 실제 엔티티를 말하지않고 가짜 엔티티, 예시!

        userRepository.findAll(userExample).forEach(System.out::println);

    }

 

위와 같이 작성하면 결과는 DB의 elements중 이메일이 "naver.com"로 끝나는 elements만 불러와 질 것이다.

 

where 부분을 보면 email이 같은지 확인하는 것을 볼 수 있당.

Hibernate: 
    select
        user0_.id as id1_0_,
        user0_.created_at as created_2_0_,
        user0_.email as email3_0_,
        user0_.name as name4_0_,
        user0_.updated_at as updated_5_0_ 
    from
        user user0_ 
    where
        user0_.email like ? escape ?
User(name=hyun, email=hyun@naver.com, createdAt=2021-05-23T20:47:25.856009, updatedAt=2021-05-23T20:47:25.856009, id=1)
User(name=lee, email=lee@naver.com, createdAt=2021-05-23T20:47:25.871625, updatedAt=2021-05-23T20:47:25.871625, id=3)

 

만약에 matcher를 제거하고 probe만 넣어서 example을 만드는 경우, probe와 exact match인 경우만 찾아옴

 

요렇게 사용할 수 도 있다. 위에서는 email이 "naver.com"으로 끝나는지 확인했는데,

이번에는 email에 "google"이 포함되는지 확인해보자.

그리고 user생성 시,  기본 생성자로 만들었당. 그래서 굳이 withIgnorePath를 사용하지 않았다.

   @Test
    void crud(){//create, read, update, delete

       User user = new User();
       user.setEmail("google");

       ExampleMatcher exampleMatcher = ExampleMatcher.matching().withMatcher("email", contains());
       Example<User> userExample = Example.of(user, exampleMatcher);

       // Example<User> userExample = Example.of(new User("ma", "naver.com"), exampleMatcher);//probe에 user class를 넣으면 되는데, probe는 실제 엔티티를 말하지않고 가짜 엔티티

        userRepository.findAll(userExample).forEach(System.out::println);

    }

결과는 예상한 것 처럼 google을 포함하는 elements만 불러왔다.

Hibernate: 
    select
        user0_.id as id1_0_,
        user0_.created_at as created_2_0_,
        user0_.email as email3_0_,
        user0_.name as name4_0_,
        user0_.updated_at as updated_5_0_ 
    from
        user user0_ 
    where
        user0_.email like ? escape ?
User(name=park, email=park@google.com, createdAt=2021-05-23T21:31:52.898314, updatedAt=2021-05-23T21:31:52.898314, id=2)
User(name=kim, email=kim@google.com, createdAt=2021-05-23T21:31:52.898314, updatedAt=2021-05-23T21:31:52.898314, id=4)
User(name=hyun, email=hyun@google.com, createdAt=2021-05-23T21:31:52.898314, updatedAt=2021-05-23T21:31:52.898314, id=5)

 

'JPA' 카테고리의 다른 글

Query Method 활용1  (0) 2021.05.26
SimpleJpaRepository분석  (0) 2021.05.24
Repository 제공 기능 2  (0) 2021.05.23
Repository에서 제공하는 기능 예시  (0) 2021.05.23
data.sql작성 및 log조회 방법  (0) 2021.05.23
Comments