코드스테이츠 백엔드 부트캠프 60일차 - Section3 기술면접 준비

wish17·2023년 3월 12일
1
post-thumbnail

Spring 기술면접 준비

Spring MVC

Spring MVC 프레임워크의 요청처리 과정

  1. 클라이언트의 요청이 DispatcherServlet에 도착합니다.
  2. DispatcherServlet은 HandlerMapping에게 요청을 전달합니다.
  3. HandlerMapping은 요청 URL을 보고, 어떤 Controller가 요청을 처리할지 결정합니다.
  4. HandlerMapping은 Controller를 찾으면, DispatcherServlet에게 Controller 정보를 전달합니다.
  5. DispatcherServlet은 HandlerAdapter에게 Controller를 실행하도록 요청합니다.
  6. HandlerAdapter는 Controller가 요청을 처리할 수 있는 형태로 변환하고, Controller의 메소드를 실행합니다.
  7. Controller는 요청을 처리하고, 응답을 반환합니다.
  8. Controller가 반환한 View 이름을 참조하여 실제 View 객체를 생성합니다.
  9. View는 Controller가 전달한 Model 객체를 이용해 응답을 생성합니다.
  10. Interceptor는 DispatcherServlet이 Controller를 실행하기 전, 후에 실행됩니다.

HandlerMapping의 역할

HandlerMapping은 요청을 처리할 Controller를 찾아주는 역할을 합니다. HandlerMapping은 요청 URL을 보고, 어떤 Controller가 요청을 처리할지 결정합니다.

HandlerAdapter의 역할

HandlerAdapter는 HandlerMapping에서 찾은 Controller를 실행합니다. Controller를 실행하기 위해선 Controller의 메소드를 호출해야 합니다. HandlerAdapter는 Controller가 요청을 처리할 수 있는 형태로 변환하고, Controller의 메소드를 실행합니다.

Controller의 역할

Controller는 요청을 처리하고, 응답을 반환하는 역할을 합니다. Controller는 주로 @Controller 어노테이션을 이용해 생성됩니다. Controller는 요청을 받은 후, 비즈니스 로직을 실행하고, Model 객체에 데이터를 담아 View로 전달합니다.

ViewResolver의 역할

ViewResolver는 Controller가 반환한 View 이름을 참조하여 실제 View 객체를 생성합니다. ViewResolver는 View 이름을 보고, 어떤 View를 사용할지 결정합니다.

View의 역할

View는 Controller가 전달한 Model 객체를 이용해 응답을 생성합니다. View는 요청을 처리한 후, 응답을 생성하여 사용자에게 반환합니다.

Model의 역할

Model은 Controller가 사용하는 데이터를 담는 객체입니다. Controller는 비즈니스 로직을 실행한 후, Model 객체에 데이터를 담아 View로 전달합니다.

Interceptor의 역할

Interceptor는 DispatcherServlet이 Controller를 실행하기 전, 후에 실행되는 클래스입니다. Interceptor는 요청에 대한 로깅, 인증, 권한 체크 등의 역할을 수행합니다.


Spring MVC에서 제공하는 CSR와 SSR 방식 개요

CSR (Client Side Rendering)

CSR은 클라이언트 측에서 렌더링을 처리하는 방식입니다. 즉, 서버는 필요한 데이터만 전송하고 클라이언트는 이를 받아서 HTML, CSS 및 JavaScript를 사용하여 렌더링합니다. CSR 방식은 초기 로딩 시간이 빠르고 사용자 경험이 좋지만 검색 엔진 최적화(SEO)에 불리합니다.

SSR (Server Side Rendering)

SSR은 서버 측에서 렌더링을 처리하는 방식입니다. 즉, 서버는 클라이언트에게 HTML, CSS 및 JavaScript를 포함한 완전한 페이지를 제공합니다. SSR 방식은 초기 로딩 시간이 느리지만 검색 엔진 최적화(SEO)에 유리합니다.

차이점

CSR과 SSR 방식의 가장 큰 차이점은 렌더링을 처리하는 위치입니다. CSR은 클라이언트 측에서 렌더링하므로 초기 로딩 시간이 빠르고 사용자 경험이 좋지만 검색 엔진 최적화(SEO)에 불리합니다. 반면, SSR은 서버 측에서 렌더링하므로 초기 로딩 시간이 느리지만 검색 엔진 최적화(SEO)에 유리합니다.

SSR or CSR 선택 기준

어떤 방식을 선택할지는 프로젝트의 목적과 요구사항에 따라 다릅니다. 만약 검색 엔진 최적화(SEO)가 중요하다면 SSR 방식을 선택하는 것이 좋습니다. 그러나 초기 로딩 시간이 중요하다면 CSR 방식을 선택하는 것이 좋습니다.

핵심 키워드

검색 엔진 최적화(SEO), 초기 로딩 시간, 렌더링을 처리하는 위치


