Spring Master 1주차 정리

김엄지·2024년 2월 25일
0

Spring

목록 보기
6/21

이해하면서 정리하기

목차

개념 정리

00. 프로젝트 생성하기
01. 그래이들(Gradle)이란 무엇일까?
02. 서버란 무엇일까?
03. http란 무엇일까?
04. 테스트 코드
05. Lombok과 application.properties
06. MySQL

Spring MVC

07. Spring MVC란 무엇일까?
08. Controller
09. 정적 페이지와 동적 페이지
10. 데이터를 Client에 반환하는 방법
11. Jackson이란 무엇일까?
12. Path Variable과 Request Param
13. http 데이터를 객체로 처리하는 방법

메모장

14. Create, Read 구현하기
15. Update, Delete 구현하기

Database와 SQL

16.Database
17.SQL
18. JDBC란 무엇일까?

프로젝트 생성하기

Spring Initializr

Create Git repositoty 체크
(체크 못할 경우, 메뉴>VCS>Create Git repositoty)
Language : Java
Type : Gradle - Groovy
JDK : zulu-17
Java : 17

Dependencies 추가

Spring Web
Lombok
Thymeleaf

Gradle이란?

빌드 자동화 시스템. 작성한 Java 코드를 설정에 맞게 자동으로 Build 해준다(코드 실행 가능한 jar 파일로 만들어줌).
(Build란 소스 코드를 실행 가능한 결과물로 만드는 일련의 과정)

build.gradle은 Gradle 기반의 빌드 스크립트이다. 이 스크립트를 작성하면 소스 코드를 빌드하고 라이브러리들의 의존성을 쉽게 관리할 수 있다. groovy 혹은 kotlin 언어를 사용한다.

dependencies에 외부 라이브러리들을 작성하면, 외부 저장소에서 자동으로 다운로드해준다.

External Libraries에서 Gradle이 다운로드해온 라이브러리들을 확인할 수 있다.

서버란?

사용자가 요청을 했을 때 해당 요청에 대한 응답을 수행하는 프로그램. 즉 서버이다.
네트워크에서도 정보를 요청 받고 전달하려면 주소에 해당하는 IP 와 받는 사람에 해당하는 포트번호를 알려줘야한다.

웹서버란?

HTTP를 이용하여 웹상의 클라이언트의 요청을 응답해주는 통신을 하는 일종의 컴퓨터이다.

  1. 브라우저를 통해 HTTP Request로 웹사이트를 웹서버에 요청합니다.
  2. 이후 웹서버는 요청을 승인하고 HTTP Response를 통해 웹사이트 데이터를 브라우저에 전송합니다.
  3. 마지막으로 브라우저는 서버에서 받아온 데이터를 이용해 웹사이트를 브라우저에 그려내는 일을 합니다.
  • 기본적으로 브라우저가 웹서버에 요청을 할때는 항상 GET method로 요청하게 됩니다.

API란?

API(application programming interface)는 다른 소프트웨어 시스템과 통신하기 위해 따라야 하는 규칙이다.
개발자는 다른 애플리케이션이 프로그래밍 방식으로 애플리케이션과 통신할 수 있도록 API를 표시하거나 생성한다.
RESTful 하게 설계되었다는 것은 서버의 api가 적절하게 http를 준수하며 잘 설계된 것이다.

Apache Tomcat란?

  • Web Server의 역할은 크게 2가지로 구분된다.
  1. 정적인 콘텐츠 (이미 완성 된 HTML 문서)를 브라우저로 전달.
  2. 동적인 요청이 들어오면 -> 요청을 WAS에 전달.
    종류로는 Apache, Nginx 등이 있다.
  • WAS는 웹 서버와 똑같이 HTTP 기반으로 동작된다.
    종류로는 Tomcat, JBoss 등이 있다.

  • Apache + Tomcat이 합쳐진 형태로 정적인 데이터 처리와 동적인 데이터 처리를 효율적으로 해줄 수 있다.

