스프링 정리 2

임선구·2일 전

3.데이터베이스 접근 방법(JPA)

01. JPA(Java Persistence API)

JPA(Java Persistence API) 는 자바에서 ORM을 위한 표준 명세 입니다.

a. ORM(Object Relational Mapping)

데이터베이스를 Object로 다루는 기술입니다. 자바에서는 Object 는 객체를 의미합니다.

b. 다양한 JPA 구현체

JPA 를 실제로 동작하게 하는 여러 구현체가 있습니다. 스프링부트에서 어떤 구현체를 사용할지 개발자가 결정할 수 있지만 기본적으로 Hibernate 구현체를 사용하고 있습니다.

02. JPA 가 SQL 을 실행하는 과정

JPA 로 편하게 DB 를 조작하는 것은
DB 에 SQL 을 보내는 과정을 편하게 만든 것입니다.
→ 실제로 DB 에 SQL 을 보내는 것은 JDBC 가 담당하게 됩니다.

JDBC(Java Database Connectivity)

  • 자바와 DB 사이의 통신 규약(인터페이스)입니다.
  • 구현체는 DB-driver(mysql, mariadb, 등) 가 담당합니다.

03. JPA 핵심 키워드 & 동작원리

⭐ a. EntityManagerFactory


EntityManagerFactory 는 DB 연결에 필요한 모든 세팅을 미리 해놓습니다.
그리고 요청이 들어오면 EntityManager 생성에 사용됩니다.


⭐ b. EntityManager


EntityManager 는 DB 에 저장, 조회, 수정, 삭제하는 작업자 입니다.

  • *Transaction 단위로 생성됩니다.

⭐ c. 엔티티

데이터베이스의 테이블 구조를 그대로 표현하는 역할을 가진 객체입니다.

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    
    private String author;
}

⭐ d. 영속성 컨텍스트

엔티티의 정보를 메모리에서 관리하는 임시 저장소. 데이터를 반영하기전 변경사항을 모두 기록합니다. 트랜잭션이 끝나면 모든 변경사항을 DB 에 반영합니다.


class Service {

		// 트랜잭션 시작
		@Transactional 
		public void doService() {

				// 1. 데이터 조회, 생성, 수정, 삭제 
				// ...
				// ...
		}
    // 트랜잭션 끝
}

i. 엔티티의 상태

ii. 영속성 컨텍스트의 4가지 특징
1. 1차 캐싱

Book a = em.find(Book.class, "의문의책A"); // SELECT * FROM books WHERE id = '의문의책A'
Book b = em.find(Book.class, "의문의책A"); // SELECT 쿼리 발생 X (1차 캐시 사용)
  1. 동일성 보장
Book a = em.find(Book.class, "의문의책A");
Book b = em.find(Book.class, "의문의책A");

// 동일성 비교 true (같은 객체 반환)
System.out.println(a == b);
  1. 쓰기 지연
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();

//데이터 변경시 트랜잭션을 시작
transaction.begin(); // 트랜잭션 시작

em.persist(bookA); // (1) INSERT ...
em.persist(bookB); // (2) INSERT ...

// 쓰기지연은 persist 호출시 SQL 이 바로 실행되지 않습니다.
// (1, 2 의 sql 을 모았다가 보낸다.)
trasnaction.commit(); 트랜젝션 커밋
  1. 변경감지
--> 트랜잭션 시작

// 영속
Book findBook = em.find(Book.class, "채식주의자");
findBook.setName("소년이온다");

// persist 호출 불필요합니다.
// 변경된 속성은 트랜잭션 커밋 시 자동 반영 됩니다.
// em.persist(findBook);

--> 트랜잭션 끝

⭐ 요약

EntityManager 는 실제로 엔티티를 DB 에 저장, 조회, 수정, 삭제하는 작업자입니다.

EntityManagerFactory 는 DB 에 연결에 필요한 모든 세팅을 미리 해놓고 EntityManager 생성에 사용됩니다.

EntityManagerFactory 는 애플리케이션 시작시 딱 한번 만들어지고 애플리케이션이 종료될때까지 유지됩니다.

EntityManagerFactory 를 만들려면 DataSource 가 정상적으로 생성되어야합니다.

EntityManager 는 EntityManagerFactory 로부터 생성되며 Transaction 단위로 생성되고 종료됩니다.

영속성컨텍스트 는 엔티티를 메모리에서 관리하는 임시 저장소입니다.


4. 인증인가 기초(쿠키, 세션, 토큰)

⭐ 01. 인증인가

a. 인증(Authentication)

누구인가 확인하는 단계

b. 인가(Authorization)

자격을 확인하는 단계

⭐ 02. 쿠키

브라우저의 저장공간

쿠키인증의 한계

⭐ 03. 세션

클라이언트와 서버의 연결을 나타내는 하나의 상태

세션의 한계

⭐ 04. 토큰

의미 있는 불규칙한 문자열

토큰인증방식의 한계

암호화가 아닙니다 - 단순한 문자열(Base64 적용)

⭐ 요약


5. 연관관계

