[4기] 백엔드 개발자 부트캠프 "오르미" ~ing/[4기] 백엔드 개발자 부트캠프 오르미 수업 복습

[4기] 63일차 SpringBoot(디렉터리 구성 및 발전시키기)

sohee99 2024. 3. 4. 20:00

오늘의 학습 SpringBoot

 

 

출처 - 이스트소프트 조성연

 

각 계층이 양옆의 계층과 통신하는 구조! 

 

- 계층 : 각자의 역할과 책임이 있는 어떤 소프트웨어의 구성 요소 의미

 

 

생소 하지만 예를 들며 이해할려고 하니 이해가 쉽네영!!!

 

 

빵집과 카페가 있고 빵집과 카페가 협업을 맺어 어떤 손님이 커피를 샀을 경우, 빵을 할인한다. 

 

이 경우가 계층간의 소통 ( 빵집은 빵을 팔고 카페는 커피팔고 ! 각자의 역할과 책임 존재 ) 

 

but,  빵집에서 빵을 팔면서 카페에서 커피를 만들고 팔 수 없듯이 계층은 서로 영향을 끼치지 못한다! 

 

 

이렇듯 스프링부트는 프레젠테이션 계층, 비즈니스 계층, 퍼시스턴스 계층이 존재하며 이계층들은 서로 통신하며 프로그램을 구성한다! 

 

 

프레젠테이션 계층 

 

- HTTP요청을 받고 이 요청을 비즈니스 계층으로 전송하는 역할 / 컨트롤러가 바로 프레젠테이션 계층의 역할 

 

컨트롤러는 스프링부트내에 여러개 존재 가능 - xxxController라는 클래스명으로 이름을 짓는다.

 

 

비즈니스 계층

 

- 모든 비즈니스 로직을 처리한다. / xxxService라는 클래스명으로 이름을 짓는다.

 

( 비즈니스 로직 : 웹사이트에서 벌어지는 모든 작업, 예를 들어 주문서비스일 경우 주문 개수, 가격 등 데이터를 처리하기 위한 로직, 주문처리를 하다가 발생하는 예외 처리 로직, 주문을 받거나 취소하는 것 같이 프로세스를 구현하기위한 로직 

한마디로 서비스를 만들기 위한 로직 )

 

 

퍼시스턴스 계층

 

- 모든 데이터베이스 관련 로직을 처리

 

이 과정에서 데이터베이스에 접근하는 DAO객체를 사용할 수 있다. 

 

( DAO : 데이터베이스 계층과 상호작용하기 위한 객체 )

 

 

 

스프링 부트 프로젝트 디렉터리 구성

 

출처 - 이스트소프트 조성연

 

main : 실제 코드 작성 공간

 

- main 디렉터리는 java , resourcecs로 구성되어있다 내가 작성한 코드가 들어있는 디렉터리는 java!

 

 

> HTML 같은 뷰 관련 파일을 넣을 templates 디렉터리 생성

 

> JSM,CSS, 이미지와 같은 정적 파일을 넣을 static 디렉터리 생성 

 

test : 프로젝트의 소스코드를 테스트할 목적의 코드나 리소스파일

 

build.gradle : 빌드를 설정하는 파일 / 의존성이나 플러그인 설정 등과 같이 빌드에 필요한 설정 시 사용

 

settings.gradle : 빌드할 프로젝트의 정보를 설정하는 파일

 

 

 

마지막으로, 스프링부트 설정을 할 수 있는 application.properties 파일 생성

 

- 스프링 부트 서버가 실행되면 자동으로 로딩하는 파일

데이터베이스의 설정 정보, 로깅 설정 정보 등 들어갈 수 있으며 직접 설정을 정의할 때 사용하기도 한다. 

 

 

스프링 부트 프로젝트 발전시키기

 

예제를 통해 스프링부트 프로젝트를 조금 더 발전 시킴과 동시에 각 계층을 어떻게 나누는 지 알아보기!

 

STEP.1 build.grale 의존성 추가하기 

 

dependencies {
...
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    runtimeOnly 'com.h2database:h2'
    compileOnly 'org.projectlombok:lombok'
...
}

 

스프링 부트용 JPA인 스프링 데이터 JPA

로컬 환경과 테스트 환경에서 사용할 인메모리 데이터베이스인 H2

반복 메소드 작성 작업을 줄여주는 라이브러리인 롬복 추가 

 

 

STEP.2 프레젠테이션, 서비스, 퍼시스턴스 계층 만들기 

 

 

프레젠테이션 계층에속하는 MemberController 클래스 생성 

 

package com.example.hellospring.controller;

import com.example.hellospring.service.MemberService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class MemberController {

    private final MemberService memberService;

    public MemberController(MemberService memberService) {  // 빈 주입
        this.memberService = memberService;
    }

    @GetMapping("/members")
    public List<MemberDTO> getAllMembers() {
        return memberService.getAllMembers();
    }
}

 

 

