Notice
Recent Posts
Recent Comments
Link
«   2026/04   »
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
관리 메뉴

Blog

[Spring] 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 본문

카테고리 없음

[Spring] 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

ggi88 2023. 4. 13. 16:07

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard

Spring Boot / JPA(Java Peristence API) / Gradle / HIBERNATE / Thymeleaf

스프링 입문

스프링 핵심 원리

스프링 웹 MVC

스프링 DB 데이터 접근기술

실전! 스프링 부트

설정

3.x.x 버전부터는 자바 17 이상을 써야한다고 한다.

  • 인텔리 제이로 build.gradle 열어서 프로젝트 오픈
  • 프로젝트 구성 확인
    • 프로젝트 폴더 main/test
  • 실행하면 localhost:8080 으로 톰캣 서버가 올라간다
  • 테스트할 때에는 settings>Build, Execution, Deployment>Gradle Build and run using&Ren tests using 을 IntelliJ IDEA 로 설정해준다
    (속도 개선)

라이브러리

  • 스프링부트 라이브러리
    • 로그 활용 시 요즘에는 logback 과 jul-to-slf4j 를 주로 사용한다
    • 테스트는 junit을 주로 쓴다 요즘에는 5버전을 쓴다,
      sping-test 스프링과 통합해서 사용할 수 있는 라이브러리
    • spring-boot-starter-web
      • spring-boot-starter-tomcat: 톰캣(웹서버)
      • spring-webmvc 스프링 웹 mvc
    • spring-boot-starter-thymeleaf 타임리프 템플릿 엔진(View)
    • spring-boot-starter(공통) 스프링부트 + 스프링 코어 + 로깅
      • spring-boot
        • spring-core
      • spring-boot-starter-logging
        • logback, slf4j
    • spring-boot-starter-test : 테스트 라이브러리
      • junit: 테스트 프레임워크
      • mockito: 목 라이브러리
      • assertj: 테스크코드를 편하게 작성해주는 라이브러리
      • spring-test: 스프링 통합 테스트 지원

View 설정

  • welcome page 만들기
  • static/index.html 을 올리면 welcome page 기능을 제공한다.
  • spring.io spring boot 문서에서 welcome page 설정을 찾아서 설명을 확인한다
  • hellospring 폴더에서 controller 폴더 만들고 HelloController.java 에 데이터 매핑 코드를 작성 후
    resources/templates/hello.html 에서 매핑된 데이터를 불러올 수 있다.
package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
    @GetMapping("hello")
    public String hello(Model model){
        model.addAttribute("data", "hello!!!!!!!");
        return "hello"; // hello.html 을 실행해라
    }
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'안녕하세요 ' + ${data}"> 안녕하세요 손님</p>
</body>
</html>

빌드

  • 콘솔로 프로젝트 폴더 이동
  • ./gradlew.bat build 실행(unix ./gradlew build)
    이상 시 clean build 실행, 지우고 빌드함
  • cd build/libs
  • java -jar hello-spring-0.0.1-SNAPSHOT.jar
    스프링이 실행된다.

스프링 웹 개발 기초

  • 정적 컨텐츠

    • static, public, resources 폴더에 넣어 그냥 사용
  • MVC 와 템플릿 엔진: 모델 뷰(템플릿) 컨트롤러 를 나눠 서버가 일정부분 화면을 그려줌

    • Controller

    • View

    • Model

    • 컨트롤러를 선언하고 다시 템플릿 코드를 작성해본다
      컨트롤러 선언 시 @RequestsParam(”name”) 을 지정하면 기본값이 필수 이기 때문에 url 에서 name 파라미터를 받아야한다.
      ex) localhost:8080/hello-mvc?name=spring

      <!DOCTYPE html>
      <html xmlns:th="http://www.thymeleaf.org">
      
      <body>
      <p th:text="'안녕하세요 ' + ${name}">Hello empty</p>
      </body>
      </html>
      @GetMapping("hello-mvc")
        public String helloMcx(@RequestParam("name") String name, Model model){
            model.addAttribute("name", name);
            return "hello-template";
        }
  • API: 요청하면 JSON 으로 데이터를 클라이언트에 전달, 화면은 알아서 클라이언트가 그림
    vue, react

    • Controller 에 @Response회
    • @ResponseBody 사용시
      Http 의 body 에 문자 내용을 직접 반환
      viewResolver 대신에 HttpMessageConverter 가 동작
      기본 문자처리 StringHttpMessageConverter
      기본 객체처리 MappingJackson2HttpMessageConverter
      byte 처리 등등 기타 여러 httpMessageConverter가 기본으로 등록되어 있

