Development/Spring 47

[Spring] 스프링 부트의 예외 처리 방식

스프링 부트의 예외 처리 방식 웹 서비스 애플리케이션에서는 외부에서 들어오는 요청에 담긴 데이터를 처리하는 경우가 많다. 그 과정에서 예외가 발생하면 예외를 복구해서 정상으로 처리하기보다는 요청을 보낸 클라이언트에 어떤 문제가 발생했는지 전달하는 경우가 많다. 예외가 발생했을 때 클라이언트에 오류 메시지를 전달하려면 각 레이어에서 발생한 예외를 엔드포인트 레벨인 컨트롤러로 전달해야 한다. 이렇게 전달받은 예외를 스프링 부트에서 처리하는 방식으로 크게 두 가지가 있다. (Rest)ControllerAdvice와 @ExceptionHandler를 통해 모든 컨트롤러의 예외를 처리 ExceptionHandler를 통해 특정 컨트롤러의 예외를 처리 @RestControllerAdvice @RestControll..

Development/Spring 2024.03.08

[Spring] 유효성 검사와 Hibernate Validator

유효성 검사(validation) 애플리케이션의 비즈니스 로직이 올바르게 동작하는지 검증하는 작업을 유효성 검사라고 한다. 유효성 검사의 예로는 여러 계층에서 들어오는 데이터에 대해 의도한 형식대로 값이 들어오는지 체크하는 과정이 있다. 특히 자바에서 가장 신경 써야 하는 것 중 하나로 NullPointException이 있다. Bean Validation 계층별로 진행하는 유효성 검사는 검증 로직이 각 클래스별로 분산돼 있어 관리하기가 어렵다. 그리고 검증 로직에 의외로 중복이 많아 여러 곳에 유사한 기능의 코드가 존재할 수 있다. 검증해야 할 값이 많다면 검증하는 코드가 길어진다. 이러한 문제로 코드가 복잡해지고 가독성이 떨어지는 문제가 있다. 이 같은 문제를 해결하기 위해 자바 진영에서는 2009년..

Development/Spring 2024.03.07

[Spring] 영속성 전이(Cascade)와 고아 객체(Orphan)

영속성 전이(Cascade) 영속성 전이란 특정 엔티티의 영속성 상태를 변경할 때 그 엔티티와 연관된 엔티티의 영속성에도 영향을 미쳐 영속성 상태를 변경하는 것 예를 들어 아래 코드에서 @OneToMany 어노테이션의 인터페이스를 살펴보면 cascade()라는 요소를 볼 수 있다. public @interface OneToMany { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default FetchType.LAZY; String mappedBy() default ""; boolean orphanRemoval() default false; } 영속성 전이에 사용되는 타입은 엔티티..

Development/Spring 2024.03.05

[Spring] 연관 관계 매핑하기

RDBMS를 사용할 때는 각 도메인에 맞는 테이블을 설계하고 연관관계를 설정해서 조인(Join) 등의 기능을 활용합니다. JPA를 사용하여 테이블의 연관관계를 엔티티 간의 연관관계로 표현할 수 있습니다. 연관관계 매핑 종류와 방향 One To One(일대일) 테이블의 하나의 레코드가 다른 테이블의 하나의 레코드만 연관되어 있는 관계입니다. 예를 들어 Product 테이블과 Product_Detail 테이블의 경우, 한 Product 당 한 Detail 레코드와 연관 관계를 가질 수 있으므로 일대일 관계라고 볼 수 있습니다. One To Many(일대다), Many To One(다대일) 한 테이블의 레코드가 다른 테이블의 여러 레코드와 연관되어 있는 관계입니다. 예를 들어 Team 테이블과 Player ..

Development/Spring 2024.03.05

[Spring] JPA Auditing, BaseEntity

JPA Auditing 'Audit'란 '감시하다'라는 뜻으로, 각 데이터마다 '누가', '언제' 데이터를 생성했고 변경했는지 감시한다는 의미로 사용됩니다. 엔티티 클래스에는 공통적으로 들어가는 필드가 있을 수 있습니다. 예를 들어, '생성 일자'와 '변경 일자', '생성 주체'와 '변경 주체' 같은 것 입니다. 이러한 필드들은 매번 엔티티별로 생성하거나 변경할 때 값을 주입해야 하는 번거로움이 있습니다. 이 같은 번거로움을 해소하기 위해 Spring Data JPA에서는 이러한 값을 자동으로 넣어주는 기능을 제공합니다. JPA Auditing 기능 활성화 @EnableJpaAudting @EnableJpaAuditing 어노테이션은 JPA Auditing을 활성화하는 역할을 합니다. 이 어노테이션은 @..