비즈니스 계층인 MemberService 파일 생성 

 

package com.example.hellospring.service;

import com.example.hellospring.controller.Member;
import com.example.hellospring.controller.MemberDTO;
import com.example.hellospring.repository.MemberRepository;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class MemberService {
    private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {   // 빈 주입
        this.memberRepository = memberRepository;
    }

    public List<MemberDTO> getAllMembers() {
        List<Member> memberList = memberRepository.findAll();            // 멤버 목록 얻기

        List<MemberDTO> resultList = memberList.stream()            // MemberDTO로 변환하여 return
                .map(member -> new MemberDTO(member.getId(), member.getName())).toList();
        return resultList;
    }
}

 

출처 - 이스트소프트 조성연

 

비즈니스 계층까지를 그림으로 표현

 

 

퍼시스턴트 계층 구조 작성

 

DB에 접근할 때 사용할 객체인 Member DAO를 생성하고 실제 DB에 접근하는 코드를 작성 / Member.java 파일 생성

 

package com.example.hellospring.controller;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class MemberDTO {
    private Long id;
    private String name;
}

 

package com.example.hellospring.controller;

import jakarta.persistence.*;
import lombok.Getter;

@Getter
@Entity
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false)
    private Long id;       // DB 테이블의 id와 컬럼 매칭

    @Column(name = "name", nullable = false)
    private String name;    // DB 테이블의 name과 컬럼 매칭
}

 

매핑작업으로 인터페이스 파일 생성 MemberRepository.java 


@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {

}

 

- DB에서 데이터를 가져오는 퍼시스턴트 계층 역할 

 

작동 확인하기

 

- 보통 이런 실행 테스트를 하기 위해 애플리케이션을 실행할 때 마다

SQL문을 실행해 데이터베이스에 직접 데이터를 넣는다.

 

h2를 사용하고 있을 시, 애플리케이션을 새로 실행할 때마다 데이터가 사라져 매우 불편하기에 이를 해결하기 위해 애플리케이션을 실행 할 때 원하는 데이터를 자동으로 넣는 작업 진행

 

STEP.1 데이터를 넣을 SQL 파일 생성 

 

- 애플리케이션이 실행 될 때 저장할 더미 데이터를 넣을 SQL 파일 생성 

( resources 디렉터리에 data.sql 파일 생성 )

 

INSERT INTO member (id, name) VALUES (1, 'name1');
INSERT INTO member (id, name) VALUES (2, 'name2');
INSERT INTO member (id, name) VALUES (3, 'name3');

 

STEP.2  application.properties 파일 코드 변경

 

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.defer-datasource-initialization=true

 

show-sql, format_sql : 애플리케이션 실행 과정에 데이터베이스에 쿼리할 일이 있으면 실행 구문을 모두 보여주는 옵션

defer-datasource-initialization 옵션은 애플리케이션을 실행할 때 테이블을 생성하고 data.sql 파일에 있는 쿼리를 실행하도록 하는 옵션

 

 

이렇게 애플리케이션을 실행하면?

 

 

쿼리문이 출력된다!

 

컨트롤러를 호출해보면!

 

 

브라우저에서 localhost:8080/members 로 직접 호출할 수 있으며,

 

postman으로 HTTP 요청을 날려 확인하는 방법도 있다.

 

 

요청-응답 과정

 

출처- 이스트소프트 조성연

 

1. 포스트맨에서 톰캣에 HTTP GET 요청 > 스프링 컨테이너 이동

 

2. DispatcherServlet이 URL 분석 > 요청을 처리할 수 있는 컨트롤러를 찾는다. 

MemberController 가 /members라는 패스에 대한 get요청을 처리할 수 있는 getAllMembers() 메소드를 

가지고 있으므로 컨트롤러에게 get 요청

 

3. /members GET 요청을 처리할 수 있는 getAllMembers() 메소드와 요청이 매치그리고,  getAllMembers() 메소드에서 비즈니스 게층과 퍼시스턴스 계층을 통해 필요데이터 가져온다.

 

4. 뷰 리졸버는 템플릿 엔진을 사용해 HTML 문서를 만들거나 JSON,XML 등의 데이터를 생성한다.

 

5. members를 return하고 데이터를 포스트맨에서 볼 수 있다.

 

 

이렇게 오늘은 스프링 부트에 대해 공부했는데엽!!!!

 

이해하는건 쉽지만 코드 작성할 때마다 막히는건 아직 어쩔 수 없네요 ㅠㅠㅠㅠ

 

스프링 봄아니야 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ 겨울이야 겨울 ㅠㅠㅠㅠㅠㅠㅠㅠㅠ

 

열심히 해봅시다 ㅜㅜㅜㅜ 언젠가 봄이 될때 까지,,, 꾸준히,,,,

 

 

오늘도 열심히 배웠고!!!!

 

내일도 공부 파이팅!!!!!!!!!