Spring 실전편

2022. 11. 15. 03:23강의 정리/Spring 기초

반응형

https://spring.io/guides

 

Spring | Guides

 

spring.io

 공식 문서는 사랑이다

 

 

 


순서

1. 프로젝트 환경설정

2. 요구사항 분석

3. 도메인과 엔티티, 테이블 설계

4. 아키텍쳐 구성(Controller, Service, Repository)

5. 핵심 비즈니스 로직 개발(회원, 상품, 주문)

  • 회원, 상품, 주문 도메인 개발
  • 핵심 비즈니스 로직 개발
  • 테스트 케이스 검증
  • 도메인 주도 설계 이해

6. 테스트

7. 웹 계층 개발

 

학습 방법

처음부터 끝까지 직접 코딩하면서 공부하기

 

 

강의 목표

기술(Spring, JPA)들을 이미 알고있는 사람들이, 최대한 기술을 잘 사용할 수 있게 만들어주는 것

 

 


 

프로젝트 환경설정

1. 프로젝트 생성

 

 

1-1. https://start.spring.io/ 에서 기본 설정들을 저장하고, 프로젝트 생성(generate)

 

1-2. 파일 압축 풀고, 저장후 IntelliJ에서 import나 Open을 통해서 폴더를 열어준다.

 

1-3. build gradle을 확인해주고, main 디렉토리의 Application, Test 실행해보고, 정상적으로 실행되는지 확인

// 혹시나 invalid source release 에러가 생겼다면

https://sohee-dev.tistory.com/134

 

[Mac/ Spring Boot] IntelliJ - invalid source release 해결 방법

📌 에러 내용 Execution failed for task ':compileJava'. > invalid source release: 11 JDK 버전과 project language level이 달라서 생기는 에러입니다. 📌 해결 방법 File -> Project Structure 저는 Project language level 이 11로 설

sohee-dev.tistory.com

 

1-4. http://127.0.0.1:8080로 접속해보기

 

1.5 lombok 설치가 잘되었는지 확인하기

windows 기준 : File - settings - 검색창에 plugins 서치

 

lombok이 잘 설치되어있다면 File - settings - 검색창에 Annotation processor 서치후 Enable 체크

 

그 후 아무 클래스나 만들고 @Getter @Setter등의 어노테이션을 적어보기

 

 

 

라이브러리에 대해서

  • Gradle은 의존관계가 있는 라이브러리를 함께 다운로드한다.

Spring boot 핵심 라이브러리

  • spring-boot-starter-tomcat: 톰캣 (웹서버)
  • spring-webmvc: 스프링 웹 MVC
  • spring-boot-starter-thymeleaf: 타임리프 템플릿 엔진(View)
  • JPA, Hibernate, Spring data JPA // Spring data JPA는 스프링과 JPA를 먼저 이해하고 사용해야 하는 응용 기술이다.
  • spring-boot-starter(공통): 스프링 부트 + 스프링 코어 + 로깅
    • spring-boot
      • spring-core
    • spring-boot-starter-logging
      • logback, slf4j

 

테스트 라이브러리

  • spring-boot-starter-test
    • junit: 테스트 프레임워크
    • mockito: 목 라이브러리
    • assertj: 테스트 코드를 좀 더 편하게 작성하게 도와주는 라이브러리
    • spring-test: 스프링 통합 테스트 지원

 

 

 

2. View 환경 설정

 

1단계에서 Thymeleaf를 설치했어야한다.

 

Thymeleaf의 장점은 HTML의 마크업을 최대한 깨지 않는다는 점이고,

단점은 반드시 태그를 닫아주어야 한다는 점이다. <br>또한 닫아주어야 한다.</br>

 

spring-boot-devtools라는 라이브러리를 추가해주고, build - recompile을 하면 개발 도중 html을 변경해도 서버를 재시작 하지않아도 된다.

 

View : 화면을 그리는데 집중

위치 : resources/templates/hello.html

<html>
<head xmlns:th="https://www.thymeleaf.org"> <!- thymeleaf 문법을 사용하겠다.-->
<body>
Hello
<p th:text="'안녕하세요. ' + ${data}">안녕하세요. 손님</p> <!- thymeleaf 문법을 사용하고, Controller(=Views.py)에서 보낸 인자 출력  -->
</body>
</head>
</html>

 

Controller : 비즈니스 로직을 처리하는데 집중

위치 : hello.hellospring/controller

@Controller // controller는 반드시 Annotation을 해주어야 함
public class HelloController {

    @GetMapping("hello") // HTTP의 Get을 의미
    // /hello url로 들어오면 해당 함수가 매핑이 된다.
    public String hello(Model model) {
        model.addAttribute("data", "hello!"); // data라는 key 값에 hello!라는 value 전송
        return "hello"; // resources:templates 폴더 밑에 있는 "hello" 이름을 가진 템플릿을 Render
    }
  }
  • Controller에서 리턴 값으로 문자를 반환하면 뷰 리졸버(viewResolver)가 화면을 찾아서 처리 함
    • Spring boot 템플릿엔진 기본 viewName 매핑
    • resource:templates/ {viewName} + .html
      1. 컨트롤러에서 "hello" 반환
      2. 뷰 리졸버에서 resource/templates 디렉토리 아래의 hello.html을 찾아 매핑 시켜줌.

 

 

 