Spring 프레임워크는 AOP, IoC/DI 등과 같은 핵심 기능들을 가지고 있지만, 가능을 사용하려면 많은 xml 설정들이 필요하다.

이 점을 개선하고자 SpringBoot가 등장했다.

  • Java의 애너테이션 기반의 설정으로 간편하게 설정할 수 있다.
  • 기본적으로 개발에 필요한 설정 값을 default로 하여 자동으로 설정해주고 있다.
  • 외부 라이브러리나 하위 프레임워크들의 의존성 관리가 매우 쉬워졌다.
  • 내장 Apache Tomcat 제공한다.

http란 무엇일까?

HTTP(HyperText Transfer Protocol)는 데이터를 주고 받는 양식을 정의한 "통신 규약"중 하나이다. 현재 이용되는 대부분의 웹 서버가 HTTP를 기반으로 정해준 규칙에 맞게 데이터를 주고 받는다.

우리는 어떻게 HTTP로 데이터를 주고 받을까?

  1. 브라우저는 서버에게 자신이 원하는 페이지(URL 등의 정보)를 요구(Request)합니다.
  2. 서버는 브라우저가 원하는 페이지가 있는지 확인하고, 있다면 해당 페이지에 대한 데이터를 실어 응답(Response)해줍니다. 없다면 없는 페이지에 대한 데이터를 반환합니다.
  3. 브라우저는 서버에게 전달 받은 데이터를 기반으로 브라우저에 그려줍니다.

HTTP 호출/요청 방식 메서드이 있다. 따로 적어둔 페이지를 확인해보자.
링크텍스트

테스트 코드

  • 자바 프로그래밍 언어 용 단위 테스트 프레임워크인 JUnit를 사용해 테스트 코드 가능하다.
  • build.gradle 파일에 이미 JUnit 사용을 위한 환경설정이 되어있다.
  • .java 파일내에서 우클릭 > Generate > Test > 기본세팅 그래도 OK > 자동으로 경로를 맞춰서 Test 파일이 생성된 것을 볼 수 있다.
  • JUnit은 main() 메서드를 실행하거나 서버를 실행시키지 않아도 메서드 혹은 기능별로 테스트할 수 있다.

Lombok과 application.properties

Lombok(롬복)이란?

메서드/생성자 등을 자동 생성해주는 라이브러리이다.
클래스 위에 롬복 @Getter를 추가한 후 컴파일된 코드를 확인해보면 이처럼 직접 작성하지 않은 getUsername(), getContents() 메서드가 자동 추가된다.

application.properties란?

  • Spring과 관련된 설정을 할 때 사용되는 파일이다.
  • 이 파일을 사용하면 자동으로 설정되고 있는 설정 값을 쉽게 수정할 수 있다.
  • DB 연결 시 DB의 정보를 제공도 쉽게 값을 전달할 수 있다.

MySQL

MySQL Command Line Client 접속 > 비밀번호 입력 > 접속 완료
데이터베이스 생성 > CREATE DATABASE 데이터베이스이름적기;
데이터베이스 확인 > show databases;
데이터베이스 사용 > use academy;
환경 변수 설정

Spring MVC란 무엇일까?