회원관리에제 - 백엔드

  • 비지니스 요구사항 정리
  1. 컨트롤러: 웹 mvc 의 컨트롤러 역활
  2. 서비스: 핵심 비즈니스 로직 구현
  3. 리포지토리: 데이터베이스에 접근, 도메인 객체를 DB 에 저장하고 관리
  4. 도메인: 비즈니스 도메인 객
  • 회원 도메인과 리포지토리 만들기
    도메인 패키지에 단순히 id, name 으로 객체 설정
    (windwos alt + insert = 제너레이)
    문법보면 익숙해서 대강은 알겠는데, 정리된거라도 빠르게 한번 훑어야겠다
  • 회원 리포지토리 테스트 케이스 작성
    JUnit 도 자주 쓰지만 AssertJ 테스트 라이브러리르 주로 쓴다고 한다.
    (DUnit 과 비슷하네, 테스트 라이브러리는 어디나 비슷비슷한듯 하다)
    클래스를 정적 임포트 시키면 함수만 바로 쓸 수 있다.
    (요떄 alt + enter 활용)
  • 회원 서비스 개발
    MemberService 클래스 만든다
    (ctrl + alt + v 리턴 코드 생성)
    repository 는 데이터 중심적으로 service 는 비즈니스 중심적으로 코드를 나눈다
  • 회원 서비스 테스트
    생성자를 선언해 메모리디비(?)를 넣어 사용하는 방법으로 변경한다
    (DI 디펜던시 인젝션)