Spring MVC에서 REST API 엔드포인트를 구현하기 위해 사용되는 애너테이션들

@RestController

@RestController 애너테이션은 @Controller와 @ResponseBody를 합친 것입니다. 즉, 해당 클래스의 모든 메소드에 @ResponseBody를 적용하는 것과 같습니다. 이 애너테이션을 사용하면 반환값이 HTTP 응답 본문으로 직접 전송됩니다.

@RequestMapping

@RequestMapping 애너테이션은 요청 URI를 매핑하는 데 사용됩니다. 클래스 레벨과 메소드 레벨에서 사용할 수 있으며, URI, HTTP 메소드, 요청 헤더 등을 지정할 수 있습니다.

@GetMapping, @PostMapping, @PutMapping, @DeleteMapping

@GetMapping, @PostMapping, @PutMapping, @DeleteMapping 애너테이션들은 각각 GET, POST, PUT, DELETE HTTP 메소드를 처리하는 데 사용됩니다. 이 애너테이션들은 @RequestMapping의 축약형이며, 각각의 HTTP 메소드에 대해 따로 애너테이션을 사용할 수 있습니다.


RESTful 웹 서비스

REST란 무엇인가?

REST (Representational State Transfer)는 웹 서비스에서 자원을 정의하고, 그 자원에 대한 주소를 지정하는 방법 중 하나입니다. 이것은 HTTP를 기반으로하며, 데이터를 주고 받는 데 필요한 모든 정보를 URI에 포함시키는 것입니다.

RESTful 웹 서비스란?

RESTful 웹 서비스는 REST 아키텍처를 따르는 웹 서비스입니다. RESTful 웹 서비스는 웹의 기존 기술을 사용하여 클라이언트와 서버 간의 통신을 구현합니다. 이러한 웹 서비스는 다른 프로그래밍 언어 및 플랫폼에서 구현하기 쉬우며, 인터넷의 기존 구조와 호환됩니다.

RESTful 웹 서비스의 구성 요소

  • 자원(Resource)

    • URI는 서버에서 제공하는 자원을 식별합니다. 이러한 자원은 일반적으로 데이터베이스의 레코드와 유사합니다.
  • 행위(Verb)

    • HTTP 프로토콜에서는 GET, POST, PUT, DELETE와 같은 메서드를 사용하여 서버에서 자원을 조작합니다.
  • 표현(Representation)

    • 자원은 여러 표현으로 표현될 수 있습니다. 자원의 표현은 JSON, XML, HTML 등의 형식으로 제공될 수 있습니다.

RESTful 웹 서비스의 특징

  • Stateless

    • RESTful 웹 서비스는 클라이언트와 서버 간의 통신에서 클라이언트의 상태를 유지하지 않습니다. 이것은 서버의 부하를 줄이는 데 도움이 됩니다.
  • Cacheable

    • RESTful 웹 서비스는 캐싱을 지원합니다. 이것은 어떤 요청이 다시 수행될 때, 이전 응답을 반환할 수 있다는 것을 의미합니다.
  • Layered system

    • RESTful 웹 서비스는 분산 시스템에 적합한 계층 구조를 가지고 있습니다. 이것은 클라이언트와 서버 사이에 다른 계층이 있을 수 있음을 의미합니다.
  • Uniform interface

    • RESTful 웹 서비스는 클라이언트와 서버 간의 인터페이스가 일관성 있게 설계되어 있습니다. 이것은 서버의 구현 방법이 변경되더라도 클라이언트에게 영향을 미치지 않도록 합니다.

RESTful 웹 서비스의 장단점

  • 장점

    • 다른 플랫폼에서 쉽게 구현할 수 있습니다.
    • 웹의 기존 구조와 호환됩니다.
    • 하나의 인터페이스로 많은 종류의 클라이언트를 지원할 수 있습니다.
  • 단점

    • 복잡한 구현이 필요합니다.
    • 보안 문제가 발생할 수 있습니다.

RESTful 웹 서비스와 SOAP 웹 서비스의 차이점

SOAP (Simple Object Access Protocol) 웹 서비스는 XML 기반의 프로토콜입니다. SOAP 웹 서비스는 WSDL (Web Services Description Language)을 사용하여 서비스의 설명을 제공합니다. 이에 반해, RESTful 웹 서비스는 완전히 다른 방식으로 작동합니다. RESTful 웹 서비스는 HTTP를 기반으로하며, 클라이언트와 서버 간의 통신을 위해 자원, 행위 및 표현을 사용합니다. 이러한 차이점은 RESTful 웹 서비스가 다양한 플랫폼에서 구현하기 쉽고, 웹의 기존 구조와 호환됨을 의미합니다.


HATEOAS

Introduction