MVC란 Model-View-Controller의 약자로, 소프트웨어 디자인 패턴 중 하나이다.

  • Spring에서 MVC 디자인 패턴을 적용하여 HTTP 요청을 효율적으로 처리한다.

  • MVC에 관해 정리한 포스팅 링크텍스트

  • 사용자가 (HTTP) API 요청했을 때 서버의 서블릿 동작 원리

  1. 사용자가 Client(브라우저)를 통해 서버에 HTTP Request 즉, API 요청을 합니다.
  2. 요청을 받은 Servlet 컨테이너는 HttpServletRequest, HttpServletResponse 객체를 생성합니다.
    • 약속된 HTTP의 규격을 맞추면서 쉽게 HTTP에 담긴 데이터를 사용하기 위한 객체입니다.
  3. 설정된 정보를 통해 어떠한 Servlet에 대한 요청인지 찾습니다.
  4. 해당 Servlet에서 service 메서드를 호출한 뒤 브라우저의 요청 Method에 따라 doGet 혹은 doPost 등의 메서드를 호출합니다.
  5. 호출한 메서드들의 결과를 그대로 반환하거나 동적 페이지를 생성한 뒤 HttpServletResponse 객체에 응답을 담아 Client(브라우저)에 반환합니다.
  6. 응답이 완료되면 생성한 HttpServletRequest, HttpServletResponse 객체를 소멸합니다.

Controller

유사한 성격의 API 를 하나의 Controller 로 관리한다.
@Controller는 해당 클래스가 Controller의 역할을 수행할 수 있도록 등록해줄 수 있다.

@Controller
public class HelloController {
    @GetMapping("/api/hello")
    @ResponseBody
    public String hello() {
        return "Hello World!";
    }
}

@RequestMapping은 중복되는 URL를 단축시켜줄 수 있다.

정적 페이지와 동적 페이지

SpringBoot 서버에 html 파일을 바로 요청하면 해당 html 파일을 static 폴더에서 찾아서 반환해 준다.
다시 공부하기.

데이터를 Client에 반환하는 방법

JSON 데이터 반환하는 방법

  • 템플릿 엔진이 적용된 SpringBoot에서는 Controller에서 문자열을 반환하면 templates 폴더에서 해당 문자열의 .html 파일을 찾아서 반환해준다.
  • JSON 데이터를 브라우저에 반환하고 싶다면 해당 메서드에 @ResponseBody 애너테이션을 추가해줘야한다.

1) 반환값: String
Java는 JSON 타입을 지원하지 않기 때문에 JSON 형태의 String 타입으로 변환해서 사용해야 한다.

@GetMapping("/response/json/string")
**@ResponseBody**
public String helloStringJson() {
    return "{\"name\":\"Robbie\",\"age\":95}";
}

2) 반환값: String 외 자바 클래스
Spring에서 자동으로 Java의 객체를 -> JSON으로 변환해준다.

@GetMapping("/response/json/class")
**@ResponseBody**
public Star helloClassJson() {
    return new Star("Robbie", 95);
}

Jackson이란 무엇일까?

Jackson은 JSON 데이터 구조를 처리해주는 라이브러리이다.
객체 -> JSON 타입의 String으로 변환
JSON 타입의 String -> 객체로 변환

Spring은 3.0버전 이후로 Jacskon과 관련된 API를 제공함으로써, 우리가 직접 소스 코드를 작성하여 JSON 데이터를 처리하지 않아도 자동으로 처리해주고 있다.

  • 따라서 SpringBoot의 starter-web에서는 default로 Jackson 관련 라이브러리들을 제공하고 있다.

  • 직접 JSON 데이터를 처리해야할 때는 Jackson 라이브러리의 ObjectMapper를 사용할 수 있다.

  • Object To JSON

@Test
@DisplayName("Object To JSON : get Method 필요")
void test1() throws JsonProcessingException {
    Star star = new Star("Robbie", 95);

    ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper
    String json = objectMapper.writeValueAsString(star);

    System.out.println("json = " + json);
}
  • JSON To Object
@Test
@DisplayName("JSON To Object : 기본 생성자 & (get OR set) Method 필요")
void test2() throws JsonProcessingException {
    String json = "{\"name\":\"Robbie\",\"age\":95}"; // JSON 타입의 String

    ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper

    Star star = objectMapper.readValue(json, Star.class);
    System.out.println("star.getName() = " + star.getName());
}

Path Variable과 Request Param

브라우저에서 서버로 HTTP 요청 방식

  • Path Variable 방식 : 서버에 보내려는 데이터를 URL 경로에 추가
