스프링(Spring), 스프링부트(SpringBoot)/스프링부트(SpringBoot) 기초

스프링 부트 핵심 가이드(장정우 지음) - 데이터베이스 연동 4: 서비스와 컨트롤러 설계2, 롬복(Lombok)

개발학생 2025. 7. 24. 16:47
반응형

*책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성  

 

[Java] 차근차근 Java 설치하기 (JDK17, Window 11)

자바 개발 도구 설치 방법에 대해서 알아보겠습니다. Java17은 LTS(Long Term Support : 장기 지원) 릴리즈로 1년 후까지 기술 지원 및 버그를 개선한 서비스를 제공받을 수 있습니다. 업데이트 버전을 꾸

yungenie.tistory.com

 

[Windows] Spring Tool Suite 4(STS 4) 다운로드 및 설치

STS란?Spring Tool Suite(STS)는 스프링 프로젝트를 생성하고, 개발할 수 있게 해주는 도구입니다. STS 설치 과정에 대해 설명드리겠습니다. 설치 파일 다운로드STS 공식 사이트에서 설치 파일을 다운로

priming.tistory.com

 

MySQL :: Download MySQL Community Server

Select Version: 9.3.0 Innovation 8.4.5 LTS 8.0.42 Select Operating System: Select Operating System… Microsoft Windows Ubuntu Linux Debian Linux SUSE Linux Enterprise Server Red Hat Enterprise Linux / Oracle Linux Fedora Linux - Generic Oracle Solaris mac

dev.mysql.com

  • Gradle

**STS에서 Gradle 프로젝트 생성한 과정 

*** 이전 글에서 이어집니다

2025.07.23 - [스프링(Spring), 스프링부트(SpringBoot)/스프링부트(SpringBoot) 기초] - 스프링 부트 핵심 가이드(장정우 지음) - 데이터베이스 연동 3: DAO 설계, 서비스와 컨트롤러 설계

 

스프링 부트 핵심 가이드(장정우 지음) - 데이터베이스 연동 3: DAO 설계, 서비스와 컨트롤러 설계

****수많은 문제들이 발생해서 업로드가 매우 늦어졌습니다.... 마지막 문제는 아직도 해결못했기때문에 다음 글로 이어집니다... *책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성 Windows11

keep-programming-study.tistory.com

1. 서비스와 컨트롤러 설계2
-> localhost8080/swagger-ui/index.html에서 POST API가 동작하지 않는 오류 마저 해결하기

1) ProductController.java의 POST API 코드 수정해보기: 그래도 오류 발생 

  • @RequestBody가 동작을 하는 건지 확인하는 용도.. 

ProductController.java의 POST API 수정
문자열 하나조차 전달되지 않아 Internal Server Error가 찍힘

  • 콘솔에서 상세 내용 확인: Java 컴파일 시 -parameters 옵션이 적용되지 않아서, Spring이 파라미터 이름을 알 수 없다는 뜻 (build.gradle을 고쳤는데도...) 
java.lang.IllegalArgumentException: 
Name for argument of type [java.lang.String] not specified, 
and parameter name information not available via reflection. 
Ensure that the compiler uses the '-parameters' flag.

 

2) ProductController.java의 POST API 코드 수정해보기2: @RequsetBody 말고 @RequestParam 방식 -> 드디어성공!! 

  • Spring이 파라미터 이름을 직접 지정받기 때문에 -parameters 옵션 없이도 작동하는 것 

@RequestParam 방식으로 ProductController.java의 POST API 수정
localhost8080/swagger-ui/index.html에서 테스트 성공
드디어 콘솔창에 작성한 내용이 제대로 찍힘!
MySQL Workbench에서도 상품 데이터가 insert된 것 확인!

*그동안 @RequestBody가 먹히지 않은 이유?
-> STS가 Gradle의 -parameters 옵션을 무시했기 때문(이틀동안 지옥을 맛봄..)

  • STS는 Eclipse 기반이라서 .class 파일을 Eclipse 빌드 경로로 만들 수 있음
  • Gradle 설정이 반영되지 않으면 파라미터 이름 정보가 누락됨
  • Jackson은 생성자 기반 바인딩을 시도하다가 null 값 주입

**해결할 수 있는 방법(택1)

  • 1. STS에서 완전한 Gradle 빌드로 전환
    • Project > Clean
    • Gradle > Refresh Gradle Project
    • .settings, .classpath, .project 파일 삭제 후 재import
  • 2. IntelliJ IDEA로 프로젝트 열기 (Gradle 설정 100% 반영 - 추천!! 저처럼 고생 마시구 책이랑 똑같이 인텔리제이 씁시다)
    • IntelliJ는 -parameters 옵션을 자동으로 반영하고, Jackson 바인딩이 훨씬 안정적