HATEOAS(하테오스)는 RESTful 웹 API 디자인에서 중요한 역할을 하는 개념입니다. HATEOAS를 활용하면 API 사용자는 응답으로 받은 하이퍼미디어를 기반으로 API와 상호작용할 수 있습니다. 이러한 기능은 웹 애플리케이션에서 매우 흔한 기능입니다. 이번 글에서는 HATEOAS의 개념, 원리, 그리고 활용 사례에 대해 알아보겠습니다.

HATEOAS의 개념

HATEOAS는 Hypermedia As The Engine Of Application State의 약어로, 애플리케이션의 상태를 관리하는 하이퍼미디어를 엔진으로 사용하는 개념입니다. 이는 클라이언트에게 API의 상태 전이를 제공합니다. 즉, 클라이언트는 API와 상호작용하기 위해 필요한 정보를 서버에서 받아올 수 있으며, 이를 통해 API와 상호작용할 수 있습니다. 이러한 방식으로 HATEOAS는 RESTful API의 자기 기술적인 설명( self-descriptive)을 가능하게 합니다.

HATEOAS의 원리

HATEOAS의 원리는 간단합니다. API의 응답으로 클라이언트에게 전달되는 메시지에는 API에서 실행 가능한 작업과 다음 상태로 이동하기 위한 링크가 포함되어 있습니다. 이러한 링크를 따라가면 클라이언트는 API와 상호작용할 수 있는 다음 단계로 이동할 수 있습니다. 이러한 방식으로 API는 클라이언트에게 API 자체의 상태를 관리하는 방법을 제공하며, 클라이언트는 API의 상태 전이를 따라가며 상호작용합니다.

HATEOAS의 활용 사례

HATEOAS는 많은 웹 애플리케이션에서 활용되고 있습니다. 예를 들어, GitLab API는 HATEOAS를 활용하여 API 사용자가 API와 상호작용하는 방법을 제공합니다. 또한, Netflix에서는 Spring HATEOAS를 사용하여 API의 상태를 관리하는 방법을 제공하고 있습니다. 이러한 방식으로 HATEOAS는 API의 디자인을 보다 유연하게 만들어줍니다.


Spring MVC에서의 예외 처리 기법

Spring MVC에서의 예외 처리 방법

Spring MVC에서는 예외 처리를 위한 다양한 방법을 제공합니다. 그 방법들 중에서도 가장 많이 사용되는 방법은 @ExceptionHandler, @ControllerAdvice, 그리고 @ResponseStatus 어노테이션을 이용한 방법입니다.

@ExceptionHandler 어노테이션을 이용한 예외 처리

@ExceptionHandler 어노테이션을 이용한 예외 처리는 특정 컨트롤러 내에서 발생하는 예외를 처리하기 위한 방법입니다. 이 어노테이션을 사용하면 특정 예외가 발생했을 때 해당 메서드가 실행되어 예외를 처리할 수 있습니다.

@ControllerAdvice 어노테이션을 이용한 예외 처리

@ControllerAdvice 어노테이션을 이용한 예외 처리는 여러 개의 컨트롤러에서 발생하는 예외를 처리하기 위한 방법입니다. 이 어노테이션을 사용하면 전역적으로 예외를 처리하는 클래스를 정의할 수 있습니다.

@ResponseStatus 어노테이션을 이용한 예외 처리

@ResponseStatus 어노테이션을 이용한 예외 처리는 예외가 발생했을 때 HTTP 응답의 상태 코드를 설정하기 위한 방법입니다. 이 어노테이션을 사용하면 예외가 발생했을 때, 응답의 상태 코드를 지정할 수 있습니다.

Spring Boot에서의 예외 처리 방법

Spring Boot에서는 @RestControllerAdvice 어노테이션을 이용한 예외 처리를 제공합니다. 이 어노테이션을 사용하면 전역적으로 예외를 처리하는 클래스를 정의할 수 있습니다.

Spring MVC에서의 예외 처리 팁과 주의사항

Spring MVC에서 예외 처리를 할 때 주의해야 할 점들이 있습니다. 예를 들어, 예외 처리기에서 예외를 발생시키면 안 되며, 예외 처리기에서도 예외가 발생할 수 있으므로 이를 잘 처리해야 합니다. 또한, 예외 처리기를 설정할 때 순서도 중요합니다. 예외 처리기의 순서를 잘못 설정하면 원치 않는 결과를 얻을 수 있습니다.


데이터 액세스 계층

DB의 외래 키(foreign key)

소개

데이터베이스(Database)는 많은 데이터들이 존재하는데 이러한 데이터들은 서로 관계가 있을 수 있습니다. 이러한 관계를 표현해주는 것이 외래 키(Foreign Key)입니다. 외래 키는 데이터베이스에서 매우 중요한 개념 중 하나입니다. 이번 글에서는 외래 키에 대해서 알아보도록 하겠습니다.

외래 키( foreign key )란?