// [Request sample]
// GET http://localhost:8080/hello/request/star/EOMJI/age/99

@GetMapping("/star/{name}/age/{age}")
@ResponseBody
public String helloRequestPath(@PathVariable String name, @PathVariable int age)
{
    return String.format("Hello, @PathVariable.<br> name = %s, age = %d", name, age);
}
  • Request Param 방식 : 서버에 보내려는 데이터를 URL 경로 마지막에 ? 와 & 를 사용하여 추가
// [Request sample]
// GET http://localhost:8080/hello/request/form/param?name=EOMJI&age=99

@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam String name, @RequestParam int age) {
    return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}

http 데이터를 객체로 처리하는 방법

공부하기

Create, Read 구현하기

DTO(Data Transfer Object)란?


데이터 전송 및 이동을 위해 생성되는 객체를 의미한다.

  • Client에서 보내오는 데이터를 객체로 처리할 때 사용
  • 서버의 계층간의 이동에도 사용
  • DB와의 소통을 담당하는 Java 클래스를 그대로 Client에 반환하는 것이 아니라 DTO로 한번 변환한 후 반환할 때도 사용
    - RequestDto : Request의 데이터를 처리할 때 사용되는 객체
    • ResponseDto : Response를 할 때 사용되는 객체

Create 구현

  1. 메모 데이터를 저장할 Memo 클래스 생성
  2. 메모 생성하기 API를 받을 수 있는 Controller와 메서드 생성
  3. Client에 데이터를 반환할 때 사용할 MemoResponseDto 클래스 생성
  4. Client의 요청 데이터를 받아줄 MemoRequestDto 클래스 생성
  5. DB와 연결을 하지 않았기 때문에 메모 데이터를 저장할 Java 컬렉션 생성
  6. 메모 생성 로직 작성

Read 구현

  1. DB 역할을 하는 memoList를 조회하여 List로 변환한 후 반환
package com.sparta.memo.controller;

import com.sparta.memo.dto.MemoRequestDto;
import com.sparta.memo.dto.MemoResponseDto;
import com.sparta.memo.entity.Memo;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api")
public class MemoController {

    private final Map<Long, Memo> memoList = new HashMap<>();

    @PostMapping("/memos")
    public MemoResponseDto createMemo(@RequestBody MemoRequestDto requestDto) {
        // RequestDto -> Entity
        Memo memo = new Memo(requestDto);

        // Memo Max ID Check
        Long maxId = memoList.size() > 0 ? Collections.max(memoList.keySet()) + 1 : 1;
        memo.setId(maxId);

        // DB 저장
        memoList.put(memo.getId(), memo);

        // Entity -> ResponseDto
        MemoResponseDto memoResponseDto = new MemoResponseDto(memo);

        return memoResponseDto;
    }

    @GetMapping("/memos")
    public List<MemoResponseDto> getMemos() {
        // Map To List
        List<MemoResponseDto> responseList = memoList.values().stream()
                .map(MemoResponseDto::new).toList();

        return responseList;
    }
}

Update, Delete 구현하기

Update 구현

Delete 구현

package com.sparta.memo.controller;

import com.sparta.memo.dto.MemoRequestDto;
import com.sparta.memo.dto.MemoResponseDto;
import com.sparta.memo.entity.Memo;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api")
public class MemoController {

    private final Map<Long, Memo> memoList = new HashMap<>();

    @PostMapping("/memos")
    public MemoResponseDto createMemo(@RequestBody MemoRequestDto requestDto) {
        // RequestDto -> Entity
        Memo memo = new Memo(requestDto);

        // Memo Max ID Check
        Long maxId = memoList.size() > 0 ? Collections.max(memoList.keySet()) + 1 : 1;
        memo.setId(maxId);

        // DB 저장
        memoList.put(memo.getId(), memo);

        // Entity -> ResponseDto
        MemoResponseDto memoResponseDto = new MemoResponseDto(memo);

        return memoResponseDto;
    }