⭐ 01. 데이터베이스 모델링

어떤 서비스를 만들 때 필요한 데이터들을 정리하고 구조화하는 작업(테이블 명세 + ERD)

연관관계

객체(엔티티) 가 서로 연결되어 있는 모습을 연관관계 라고 합니다. (JPA 와 다른 ORM 에서 사용하는 용어).

a. 연관관계 주인
b. 부모-자식 관계
c. 단방향과 양방향 연관관계

⭐ a. 연관관계 주인

연관관계가 있는 테이블 사이에서
물리적으로 다른테이블의 외래키를 소유하고 있는 테이블/엔티티를 연관관계의 주인이라고 표현합니다.


⭐ b. 부모 - 자식 관계

비즈니스 관점에서 한 도메인이 다른 도메인을 포함하는 논리적인 관계를 의미합니다.

  • 부모: 포함하고 있는 도메인
  • 자식: 포함되는 도메인

수강생은 연관관계 부모-자식 관계에서 자식 이다.

수업은 연관관계 부모-자식 관계에서 부모 이다.

연관관계 정리

⭐ i. 단방향

한쪽에서만 다른 엔티티를 참조하는 상황 (@ManyToOne)

⭐ ii. 양방향

엔티티(객체) 들이 서로 참조하는 상황(@OneToMany)

cascadeType 그리고 orphanRemoval

양방향 연관관계를 더 멋지게? 사용하는 방법

a. cascadeType

양방향 연관관계(@OneToMany) 에서 부모 엔티티를 PERSIT 하거나 REMOVE할때 연관된 자식 엔티티에게도 그 작업을 자동으로 적용할지 결정하는 설정

b. orphanRemoval

부모와의 연관관계가 끊겨 있는 엔티티를 자동으로 삭제할지 결정하는 기능
→ 부모 없는 엔티티 → 고아(orphan) 이라고 표현합니다.

c. 조합 정리(cascadeType + orphanRemoval)

⭐ 05. 양방향 연관관계의 위험성

양방향 연관관계 사용시 객체의 상태가 양쪽에 존재하기 때문에 어떤 값을 DB 에 반영해야하는지 JPA 가 자동으로 판단할 수 없는 모호한 상황이 발생할 수 있습니다.

실무는 대부분 단방향


6. 스프링의 예외처리 원리

01. 예외 처리 복습

예외 처리 라고 하는 것은 크게 두가지로 나누어져 있습니다.

예외 처리
1. 직접 처리
2. 전파 후 처리(책임전가)

예외 종류

a. 체크예외(Exception)

  • RuntimeException 을 제외한 Exception 클래스를 상속받은 모든 하위 클래스
  • 반드시 명시적으로 예외를 처리해야합니다.
  • 컴파일러가 컴파일 단계에서 검사해줍니다.

b. 언체크예외(UncheckedException)

  • RuntimeException 클래스를 상속 받은 모든 하위 예외 클래스
  • 처리방식은 똑같지만 예외처리를 강제하지 않습니다.
  • 컴파일 단계에서 검사해주지 않습니다.

정리

⭐ 4. 논의 - 언제 check / unchecked 를 사용해야할까?

프로그램 실행 흐름안에서 직접 처리시 복구가능성이 있는 상황이라면 checked 그렇지 않다면 unchecked 를 사용합니다.


⭐ 스프링 예외처리 흐름

예외가 발생하면 /error 경로로 BasicErrorController 를 호출해서 에러 응답 본문을 만들어줍니다.

예외처리 흐름 살펴보기 - 필터

a. 필터

스프링필터는 WAS 와 DispatcherServlet 사이에 위치합니다. 이 위치 덕분에 모든 요청 응답에 대한 공통작업(보안검사, 요청/응답 기록 등) 처리에 적합한 역할을 합니다.

⭐ 05. ExceptionResolver

스프링은 3가지 resolver 를 활용해 예외처리시 사용할 상태코드, 에러메시지 등을 미리 설정합니다.

스프링에서 예외가 발생했을때 c → b → a 순차적으로 예외를 처리하려고 시도합니다.

  1. DefaultHandlerExceptionResolver
  2. ResponseStatusExceptionResolver
  3. *(현업사용) ExceptionHandlerExceptionResolver

1. DefaultHandlerExceptionResolver

  • 스프링에서 기본적으로 정의해놓은 표준 예외(메시지, 상태코드)를 처리하는 resolver 입니다.
  • BasicErrorController 통해서 예외를 처리합니다.
  • 파일참고: DefaultHandlerExceptionResolver.java 참고

2. ResponseStatusExceptionResolver

  • @ResponseStatus 로 설정한 예외를 처리하는 resolver 입니다.
  • BasicErrorController 통해서 예외를 처리합니다.

⭐ c. ExceptionHandlerExceptionResolver

커스텀하게 특정 예외에 상태코드, 메시지, 응답 본문을 만들어 줄 수 있습니다.

출처: 내일배움 스파르타 코딩 클럽

profile
끝까지 가면 내가 다 이겨

0개의 댓글