외래 키는 다른 테이블의 기본 키(primary key)를 참조하는 열(column) 또는 열의 집합입니다. 이를 통해 두 테이블 간의 관계를 맺을 수 있습니다. 예를 들어, 학생 테이블과 성적 테이블이 있다면 학생 테이블의 기본 키인 학생 ID를 외래 키로 갖는 성적 테이블이 있을 수 있습니다.

외래 키를 사용하는 이유는?

외래 키를 사용하는 이유는 다음과 같습니다.

  • 데이터 무결성 유지: 외래 키를 사용하면 참조 무결성 제약 조건을 적용할 수 있습니다. 이를 통해 데이터 무결성을 유지할 수 있습니다.
  • 관계 표현: 외래 키를 사용하면 두 테이블 간의 관계를 표현할 수 있습니다. 이를 통해 데이터베이스의 구조를 명확하게 파악할 수 있습니다.
  • 데이터 검색: 외래 키를 사용하면 데이터를 빠르게 검색할 수 있습니다. 이를 통해 데이터베이스의 성능을 향상시킬 수 있습니다.

외래 키를 사용할 때 주의할 점은?

외래 키(Foreign Key)를 사용할 때 주의할 점은 다음과 같습니다.

  1. 참조 무결성 제약 조건 : 외래 키를 사용하여 두 테이블을 연결할 때, 참조하는 테이블의 무결성을 보장하기 위해 참조 무결성 제약 조건을 설정해야 합니다. 이를 통해 참조하는 테이블의 레코드가 삭제될 때 참조되는 테이블의 레코드도 함께 삭제되거나 변경되지 않도록 보장할 수 있습니다.
  2. 인덱스 생성 : 외래 키를 사용한 조인 작업은 성능에 영향을 미치므로, 참조되는 테이블의 외래 키에 인덱스를 생성하는 것이 좋습니다.
  3. 연관된 엔티티의 로딩 전략 : 연관된 엔티티를 로딩할 때는 적절한 로딩 전략을 선택하여 성능을 최적화해야 합니다. 즉, 지연로딩(Lazy Loading)이나 즉시로딩(Eager Loading) 중 적절한 방법을 선택해야 합니다.
  4. 연관된 엔티티의 추가 및 수정 : 외래 키를 사용한 연관 관계를 설정할 때, 연관된 엔티티를 추가하거나 수정할 때는 주의해야 합니다. 즉, 연관된 엔티티의 상태가 영속성 컨텍스트와 일치하도록 관리해야 합니다.
  5. 복합 키 사용 시 : 복합 키를 사용하는 경우, 외래 키에 복합 키의 모든 컬럼을 포함해야 합니다. 이때, 복합 키를 구성하는 컬럼 순서도 일치해야 합니다.
  6. NULL 값 주의 : 외래 키의 컬럼에 NULL 값을 허용하는 경우, 해당 열에 NULL 값이 저장될 수 있습니다. 이때, 외래 키를 참조하는 테이블에서 NULL 값을 가진 레코드를 참조하면 오류가 발생합니다. 따라서 외래 키를 사용할 때는 외래 키가 참조하는 테이블의 레코드가 NULL 값을 가지지 않도록 주의해야 합니다. 이를 위해 외래 키의 컬럼에 NOT NULL 제약 조건을 설정하거나, 해당 열을 NULL 값을 허용하지 않도록 디자인하는 것이 좋습니다. 또한, 외래 키를 참조하는 SQL 쿼리에서는 외래 키가 NULL 값이 아닌 레코드만 조회하도록 조건을 설정하여 오류를 방지할 수 있습니다.

외래 키의 제약 조건

외래 키에는 다음과 같은 제약 조건이 있습니다.

  • 참조 무결성 제약 조건: 외래 키는 참조하는 테이블의 기본 키와 일치해야 합니다.
  • 삭제와 업데이트 규칙: 참조되는 테이블의 행이 업데이트되거나 삭제될 때, 참조하는 테이블의 행도 업데이트되거나 삭제됩니다.

결론

외래 키는 데이터베이스에서 중요한 개념 중 하나입니다. 외래 키를 사용하면 데이터 무결성을 유지하고, 관계를 표현하며, 데이터 검색을 빠르게 할 수 있습니다. 하지만, 외래 키를 사용할 때에는 주의해야 할 점들이 있습니다. 이러한 제약 조건들을 잘 이해하고, 외래 키를 적절히 사용하면 데이터베이스를 효율적으로 관리할 수 있습니다.


JPA의 엔티티 간 연관 관계 매핑

소개

JPA(Java Persistence API)는 자바에서 제공하는 ORM(Object-Relational Mapping) 기술의 표준 스펙입니다. ORM은 객체와 관계형 데이터베이스 간의 매핑을 지원하여 객체 지향 설계와 관계형 데이터베이스를 연결하는 기술입니다. 이번에는 JPA에서 제공하는 엔티티 간 연관 관계 매핑에 대해 알아보겠습니다.

엔티티(Entity)란?