    @GetMapping("/memos")
    public List<MemoResponseDto> getMemos() {
        // Map To List
        List<MemoResponseDto> responseList = memoList.values().stream()
                .map(MemoResponseDto::new).toList();

        return responseList;
    }

    @PutMapping("/memos/{id}")
    public Long updateMemo(@PathVariable Long id, @RequestBody MemoRequestDto requestDto) {
        // 해당 메모가 DB에 존재하는지 확인
        if(memoList.containsKey(id)) {
            // 해당 메모 가져오기
            Memo memo = memoList.get(id);

            // memo 수정
            memo.update(requestDto);
            return memo.getId();
        } else {
            throw new IllegalArgumentException("선택한 메모는 존재하지 않습니다.");
        }
    }

    @DeleteMapping("/memos/{id}")
    public Long deleteMemo(@PathVariable Long id) {
        // 해당 메모가 DB에 존재하는지 확인
        if(memoList.containsKey(id)) {
            // 해당 메모 삭제하기
            memoList.remove(id);
            return id;
        } else {
            throw new IllegalArgumentException("선택한 메모는 존재하지 않습니다.");
        }
    }
}

Database

Database란?

데이터의 집합 즉, 전자적으로 저장되고 체계적인 데이터 모음이다.

DBMS, RDBMS 용어 정리

  • DBMS 는 ‘Database Management System’ 의 약자로 Database를 관리하고 운영하는 소프트웨어이다.

  • RDBMS는 ‘Relational DBMS’의 약자로 관계형 데이터베이스이다.

  • RDBMS는 테이블(table)이라는 최소 단위로 구성되며, 이 테이블은 열(column)과 행(row)으로 이루어져 있다.

  • 테이블간 FK(Foreign Key)를 통해 다른 데이터를 조합해서 함께 볼수 있다라는 장점이 있다.

  • RDBMS 종류로는 MySQL, PostgreSQL 등이 있다.

SQL

SQL란?

Structured Query Language로 RDBMS에서 사용되는 언어이다. 수 많은 정보를 Database에서 조작하고 관리하기 위해서는 SQL 언어를 사용해야한다.

DDL

Data Definition Language로 테이블이나 관계의 구조를 생성하는데 사용한다.

  • CREATE : 새로운 데이터베이스 및 테이블을 생성해준다.
  • ALTER : 데이터베이스와 테이블의 내용을 수정할 수 있다.
  • DROP : 데이터베이스와 테이블을 삭제할 수 있다. 데이터 및 테이블 전체를 삭제한다.
  • TRUNCATE : 데이터베이스와 테이블을 삭제할 수 있다. 최초 테이블이 만들어졌던 상태 즉, 컬럼값만 남긴다.

DCL

Data Control Language 데이터의 사용 권한을 관리하는데 사용한다.

  • GRANT : 사용자 또는 ROLE에 대해 권한을 부여할 수 있다.
  • REVOKE : 사용자 또는 ROLE에 부여한 권한을 회수할 수 있다.

DML

Data Manipulation Language로 테이블에 데이터를 검색, 삽입, 수정, 삭제하는데 사용한다.

  • INSERT : 테이블에 새로운 row를 추가할 수 있다.
  • SELECT : 테이블의 row를 선택할 수 있다.
  • UPDATE : 테이블의 row의 내용을 수정할 수 있다.
  • DELETE : 테이블의 row를 삭제할 수 있다.

