스프링

 

 

중급자를 위해 준비한
[웹 개발, 백엔드] 강의입니다.

JPA(Java Persistence API)를 보다 쉽게 사용할 수 있도록 여러 기능을 제공하는 스프링 데이터 JPA에 대해 학습합니다.

✍️
이런 걸
배워요!

ORM에 대한 이해

JPA 프로그래밍

Bean 생성 방법

스프링 JPA가 어렵게 느껴졌다면?
개념과 원리, 실제까지 확실하게 학습해 보세요.

제대로 배우는
백기선의 스프링 데이터 JPA

JPA(Java Persistence API)를 보다 쉽게 사용할 수 있도록 여러 기능을 제공하는 스프링 데이터 JPA에 대해 학습합니다.

 

강의 :

https://www.inflearn.com/course/스프링-데이터-jpa#reviews

 

 

 

강의자료 :

https://docs.google.com/document/d/1IjSKwMEsLdNXhRLvFk576VTR03AKTED_3jMsk0bHANg/edit

 

 

 

소스 코드

https://github.com/braverokmc79/springdatajpa

 

 

https://github.com/braverokmc79/demojpa3

 

 

 

  1. 강좌 소개

 

Application -> 스프링 데이터 JPA (-> JPA -> JDBC) -> Database

 

 

 

  1. 강사 소개

 

백기선

 

마이크로소프트(2+) <- 아마존(1) <- 네이버(4.5) <- SLT(2.5) ...

 

강좌

  • 스프링 프레임워크 입문 (Udemy)

  • 백기선의 스프링 부트 (인프런)

 

특징

  • 스프링 프레임워크 중독자

  • JPA 하이버네이트 애호가

  • 유튜브 / 백기선

 

 

 

 

 

 

 

[2부: 스프링 데이터 JPA 활용]

 

 

 

26.스프링 데이터 Common 11. 웹 기능 1부 소개

 

 

강의 :

https://www.inflearn.com/course/lecture?courseSlug=스프링-데이터-jpa&unitId=13769&tab=curriculum

 

 

스프링 데이터 웹 지원 기능 설정

  • 스프링 부트를 사용하는 경우에.. 설정할 것이 없음. (자동 설정)

  • 스프링 부트 사용하지 않는 경우?

 

@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
class WebConfiguration {}

 

 

 

제공하는 기능

  • 도메인 클래스 컨버터

  • @RequestHandler 메소드에서 Pageable과 Sort 매개변수 사용 

  • Page 관련 HATEOAS 기능 제공

    • PagedResourcesAssembler

    • PagedResoure

  • Payload 프로젝션

    • 요청으로 들어오는 데이터 중 일부만 바인딩 받아오기

    • @ProjectedPayload, @XBRead, @JsonPath

  • 요청 쿼리 매개변수를 QueryDSLdml Predicate로 받아오기

    • ?firstname=Mr&lastname=White => Predicate

 

 

 

 

 

 

 

 

 

 

 

 

 

 

27.스프링 데이터 Common 12. 웹 기능 2부 DomainClassConverter

 

 

강의 :

https://www.inflearn.com/course/lecture?courseSlug=스프링-데이터-jpa&unitId=13770&tab=curriculum

 

스프링 Converter

 

  @GetMapping("/posts/{id}")
    public String getAPost(@PathVariable Long id) {
        Optional<Post> byId = postRepository.findById(id);
        Post post = byId.get();
        return post.getTitle();
    }

 

 

 

   @GetMapping("/posts/{id}")
    public String getAPost(@PathVariable(“id”) Post post) {
        return post.getTitle();
    }

 

테스트

 

package com.example.demojap3.post;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;


import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
class PostControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Autowired
    PostRepository postRepository;


    @Test
    public void getPost() throws  Exception{
        Post post=new Post();
        post.setTitle("jpa");
        postRepository.save(post);

        mockMvc.perform(get("/posts/"+post.getId()))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().string("jpa"));
    }


}

 

 

 

 

 

 

 

 

 

 

 

 

 

28.스프링 데이터 Common 13. 웹 기능 3부 Pageable과 Sort

 

 

강의 :

https://www.inflearn.com/course/lecture?courseSlug=스프링-데이터-jpa&unitId=13771&tab=curriculum

 

스프링 MVC HandlerMethodArgumentResolver

 

페이징과 정렬 관련 매개변수

  • page: 0부터 시작.

  • size: 기본값 20.

  • sort: property,property(,ASC|DESC)

  • 예) sort=created,desc&sort=title (asc가 기본값)

 

 

   @GetMapping("/posts")
    public Page<Post> getPosts(Pageable pageable){
        return postRepository.findAll(pageable);
    }

 

 

package com.example.demojap3.post;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;


import static org.hamcrest.core.Is.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@SpringBootTest
@AutoConfigureMockMvc
class PostControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Autowired
    PostRepository postRepository;



    @Test
    public void getPosts() throws Exception{
        Post post =new Post();
        post.setTitle("jpa");
        postRepository.save(post);

        mockMvc.perform(
                get("/posts")
                .param("page", "0")
                .param("size", "10")
                .param("sort", "created,desc")
                .param("sort", "title")
                )
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.content[0].title", is("jpa")));
    }


}

 