엔티티는 데이터베이스에서 데이터를 저장할 수 있는 단위입니다. JPA에서 엔티티는 객체를 말하며, 클래스를 정의하여 사용합니다. 엔티티의 필드는 데이터베이스의 컬럼과 매핑됩니다.

연관 관계 매핑이란?

엔티티 간의 관계를 매핑하여 객체를 참조하는 방식입니다. 연관 관계 매핑은 객체 간의 관계를 매핑하는 것으로 데이터베이스의 외래 키(foreign key)와 유사합니다.

연관 관계 매핑의 종류

연관 관계 매핑에는 다음과 같은 종류가 있습니다.

일대일(OneToOne)

일대일 관계는 한 쪽 엔티티가 다른 쪽 엔티티와 하나의 관계만 가지는 것을 의미합니다. 예를 들어, 회원(Member)과 회원의 프로필(Profile)이 있을 때 회원은 하나의 프로필만 가질 수 있습니다.

일대다(OneToMany)

일대다 관계는 한 쪽 엔티티가 다른 쪽 엔티티와 여러 개의 관계를 가지는 것을 의미합니다. 예를 들어, 하나의 팀(Team)에 여러 명의 회원(Member)이 있을 때, 팀은 여러 명의 회원을 가질 수 있습니다.

다대일(ManyToOne)

다대일 관계는 여러 쪽 엔티티가 한 쪽 엔티티와 관계를 가지는 것을 의미합니다. 예를 들어, 여러 명의 회원(Member)이 하나의 팀(Team)에 속해있을 때, 회원은 하나의 팀에만 속할 수 있습니다.

다대다(ManyToMany)

다대다 관계는 여러 쪽 엔티티가 다른 쪽 엔티티와 여러 개의 관계를 가지는 것을 의미합니다. 예를 들어, 여러 명의 회원(Member)이 여러 개의 프로젝트(Project)에 참여할 때, 회원과 프로젝트는 다대다 관계를 가집니다.

연관 관계 매핑 시 설정할 수 있는 속성

  • mappedBy: 양방향 연관 관계에서 연관 관계의 주인을 설정합니다. mappedBy 속성을 사용하면 관계의 주인이 아닌 쪽에서 mappedBy 속성을 사용하여 연관 관계를 설정할 수 있습니다.
    @Entity
    public class Order {
        @Id
        @GeneratedValue
        private Long id;
    
        @ManyToOne
        @JoinColumn(name = "customer_id")
        private Customer customer;
        ...
    }
    
    @Entity
    public class Customer {
        @Id
        @GeneratedValue
        private Long id;
    
        @OneToMany(mappedBy = "customer")
        private List<Order> orders;
        ...
    }
    
    위 코드에서 Order 엔티티는 ManyToOne 어노테이션을 사용하여 Customer 엔티티와 연관 관계를 맺고 있습니다. 이때, 관계의 주인은 Order 엔티티이며, JoinColumn 어노테이션을 사용하여 외래 키를 매핑하고 있습니다. 반면, Customer 엔티티는 mappedBy 속성을 사용하여 관계의 주인이 아니라는 것을 표시하고 있습니다. 이때, mappedBy 속성의 값으로는 Order 엔티티에서 매핑한 customer 필드의 이름을 사용하고 있습니다. 이렇게 함으로써, Order 엔티티에서는 customer 필드를 통해 Customer 엔티티와의 관계를 조회할 수 있으며, Customer 엔티티에서는 orders 필드를 통해 Order 엔티티와의 관계를 조회할 수 있습니다. 💡 mappedBy 속성을 사용하여 연관관계의 주인을 설정한 경우, 역방향에서 연관된 엔티티를 조회할 때는 쿼리문이 실행되지 않습니다. 따라서 해당 예시에서는 Order 엔티티를 조회하는 경우 Customer 엔티티의 조회 쿼리문만 실행됩니다.
  • cascade: 연관된 엔티티에 대한 작업을 전파할지 여부를 설정합니다. 예를 들어, 부모 엔티티가 삭제될 때 자식 엔티티도 함께 삭제할지 여부를 설정할 수 있습니다.
    @Entity
    public class Customer {
        @Id
        @GeneratedValue
        private Long id;
    
        @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
        private List<Order> orders;
        ...
    }
    
    @Entity
    public class Order {
        @Id
        @GeneratedValue
        private Long id;
    
        @ManyToOne
        @JoinColumn(name = "customer_id")
        private Customer customer;
        ...
    }
    
    위 코드에서 Customer 엔티티는 OneToMany 어노테이션을 사용하여 Order 엔티티와 일대다 관계를 맺고 있습니다. 이때, cascade 속성을 CascadeType.ALL로 설정하면 Customer 엔티티에 대한 작업이 Order 엔티티에도 전파되어 Order 엔티티도 함께 생성, 수정, 삭제됩니다.
    • CascadeType.ALL (전파)인 경우, Customer 엔티티를 삭제할 때 해당 고객이 생성한 모든 주문 정보도 함께 삭제됩니다. 따라서 Customer 엔티티를 삭제하는 쿼리문은 다음과 같습니다.

      DELETE FROM customer WHERE id = ?
      

      Customer 엔티티를 삭제할 때, 해당 고객이 생성한 모든 주문 정보도 함께 삭제되게 됩니다. 이때, cascade 속성을 설정하지 않으면 Customer 엔티티를 삭제할 때 주문 정보는 삭제되지 않습니다.

  • fetch: 연관된 엔티티를 조회할 때 데이터를 어떻게 가져올지 설정합니다. EAGER와 LAZY 두 가지 옵션이 있습니다.
    @Entity
    public class Customer {
        @Id
        @GeneratedValue
        private Long id;
    
        @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        private List<Order> orders;
        ...
    }
    
    @Entity
    public class Order {
        @Id
        @GeneratedValue
        private Long id;
    
        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "customer_id")
        private Customer customer;
        ...
    }
    
    위 코드에서 Customer 엔티티는 OneToMany 어노테이션을 사용하여 Order 엔티티와 일대다 관계를 맺고 있습니다. 이때, fetch 속성을 FetchType.LAZY로 설정하면 Customer 엔티티를 조회할 때 연관된 Order 엔티티는 지연로딩되어 필요한 시점에 가져옵니다.
    • FetchType.LAZY (지연로딩)인 경우, Customer 엔티티를 조회할 때 연관된 Order 엔티티는 필요한 시점에 가져옵니다. 따라서 Customer 엔티티를 조회하는 쿼리문은 다음과 같습니다.

      SELECT * FROM customer WHERE id = ?
      

      반면, Order 엔티티는 ManyToOne 어노테이션을 사용하여 Customer 엔티티와 다대일 관계를 맺고 있습니다. 이때, fetch 속성을 FetchType.EAGER로 설정하면 Order 엔티티를 조회할 때 연관된 Customer 엔티티는 즉시로딩되어 함께 조회됩니다.

    • FetchType.EAGER (즉시로딩)인 경우, Order 엔티티를 조회할 때 연관된 Customer 엔티티는 즉시 함께 조회됩니다. 따라서 Order 엔티티를 조회하는 쿼리문은 다음과 같습니다.

      SELECT o.*, c.* FROM order o JOIN customer c ON o.customer_id = c.id WHERE o.id = ?
      

      즉, 위 코드에서는 Customer 엔티티를 조회할 때 연관된 Order 엔티티는 필요한 시점에 가져오고, Order 엔티티를 조회할 때 연관된 Customer 엔티티는 즉시 함께 조회됩니다.

  • optional: 연관된 엔티티가 항상 존재하는지 여부를 설정합니다. optional=false로 설정하면 연관된 엔티티가 반드시 존재해야 합니다.
  • targetEntity: 연관된 엔티티의 클래스를 설정합니다. 일반적으로 이 속성을 사용하지 않아도 됩니다.