Development/Spring 2024.03.03

[Spring] QueryDSL

QueryDSL QueryDSL은 정적 타입을 이용해 SQL과 같은 쿼리를 생성할 수 있도록 지원하는 프레임워크 문자열이나 XML파일을 통해 쿼리를 작성하는 대신 QueryDSL이 제공하는 플루언트(Fluent) API를 활용해 쿼리를 생성할 수 있다. QueryDSL의 장점 IDE가 제공하는 코드 자동 완성 기능을 사용할 수 있다. 문법적으로 잘못된 쿼리를 허용하지 않는다. 따라서 정상적으로 활용된 QueryDSL은 문법 오류를 발생시키지 않는다. 고정된 SQL 쿼리를 작성하지 않기 때문에 동적으로 쿼리를 생성할 수 있다. 코드로 작성하므로 가독성 및 생산성이 향상된다. 도메인 타입과 프로퍼티를 안전하게 참조할 수 있다. QueryDSL 의존성 추가하기 Spring 3.x.x이상, Java 21, Gr..

Development/Spring 2024.03.01

[Spring] JPA의 정렬과 페이징 처리

정렬 처리하기 일반적인 쿼리문에서 정렬을 사용할 때는 ORDER BY 구문을 사용합니다. 쿼리 메서드도 정렬 기능에 동일한 키워드가 사용됩니다. // ASC: 오름차순, DESC: 내림차순 List findByNameOrderByNumberAsc(String name); List findByNameOrderByNumberDesc(String name); 위와 같이 기본 쿼리 메서드를 작성한 후 OrderBy 키워드를 삽입하고 정렬하고자 하는 칼럼과 오름차순/내림차순을 설정하면 정렬이 수행됩니다. 여러 정렬 조건을 사용하기 위해선 다음과 같이 작성할 수 있습니다. List findByNameOrderByPriceAscStockDesc(String name); 위 코드에서 먼저 Price를 우선으로 오름차순..

Development/Spring 2024.02.29

[Spring] JPQL (JPA Query Language)과 쿼리 메서드

JPQL (JPA Query Language) JPQL은 JPA Query Language의 줄임말로 JPA에서 사용할 수 있는 쿼리를 의미합니다. JPQL의 문법은 SQL과 매우 유사하여 데이터베이스 쿼리에 익숙하다면 쉽게 사용할 수 있습니다. SQL과의 차이점은 SQL에서는 테이블이나 칼럼의 이름을 사용하는 것과 달리 JPQL은 엔티티 객체를 대상으로 수행하는 쿼리이기 때문에 매핑된 엔티티의 이름과 필드의 이름을 사용해야 합니다. SELECT p FROM Product p WHERE p.number = ?1; 위 문장에서 Product는 엔티티 클래스 이름, p.number는 엔티티의 속성입니다. 리포지토리 쿼리 메서드 생성하기 쿼리 메서드는 크게 동작을 결정하는 주제(Subject)와 서술어(Pre..

Development/Spring 2024.02.28

[Spring] 스프링 부트에서 테스트 코드 작성하기

스프링 부트의 테스트 설정 스프링 부트는 테스트 환경을 쉽게 설정할 수 있도록 spring-boot-starter-test 프로젝트를 지원한다. 이 프로젝트를 사용하려면 의존성을 추가해야 한다. Gradle (build.gradle) dependencies { ... testImplementation 'org.springframework.boot:spring-boot-starter-test' } Maven (pom.xml) org.springframework.boot spring-boot-starter-test test 스프링 부트에서 제공하는 spring-boot-starter-test 라이브러리는 JUnit, Mockito, assertJ등의 다양한 테스트 도구를 제공한다. spring-boot-st..

Development/Spring 2024.02.23

[Spring] Lombok

Lombok (롬복) Lombok은 데이터(모델) 클래스를 생성할 때 반복적으로 사용하는 getter/setter같은 메서드를 어노테이션으로 대체하는 기능을 제공하는 라이브러리이다. 이는 반복되는 코드를 생략하여 가독성을 높여줄 수 있다. 또한 어노테이션 기반으로 코드를 자동 생성해주어 생산성이 높아진다. Lombok 의존성 추가 Gradle compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' build.gradle에 dependencies에 위 코드를 추가 Maven org.projectlombok lombok true pom.xml에 위 코드를 추가 Lombok의 주요 어노테이션 @Getter, @..

Development/Spring 2024.02.21