3) ProductController.java의 GET API도 @RequestParam 방식으로 코드를 수정하고 동작 확인

  • 정상적으로 동작함! 

@RequestParam 방식으로 ProductController.java의 GET API 수정
정상적으로 number에 맞는 상품 데이터를 가져옴!

4) ProductController.java의 PUT API도 @RequestParam 방식으로 코드를 수정하고 동작 확인

  • 역시 정상적으로 동작함! 

@RequestParam 방식으로 ProductController.java의 PUT API 수정

 

정상적으로 number에 맞는 상품의 이름을 변경함!
MySQL Workbench에서도 상품 데이터가 update 된 것 확인!

5) ProductController.java의 DELETE API도 @RequestParam 방식으로 코드를 수정하고 동작 확인

  • 마지막까지 정상적으로 동작함! 

@RequestParam 방식으로 ProductController.java의 DELETE API 수정
정상적으로 number에 맞는 상품의 데이터를 삭제함!
MySQL Workbench에서도 상품 데이터가 DELETE 된 것 확인

2. 롬복(Lombok): 반복되는 코드의 작성을 생략하는 방법

1) 롬복이란?

  • 데이터(모델) 클래스 생성 시 반복적으로 사용하는 getter/setter 같은 메서드를 어노테이션으로 대체하는 기능의 라이브러리
    -> 코드가 길어지고 가독성이 낮아지는 문제 해결
  • 어노테이션 기반으로 코드를 자동 생성하여 생산성이 높아짐
  • 롬복을 안다면 간단하게 코드를 유추할 수 있어 유지보수에 용이

2) 프로젝트에 롬복 추가하기

(1) build.gradle에 롬복 의존성 추가 후 저장(단축키 ctrl+s)

  • 필자는 프로젝트 생성 시 이미 추가한 상태 
dependencies {
	// 롬복 의존성 
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
}

 

(2) build.gradle 우클릭 후, Gradle -> Refresh Gradle Project 클릭 

Gradle -> Refresh Gradle Project

 3) 프로젝트에 롬복 적용해보기: Product.java

// Product.java
package com.example.demo.jpa.data.entity;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

//클래스의 모든 필드에 대해 Getter 메서드를 자동 생성
@Getter
//클래스의 모든 필드에 대해 Setter 메서드를 자동 생성
@Setter
//파라미터가 없는 기본 생성자를 자동 생성
@NoArgsConstructor
//모든 필드를 파라미터로 받는 생성자를 자동 생성
@AllArgsConstructor
//이 클래스는 JPA 엔티티로 데이터베이스 테이블과 매핑
@Entity
//엔티티가 매핑될 테이블 이름을 명시적으로 지정 (기본값은 클래스 이름)
@Table(name="product")
public class Product {
	// 기본 키(PK)로 지정된 필드. 데이터베이스의 고유 식별자 역할
    @Id
    // ID 값을 자동 생성함. GenerationType.IDENTITY는 DB가 직접 AUTO_INCREMENT 방식으로 생성하도록 함(insert 후에 pk 자동생성)
    // -> IDENTITY외에도 AUTO(기본값, 사용하는 데이터베이스에 맞게 기본값 자동 생성), 
    //    SEQUENCE(Oracle, PostgreSQL 등 시퀀스를 지원하는 DB에서 별도 시퀀스 객체를 생성해 PK값 증가), 
    //    TABLE(키 값을 관리하는 별도 테이블을 생성해 PK값 증가-성능 낮음)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
	private long number;

    // 엔티티 클래스의 필드는 자동으로 테이블 칼럼으로 매핑되므로, 별다른 설정을 하지 않을 경우 @Column을 생략해도 됨
    // 상품 이름 (Null 허용하지 않음)
    @Column(nullable = false)
    private String name;
    
    // 가격 (Null 허용하지 않음)
    @Column(nullable = false)
    private int price;
    
    // 재고 수량 (Null 허용하지 않음)
    @Column(nullable = false)
    private int stock;

    // 상품 생성 일시 (자동 설정할 수 있으나 현재는 수동 할당 전제)
    private LocalDateTime createdAt;

    // 상품 수정 일시
    private LocalDateTime updatedAt;
}

 

4) 롬복에서 많이 쓰이는 어노테이션(Product.java에 적용한 어노테이션 제외)

@RequiredArgsConstructor 필드 중 final이나 @NotNull이 설정된 변수를 매개변수로 갖는 생성자를 자동 생성
@ToString 필드의 값을 문자열로 조합해서 리턴하는 toString() 메서드를 자동 생성
@EqualsAndHashCode 객체의 동등성(Equality)과 동일성(Identity)을 비교하는 연산 메서드 생성 
-> .equals()와 .hashCode()메서드 자동 생성

 

반응형