연관 관계 매핑 시 주의할 점

연관 관계 매핑 시 주의할 점은 다음과 같습니다.

  • 양방향 관계 설정 시 상호 참조에 주의해야 합니다.
  • 연관 관계의 주인을 명확하게 설정해야 합니다.
  • 연관 관계 매핑 시 지연 로딩(Lazy Loading)을 사용하여 성능을 최적화할 수 있습니다.

JPA의 단일 엔티티 매핑 방법

소개

JPA(Java Persistence API)는 자바 진영의 ORM(Object Relational Mapping) 기술 표준입니다. 이번 글에서는 JPA에서 단일 엔티티 매핑 방법에 대해 알아보겠습니다.

엔티티 매핑의 개념

JPA에서 엔티티 매핑은 객체와 데이터베이스 테이블 간의 매핑을 의미합니다. 객체를 데이터베이스에 저장하거나 데이터베이스에서 객체를 읽어올 때 이 매핑 정보를 참조하여 작업을 수행합니다.

단일 엔티티 매핑(Single Entity Mapping)

JPA에서 가장 간단한 형태의 엔티티 매핑 방법으로, 하나의 엔티티 클래스와 하나의 테이블을 매핑하는 방법입니다. 즉, 엔티티 클래스 하나가 데이터베이스의 테이블 하나와 매핑되어 데이터를 주고받습니다. 이 방식은 주로 단순한 데이터 모델에서 사용됩니다.

어노테이션을 이용한 단일 엔티티 매핑 방법

JPA에서 단일 엔티티 매핑을 위해 사용하는 어노테이션은 다음과 같습니다.

  • @Entity : JPA에서 엔티티 클래스임을 명시
  • @Table : 엔티티와 매핑할 테이블을 지정
  • @Id : 엔티티 클래스의 필드 중 기본 키(primary key)로 사용할 필드를 지정
  • @GeneratedValue : 기본 키의 생성 방식을 지정
  • @Column : 엔티티 클래스의 필드와 데이터베이스 테이블의 컬럼을 매핑