스프링 빈과 의존관계

  • 스프링 빈을 등록하고 의존관계 설정하기
    • 회원 컨트롤러가 회원서비스와 회원 리포지토리를 사용할 수 있게 의존관계를 준비하자
      MemberController 만들고 생성자를 추가해주자
    • 생성자 위에 @Autowired 어노테이션을 선언하자
    • @Controller, @Service, @Repository 각 클래스별로 선언, 정형화된 패턴이라함
    • 컨트롤러 통해서 외부 요청 받고, 서비스에서 비즈니스 로직을 만들고, 리포지토리에서 데이터 저장하고
  • 스프링빈을 등록하는 2가지 방법
    • 컴포넌트 스캔과 자동 의존관계 설정
    • @Autowired 같이 어노테이션 걸어주는 것
    • 자바 코드로 직접 스프링 빈 등록하기
  • 컴포넌트 스캔과 자동 의존관계 설정
    • @Component 어노테이션이 있으면 스프링 빈으로 자동등록된다.
    • @Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컨포넌트 스캔때문이다.
    • @Component 를 포함하는 다음 어노테이션도 스프링 빈으로 자동 등록된다.
      • @Controller
      • @Service
      • @Repository
  • 자바코드로 직접 스프링 빈 등록하기
    • SpringConfig 파일 만들고, @Configuration 어노테이션을 걸어준다
    • 그리고 내부 생성자 메소드 위에 @Bean 을 선언해준다
  • @Autowried 와 자바코드로 직접 주입 하는 것 중 아무래도 Autowired 가 편한다
    필드 주입 방식도 있지만 권장하진 않는다.
  • 회원 컨트롤러에 의존관계 추가
  • 회원 웹 기능 - 홈 화면 추가
    • HomeController 만들고 resource/template 에 home.html 을 만들어 연결해준다
  • 회원 웹 기능 - 조회
  • H2 데이터 베이스 설치
    • H2 데이터베이스 설치
      • 개발이나 테스트용도로 가볍고 편리한 DB, 웹 화면 제공
      • https://www.h2database.com/
      • h2 데이터베이스 버전은 스프링부트 버전에 맞춘다
      • 권한 chmod 755 h2.sh
      • 실행 ./h2.sh
      • 데이터베이스 파일 생성 방법
        • jdbc:h2:~/test (최초한번)
        • ~/test.mv,db 파일 생성 확인
        • 이후부터는 jdbc:h2:tcp://localhsot/~/test 이렇게 접속
    • 순수 JDBC
      • 스프링 통합 테스트
        • @SpringBootTest
          • 스프링 컨테이너와 테스트를 함께 실행한다.
        • @Transcational
          • 스프링 컨테이너에 이 어노테이션이 있으면, 테스트 시작 전에 트랜잭션을 시작하고 테스트 완료 후에 항상 롤백한다.
    • 스프링 JDBC Template
      • 순수 jdbc 와 동일한 환경설정을 하면된다
      • 스프링 jdbcTemplate과 Mybatis 같은 라이브러리는 JDBC API에서 본 반복코드를 대부분 제거해준다. 하지만 SQL은 직접 작성해야한다.
      • 추가로 생성자가 하나면 @Autowired 를 생략해서 사용할 수 있다.
    • JPA
      • JPA는 기존의 반복코드는 물론이고, 기본적인 SQL도 JPA가 직접 만들어서 실행해준다
      • JPA를 사용하면 SQL과 데이터 중심의 설꼐에서 객체 중심으로 설계로 패러다임을 전환을 할 수 있다.
      • JPA를 사용하면 개발 생산성을 크게 높일 수 있다.
      • build.gradle 에 jpa impliments 추가
      • application.properties 에 spring.jpa.show-sql=true 를 추가
      • application.properties 에 spring.jpa.hiberate.ddl-auto=none 추가
        • none 으로한 이유는 이미 테이블이 만들어져 있기 때문에
        • 도메인 클래스에 어노테이션을 걸어준다
          • @Id, @GeneratedValue(strategy = GenerationType.IDENTITY)
    • 스프링 데이터 JPA
      • 스프링부트와 JPA만 사용해도 개발 생산성이 정말 많이 증가하고, 개발해야할 코드도 확연히 줄어듭니다. 여기에 스프링 데이터 JPA를 사용하면, 기존의 한계를 넘어 마치 마법처럼, 리포지토리에 구현 클래스없이 인터페이스 만으로 개발을 완료할 수 있습니다.
      • 그리고 반복 개발해온 기본 CRUD 기능도 스프링 데이터 JPA가 모두 제공합니다.
      • 스프링부트와 JPA라는 기반 위에 스프링 데이터 JPA라는 환상적인 프레임워크를 더하면 개발이 정말 즐거워집니다.
      • 지금까지 조금이라도 단순하고 반복이라 생각했던 개발 코드들이 확연하게 줄어듭니다.
      • 따라서 개발자는 핵심 비즈니스 로직을 개발하는데 집중할 수 있습니다.
      • 실무에서 관계형 데이터베이스를 사용한다면 스프링 데이터 JPA는 이제 선택이 아니라 필수 입니다.
      • 스프링 데이터 JPA 제공 기능
        • 인터페이스를 통한 기본적인 CRUD 제공
        • findByName(), findByEmail() 처럼 메서드 이름 만으로 조회 기능 제공
        • 페이징 기능 자동 제공
        • 참고: 실무에서는 JPA와 스프링데이터 JPA를 기본으로 사용하고 복잡한 동적쿼리는 Querydsl 이라는 라이브러리를 사용하면 된다. Querydsl을 사용하면 쿼리도 자바 코드로 안전하게 작성할 수 있고, 동적 쿼리도 편리하게 작성할 수 있다. 이 조합으로 해결하기 어려운 쿼리는 JPA가 제공하는 네이티브 쿼리를 사용하거나 앞서 학습한 스프링 JdbcTemplate를 사용하면 된다.

AOP

  • AOP 가 필요한 상황
    • 모든 메소드의 호출 시간을 측정하고 싶다면?
    • 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern)
    • 회원 가입 시간, 회원 조회 시간을 측정하고 싶다면?
      • 코드를 일일이 넣자니…노동이다
      • 문제
        • 회원가입, 회원 조회에 시간을 측정하는 기능은 핵심 관심 사항이 아니다.
        • 시간을 측정하는 로직은 공통 관심 사항이다.
        • 시간을 측정하는 로직과 핵심 비즈니스의 로직이 섞여서 유지보수가 어렵다
        • 시간을 측정하는 로직을 별도의 공통 로직으로 만들기 매우 어렵다
        • 시간을 측정하는 로직을 변경할 때 모든 로직을 찾아가면서 변경해야한다.
  • AOP 적용
    • AOP: Aspect Oriented Programming
    • 공통관심사항 vs 핵심관심사항
    • SpringConfig 에 Bean 으로 등록해도 되고, Aop 활용 클래스에서 @Component 로 설정해줘도 된다.

사람들이 스프링을 쓰는 이유가 있을 테니…열심히 찾아봐야겠다.