3. H2 DB 설치 및 JPA와 DB 설정, 동작 확인

 

H2는 개발이나 테스트 용도로 가볍고 편리한 DB, 웹 화면 제공
https://www.h2database.com

 

윈도우 설치 버전: https://h2database.com/h2-setup-2019-10-14.exe
윈도우, 맥, 리눅스 실행 버전: https://h2database.com/h2-2019-10-14.zip
https://www.h2database.com

 

  • H2 설치후 H2 콘솔 실행하기
  • 데이터베이스 파일 생성 방법
    • jdbc:h2:~/jpashop(프로젝트명으로) (최소 한번)
    • ~/jpashop.mv.db 파일 생성 확인
    • 이후 부터는 jdbc:h2:tcp://localhost/~/jpashop 이렇게 접속

 

 

JPA와 DB 설정

1. application.yml에 아래와 같이 작성한다.

 

spring:
  datasource:
    url: jdbc:h2:tcp://localhost/~/jpashop
    username: sa
    password:
    driver-class-name: org.h2.Driver 
  
  jpa:
    hibernate:
      ddl-auto: create # 자동으로 테이블을 만들어주는 코드
    properties:
      hibernate:
        # show_sql: true
          format_sql: true

logging:
  level:
    org.hibernate.SQL: debug # 하이버네이트가 생성한 모든 sql과 로그를 남길 수 있다.
    # org.hibernate.type: trace

 

2. 실제로 동작하는지 확인을 위해 엔티티를 만든다.

package com.jpabook.jpashop;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
@Getter @Setter // Lombok을 사용하기에 게터 세터 어노테이션 가능
public class Member {

    @Id @GeneratedValue
    private Long id;

    private String username;
}

 

3. 레포지토리도 만든다.

package com.jpabook.jpashop;

import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Repository
public class MemberRepo {

    @PersistenceContext
    private EntityManager em; // @PersistenceContext를 등록해놓으면 스프링이 알아서 엔티티매니저를 생성해준다.

    public Long save(Member member) {
        em.persist(member); // 멤버 엔티티 영속 컨텍스트에 저장 -> DB로 전달
        return member.getId();
    }

    public Member find(Long id) {
        return em.find(Member.class, id);
    }
}

 

4. Shift + Ctrl + T로 테스트 클래스 생성하기

package com.jpabook.jpashop;

import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringRunner.class) // JUnit에게 Spring에 관련된 것을 테스팅한다 말해줘야함.
@SpringBootTest
public class MemberRepoTest {
    @Autowired
    MemberRepo memberRepo; // 의존성 주입

    @Test
    @Transactional // DB에 접근할 때는 반드시 트랜잭션 안에서 실행되어야한다.
    @Rollback(false)
    public void testMember() {
        //given
        Member member = new Member();
        member.setUsername("memberA");

        //when
        Long savedId = memberRepo.save(member);
        Member findMember = memberRepo.find(savedId);

        //then
        // 실제 잘 저장되었는지 확인
        Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
        Assertions.assertThat(findMember).isEqualTo(member); // true가 반환된다. 그 이유는 같은 트랜잭션 내에서 조회하면 같은 영속성 컨텍스트 안에 있기에, ID가 같다면 같은 엔티티로 인식함.
    }
}

 

위 테스트 메소드를 실행하면 위 SQL이 실행된다.

  • Spring에서는 테스트의 경우 테스트가 끝나면 실행했던 SQL문을 다시 롤백한다. 
    • Rollback(false)일시 롤백을 하지 않는다.

 

5. 실제 DB에 가서, 잘 저장되었는지 확인한다.

 

오류 해결하기

https://www.inflearn.com/questions/15495

 

테스트 도중 에러 발생 - 인프런 | 질문 & 답변

FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':test'. > No tests found for given includes: [jpabook.jpashop....

www.inflearn.com

 

 

 

쿼리 파라미터 로그 남기기

쿼리 파라미터 로그를 남기는 것이 중요하다.

?, ?에 무엇이 들어갔는지(= 값이 잘 전달되었는지)

 

방법 1 : 로그에 다음을 추가하기 org.hibernate.type : SQL 실행 파라미터를 로그로 남긴다.

logging:
  level:
    org.hibernate.type: trace # 파라미터의 인자 타입과 값을 보여준다.

인자 - 값

 

 

방법 2 : ?, ?를 직접적으로 보기 위해서 외부 라이브러리를 사용하면 된다.

https://github.com/gavlyukovskiy/spring-boot-data-source-decorator

 

GitHub - gavlyukovskiy/spring-boot-data-source-decorator: Spring Boot integration with p6spy, datasource-proxy, flexy-pool and s

Spring Boot integration with p6spy, datasource-proxy, flexy-pool and spring-cloud-sleuth - GitHub - gavlyukovskiy/spring-boot-data-source-decorator: Spring Boot integration with p6spy, datasource-p...

github.com

 

 

 

 

 

 

반응형