엔티티 클래스의 생성 및 활용 방법

JPA에서 단일 엔티티 매핑을 위해 엔티티 클래스를 생성하고 활용하는 방법은 다음과 같습니다.

  1. EntityManagerFactory 생성 : JPA를 사용하기 위해 가장 먼저 생성하는 객체입니다.
  2. EntityManager 생성 : JPA를 사용하여 데이터베이스와 통신하기 위한 객체입니다. 엔티티 등록, 조회, 수정, 삭제와 같은 데이터베이스 작업을 수행할 수 있습니다.

영속성 컨텍스트 개요

소개

영속성 컨텍스트(Persistence Context)란, JPA에서 엔티티(Entity)를 관리하는 논리적인 개념입니다. JPA는 영속성 컨텍스트를 통해 엔티티를 관리하며, 이를 통해 데이터베이스와의 작업을 보다 쉽고 효율적으로 할 수 있습니다.

장점

영속성 컨텍스트를 사용하면, 엔티티를 데이터베이스에 저장하거나 조회할 때 데이터베이스와의 I/O를 줄일 수 있습니다. 또한, 영속성 컨텍스트는 1차 캐시를 가지고 있어 같은 엔티티를 반복해서 조회할 때 데이터베이스에서 가져오는 것이 아니라, 1차 캐시에서 가져오기 때문에 애플리케이션의 성능을 향상시킬 수 있습니다.

생명주기

영속성 컨텍스트는 엔티티마다 생명주기를 가지고 있습니다. 생명주기는 총 4가지로, 비영속, 영속, 준영속, 삭제 상태가 있습니다. 비영속 상태는 JPA에서 관리하지 않는 상태이며, 영속 상태는 JPA에서 관리하는 상태입니다. 준영속 상태는 영속성 컨텍스트에서 분리된 상태이며, 삭제 상태는 데이터베이스에서 삭제된 상태입니다.

동기화 방법

영속성 컨텍스트와 데이터베이스는 내부적으로 동기화(Synchronization)를 수행합니다. 트랜잭션을 커밋할 때, 영속성 컨텍스트는 변경된 엔티티를 데이터베이스에 동기화합니다. 이때, 영속성 컨텍스트는 데이터베이스에 쿼리를 전송하기 전에 엔티티의 상태를 확인하고 변경된 내용이 있으면 쿼리를 생성하여 전송합니다.

관련된 주요 개념들

  • 트랜잭션(Transaction): 데이터베이스에서 논리적인 작업 단위입니다. 트랜잭션 내에서 수행된 작업은 모두 성공하거나 모두 실패해야 합니다.
  • 엔티티(Entity): 데이터베이스에서 관리되는 실제 데이터를 말합니다. 예를 들어, 회원(Member), 상품(Item) 등이 엔티티가 될 수 있습니다.
  • 엔티티 매니저(Entity Manager): 영속성 컨텍스트를 관리하는 객체입니다. 엔티티 매니저를 통해 엔티티를 생성, 조회, 수정, 삭제할 수 있습니다.

Spring JDBC, Spring Data JDBC, Spring Data JPA의 차이점

Spring JDBC, Spring Data JDBC, Spring Data JPA는 모두 스프링 프레임워크에서 제공하는 데이터 액세스 기술입니다. 그러나 각각의 기술은 목적과 사용 방법이 조금씩 다릅니다.

Spring JDBC

  • JDBC(Java Database Connectivity)를 기반으로 하는 스프링 프레임워크의 데이터 액세스 기술
  • JDBC API를 직접 사용하여 SQL 쿼리를 수행하고 결과를 가져옴
  • 간단하고 직관적인 방법으로 데이터베이스에 접근할 수 있으며, SQL 쿼리를 직접 작성해야 함
  • 빠른 응답 시간이 필요한 경우, 대량 데이터 처리가 필요한 경우 등에 적합

Spring Data JDBC

  • JDBC를 기반으로 하는 Spring Data 프로젝트의 일부
    ( JDBC API를 추상화한 기술을 사용 )
  • 간단한 CRUD(Create, Read, Update, Delete) 작업을 위한 객체 매핑을 지원하는 데이터 액세스 기술
  • SQL 쿼리를 직접 작성하는 대신, 도메인 모델과 일치하는 자동 생성 SQL을 사용하여 데이터베이스와 상호 작용
  • 자동으로 생성되는 SQL을 수정하거나 직접 작성할 수 있음
  • 도메인 모델과 데이터베이스 스키마 간의 일관성 유지 및 변경 사항 관리가 용이함