출력 

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = {"content":[{"id":1,"title":"jpa","content":null,"created":null}],"pageable":{"sort":{"empty":false,"unsorted":false,"sorted":true},"offset":0,"pageNumber":0,"pageSize":10,"unpaged":false,"paged":true},"last":true,"totalElements":1,"totalPages":1,"size":10,"number":0,"sort":{"empty":false,"unsorted":false,"sorted":true},"first":true,"numberOfElements":1,"empty":false}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

 

 

 

 

 

 

 

 

 

 

 

 

 

 

29.스프링 데이터 Common 14. 웹 기능 4부 HATEOAS

 

 

강의 :

https://www.inflearn.com/course/lecture?courseSlug=스프링-데이터-jpa&unitId=13772&tab=curriculum

 

 

라이브러리 추가

 

 

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-hateoas</artifactId>
		</dependency>

 

 

스프링 HATEOAS의 낮은 버전에서는 ResourceSupport / Resource / Resources / PagedResources와 같은 클래스를 제공해줬지만 버전이 올라가면서 ResourceSupport / Resource / Resources / PagedResources 클래스의 위치와 이름이 변경되었습니다.

HATEOAS에서 위와 같은 클래스들을 사용할 수 없다면 밑에 변경된 클래스들을 확인하고 변경해줘야 합니다. 

 

 

첫 번째

 

첫 번째로 linkTo, methodOn의 메소드의 경우에는 옛날 버전에서는 ControllerLinkBuilder안에 포함되었지만 지금은 WebMvcLinkBuilder 안에 존재합니다.

 

  • import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*; 를 
  • import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; 로 변경 

 

  • ResourceSupport -> RepresentationModel

  • Resource -> EntityModel

  • Resources -> CollectionModel

  • PagedResources -> PagedModel

 

 

 

 

 

 

1. 기본 

 

    @GetMapping("/posts")
    public Page<Post> getPosts(Pageable pageable){
        return postRepository.findAll(pageable);
    }

=>출력

{  
   "content":[  
...
      {  
         "id":111,
         "title":"jpa",
         "created":null
      }
   ],
   "pageable":{  
      "sort":{  
         "sorted":true,
         "unsorted":false
      },
      "offset":20,
      "pageSize":10,
      "pageNumber":2,
      "unpaged":false,
      "paged":true
   },
   "totalElements":200,
   "totalPages":20,
   "last":false,
   "size":10,
   "number":2,
   "first":false,
   "numberOfElements":10,
   "sort":{  
      "sorted":true,
      "unsorted":false
   }
}

 

 

 

 

 

 ★2. hateoas 로 할경우

 

    @GetMapping("/posts-ha")
    public PagedModel<EntityModel<Post>> getPosts(Pageable pageable, PagedResourcesAssembler<Post> assembler) {
        Post post=new Post();
        post.setTitle("hello");
        post.setContent("jpa");
        postRepository.save(post);
        return assembler.toModel(postRepository.findAll(pageable));
    }

 

   "_embedded":{  
      "postList":[  
         {  
            "id":140,
            "title":"jpa",
            "created":null
         },
...
         {  
            "id":109,
            "title":"jpa",
            "created":null
         }
      ]
   },
   "_links":{  
      "first":{  
         "href":"http://localhost/posts?page=0&size=10&sort=created,desc&sort=title,asc"
      },
      "prev":{  
         "href":"http://localhost/posts?page=1&size=10&sort=created,desc&sort=title,asc"
      },
      "self":{  
         "href":"http://localhost/posts?page=2&size=10&sort=created,desc&sort=title,asc"
      },
      "next":{  
         "href":"http://localhost/posts?page=3&size=10&sort=created,desc&sort=title,asc"
      },
      "last":{  
         "href":"http://localhost/posts?page=19&size=10&sort=created,desc&sort=title,asc"
      }
   },
   "page":{  
      "size":10,
      "totalElements":200,
      "totalPages":20,
      "number":2
   }
}

 

 

 

 

 

 

 

 

 

 

 

30.스프링 데이터 Common: 마무리

 

 

강의 :

https://www.inflearn.com/course/lecture?courseSlug=스프링-데이터-jpa&unitId=13774&tab=curriculum

 

 

지금까지 살펴본 내용

  • 스프링 데이터 Repository

  • 쿼리 메소드

    • 메소드 이름 보고 만들기

    • 메소드 이름 보고 찾기

  • Repository 정의하기

    • 내가 쓰고 싶은 메소드만 골라서 만들기

    • Null 처리

  • 쿼리 메소드 정의하는 방법

  • 리포지토리 커스터마이징

    • 리포지토리 하나 커스터마이징

    • 모든 리포지토리의 베이스 커스터마이징

  • 도메인 이벤트 Publish

  • 스프링 데이터 확장 기능

    • QueryDSL 연동

    • 웹 지원

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

보람있게 보낸 하루가 편안한 잠을 가져다주듯이 값지게 쓰여진 인생은 편안한 죽음을 가져다준다. -레오나르도 다빈치

댓글 ( 4)

댓글 남기기

작성