CREATE 제약조건

  • AUTO_INCREMENT : 컬럼의 값이 중복되지 않게 1씩 자동으로 증가하게 해줘 고유번호를 생성해 준다.

    CREATE TABLE 테이블이름
    (
        필드이름 필드타입 AUTO_INCREMENT,
        // id bigint AUTO_INCREMENT,
    );
  • NOT NULL : 해당 필드는 NULL 값을 저장할 수 없게 된다.

    CREATE TABLE 테이블이름
    (
        필드이름 필드타입 NOT NULL,
    );
  • UNIQUE : 해당 필드는 서로 다른 값을 가져야만 한다

    CREATE TABLE 테이블이름
    (
        필드이름 필드타입 UNIQUE,
    );
  • PRIMARY KEY : 해당 필드가 NOT NULL과 UNIQUE 제약 조건의 특징을 모두 가지게 된다.
    중복된 데이터가 테이블에 삽입되는 것을 방지하는 제약조건이다.

    CREATE TABLE 테이블이름
    (
        필드이름 필드타입 PRIMARY KEY,
    );
  • FOREIGN KEY : 하나의 테이블을 다른 테이블에 의존하게 만들며 데이터의 무결성을 보장해 준다.

    • FK 를 가지는 테이블이 참조하는 기준 테이블의 열은 반드시 PK, UNIQUE 제약조건이 설정되어 있어야 한다.
    • 외래 키는 두개의 테이블을 연결하는 다리 역할을 해주는 키이다.
    CREATE TABLE 테이블이름
    (
        필드이름 필드타입,
            FOREIGN KEY(필드이름)
        REFERENCES 테이블이름(필드이름)
    );
  • CASCADE : FOREIGN KEY 로 연관된 데이터를 삭제,변경할 수 있다.

    CREATE TABLE 테이블이름
    (
        필드이름 필드타입,
            FOREIGN KEY(필드이름)
        REFERENCES 테이블이름(필드이름) ON DELETE CASCADE 
    //ON UPDATE CASCADE
    );

    CREATR, ALTER, INSERT, UPDATE, DELETE, SELECT, JOIN

  • JOIN은 나누어진 테이블을 하나로 합치기 위해 데이터베이스가 제공하는 기능이다.

    • JOIN 은 ON 이라는 키워드를 통해 기준이 되는 컬럼을 선택하여 2개의 테이블을 합쳐 준다.
    • JOIN을 할 때에는 적어도 하나의 컬럼을 서로 공유하고 있어야 하기 때문에 테이블에 외래 키가 설정 되어 있다면 해당 컬럼을 통해 JOIN을 하면 조건을 충족할 수 있다.

JDBC란 무엇일까?

애플리케이션 서버와 데이터베이스는 어떻게 소통할까?

기존에 사용하던 MySQL 서버를 PostgreSQL 서버로 변경한다면 무슨일이 발생할까?
이러한 문제를 해결하기위해 JDBC 표준 인터페이스가 등장했다.

JDBC란?

Java Database Connectivity로 DB에 접근할 수 있도록 Java에서 제공하는 API이다.
DB의 JDBC 드라이버를 제공하면 DB 연결 로직을 변경할 필요없이 DB 변경이 가능하다.


JDBC의 등장으로 손쉽게 DB교체가 가능해졌지만 아직도 DB에 연결하기 위해 여러가지 작업 로직들을 직접 작성해야한다는 불편함이 있었고,
반복적이고 중복되는 작업들을 대신 처리해주는 JdbcTemplate이 등장한다.

JdbcTemplate이 사용방법

  1. application.properties에 DB에 접근하기 위한 정보를 작성
  2. build.gradle에 JDBC 라이브러리와 MySQL을 등록
  3. DB연결이 필요한 곳에서 JdbcTemplate을 주입받아와 사용
    • 생성자의 파라미터를 통해 JdbcTemplate 객체가 자동으로 넘어와 jdbctemplate 변수에 저장된다.

Jdbc 사용법 링크텍스트


다음주 내용
Java 개발자들을 위해 DB와 객체를 매핑하여 소통할 수 있는 ORM이라는 기술이 등장하게 된다.

profile
나만의 무언가를 가진 프로그래머가 되자

0개의 댓글