Spring Data JPA

  • JPA(Java Persistence API)를 기반으로 하는 Spring Data 프로젝트의 일부
  • 객체-관계 매핑(Object-Relational Mapping, ORM)을 지원하는 데이터 액세스 기술
  • JPA의 엔티티 매핑 기능을 사용하여 객체와 데이터베이스 간의 매핑을 자동화함
  • 객체 지향적인 방식으로 데이터베이스를 다룰 수 있으며, SQL 쿼리를 직접 작성할 필요가 없음
  • JPA 프로바이더(예: Hibernate)에서 제공하는 다양한 기능(예: 지연 로딩, 캐시 등)을 활용할 수 있음
  • 각각의 기술은 목적과 사용 방법이 다르므로, 프로젝트의 요구사항에 따라 적합한 기술을 선택해야 합니다.

객체-관계 매핑(Object-Relational Mapping, ORM)

ORM은 객체 지향 프로그래밍 언어에서 사용하는 객체와 관계형 데이터베이스 간의 데이터를 매핑하는 기술입니다.

ORM의 장점

  • 객체 지향 프로그래밍 언어에서 사용하는 객체와 데이터베이스의 관계형 데이터 간의 매핑이 용이해짐
  • SQL 쿼리를 직접 작성하지 않아도 되므로 생산성이 향상됨
  • 데이터베이스 구조가 변경되어도 객체 구조를 유지할 수 있으므로 유연성이 높아짐
  • 객체와 데이터베이스 간의 불일치를 줄여줘서 프로그래머가 불필요한 작업을 하지 않도록 도와줌
  • 성능 최적화 기능(예: 캐시, 지연 로딩)을 제공하여 높은 성능을 유지할 수 있음

ORM의 단점

  • ORM을 사용하면 객체-관계 매핑이 복잡해질 수 있음
  • SQL 쿼리를 직접 작성하는 것보다 실행 계획을 이해하고 최적화하는 것이 어려울 수 있음
  • ORM 프레임워크에 대한 학습 비용이 필요할 수 있음
  • 성능 문제가 발생할 수 있음(ORM 프레임워크에 따라 다름)

ORM 프레임워크

  • Hibernate, JPA(Java Persistence API), MyBatis, EclipseLink 등 많은 ORM 프레임워크가 존재함
  • 각 ORM 프레임워크는 각기 다른 장단점과 특징을 가지고 있으므로, 프로젝트의 요구사항에 맞게 선택해야 함
  • ORM 프레임워크를 사용하면 객체-관계 매핑 코드를 줄일 수 있고, 자동으로 SQL 쿼리를 생성하여 데이터베이스와 상호 작용할 수 있음

ORM 매핑 방식

  • 객체와 데이터베이스 간의 매핑 방식에는 주로 두 가지 방식이 사용됨
  • 관례적인 매핑 방식: 객체와 데이터베이스의 이름이 일치하도록 하거나, 일정한 규칙에 따라 매핑함
  • 어노테이션, XML 등을 사용하는 매핑 방식: 객체와 데이터베이스 간의 매핑을 선언적으로 지정함

ORM 관계 매핑

  • ORM에서는 객체와 테이블 간의 관계를 매핑해야 함
  • 일대일, 일대다, 다대일, 다대다 등 다양한 관계를 매핑할 수 있음
  • 관계 매핑 방식에는 조인 컬럼, 일대다 양방향, 일대다 단방향, 다대다 등 다양한 방식이 존재함

지연 로딩(Lazy Loading)

  • ORM에서는 지연 로딩을 통해 성능을 향상시킬 수 있음
  • 지연 로딩은 연관된 엔티티를 즉시 로딩하는 대신, 필요할 때 로딩하는 방식임
  • 이를 통해 불필요한 쿼리를 방지하고, 성능을 개선할 수 있음

캐시(Cache)

  • ORM에서는 캐시를 사용하여 성능을 향상시킬 수 있음
  • 캐시는 자주 사용되는 데이터나 연관된 데이터를 메모리에 저장해두고, 필요할 때 메모리에서 로딩하는 방식임
  • 이를 통해 빠른 응답속도를 유지할 수 있음

성능 최적화

  • ORM에서는 성능 최적화를 위한 다양한 기능을 제공함
  • 캐시, 지연 로딩, 배치 작업 등을 통해 성능을 최적화할 수 있음
  • 또한 ORM 프레임워크에서 제공하는 통계 정보를 통해 성능 튜닝이 가능함

ORM의 주의사항

  • ORM을 사용한다고 해서 모든 상황에서 성능이 향상되는 것은 아님
  • 일부 복잡한 쿼리나 대용량 데이터에 대해서는 SQL 쿼리를 직접 작성하는 것이 성능이 더 우수할 수 있음
  • ORM 프레임워크를 사용하더라도, SQL 쿼리를 이해하고 최적화하는 능력이 필요함
  • 또한 ORM을 사용할 때는 데이터베이스 스키마의 성능에도 고려해야 함. 대용량 데이터를 처리할 때는 인덱스, 파티션, 샤딩 등의 방법도 고려해야 함.































0개의 댓글