자바 웹 JPA와 스프링 부트

Dear·2025년 7월 2일

TIL

목록 보기
53/74

💙 Optional

Java 8부터 도입된 null을 안전하게 처리하기 위한 래퍼 클래스

String name = person.getName(); // name이 null 이면 NPE 발생

-> NullPointerException(NPE) 발생 가능성이 존재

java.util.Optional<T> 형태로 사용되며, null 값을 직접 다루지 않고도 값이 존재할 수도 있고 없을 수도 있는 상황을 처리할 수 있도록 도와준다.

주요 메소드

메서드설명
Optional.of(value)절대 null이 아닌 값을 감쌈 (null이면 예외 발생)
Optional.ofNullable(value)null일 수도 있는 값을 감쌈
Optional.empty()빈 Optional 객체 생성
isPresent()값이 존재하면 true
ifPresent(Consumer)값이 존재할 때 동작 실행
get()값 반환 (값이 없으면 예외 발생)
orElse(defaultValue)값이 없으면 기본값 반환
orElseGet(Supplier)값이 없으면 함수형 인터페이스로 기본값 생성
orElseThrow(Supplier)값이 없으면 예외 발생
Optional<String> name = Optional.of("John");
System.out.println(name.get()); // John

Optional<String> empty = Optional.empty();
System.out.println(empty.orElse("default")); // default

Optional<String> maybeNull = Optional.ofNullable(null);
maybeNull.ifPresent(System.out::println); // 실행 안 됨

String result = maybeNull.orElseGet(() -> "Generated");
System.out.println(result); // Generated

💙 MyBatis와 JPA

항목MyBatisJPA
데이터 객체VO (모든 계층에서 동일)Entity, DTO 분리
SQL 처리 방식XML Mapper 사용ORM 기반 자동 쿼리
구조 단순성단순하지만 불안정구조화되어 보안/유지보수 유리
계층 간 분리없음명확히 분리 (프론트와 도메인 영역)
대표 단점보안에 취약 (비밀번호 전달 등), 계층 혼재학습 곡선 있음, 추상화로 인한 디버깅 어려움

MyBatis 구조도

Controller -> Service -> DAO -> VO -> Mapper(XML) -> DB

JPA 구조도

Controller -> Service -> DTO -> Repository -> Entity -> DB




💙 Spring Boot

스프링 프레임워크를 더 쉽고 빠르게 사용할 수 있도록 도와주는 도구(프레임워크)

기존 Spring Framework는 유연하지만, 설정 파일(XML)이 많고, 초기 환경 구성에 시간이 오래 걸리고, 실행하려면 외부 Tomcat 서버가 필요하다.
Spring Boot는 복잡한 설정을 최소화하고, 빠르게 애플리케이션을 개발,배포할 수 있도록 도와준다.

💙 특징

  • 자동 설정 (Auto Configuration)
    대부분의 설정을 자동으로 처리해준다.
    application.properties 또는 application.yml만 설정해도 동작한다.
  • 스타터 의존성 (Starter)
    필요한 기능을 쉽게 사용할 수 있도록 묶어둔 의존성 모음
    spring-boot-start-web, spring-boot-starter-data-jpa
  • 내장 서버
    톰캣(Tomcat), Jetty, Undertow 등이 포함되어 있어 jar 파일 실행만으로 서버 실행 가능
  • 프로덕션 준비 기능
    헬스 체크, 모니터링, 메트릭 등을 제공하는 Spring Boot Actuator 지원
  • 운영 편의성
    설정 중심 개발 -> 빠른 개발과 테스트 가능
@SpringBootApplication  // @Configuration + @EnableAutoConfiguration + @ComponentScan
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args); // 내장 서버 실행
    }
}

@SpringBootApplication : 스프링 부트의 핵심 어노테이션. 설정과 컴포넌트 스캔 등을 포함
SpringApplication.run(...) : 내장 서버(Tomcat 등)를 실행하여 애플리케이션 구동

자주 사용하는 Starter

Starter설명
spring-boot-starter-web웹 애플리케이션 (MVC 포함)
spring-boot-starter-data-jpaJPA 사용을 위한 기본 설정
spring-boot-starter-security보안 설정 (로그인/인가 등)
spring-boot-starter-test테스트 관련 라이브러리 (JUnit, Mockito 등)
spring-boot-starter-thymeleaf템플릿 엔진 Thymeleaf 사용

spring-boot-starter-web

웹 애플리케이션 개발에 필요한 필수 라이브러리들을 묶어놓은 Starter

포함된 주요 라이브러리

라이브러리설명
Spring MVC웹 애플리케이션 구조 (Controller, RestController 등)
JacksonJSON 변환 (Java ↔ JSON 자동 매핑)
Validation (spring-boot-starter-validation)입력값 검증 (@Valid, @NotNull 등)
Tomcat (내장)내장 웹 서버 (별도 설치 없이 실행 가능)

💙 Spring Boot와 기존 Spring Framework 차이

항목Spring FrameworkSpring Boot
설정 방식XML 또는 자바 설정 클래스 필요자동 설정 + 최소한의 설정
서버 배포WAR 파일을 만들어 WAS에 배포내장 톰캣으로 JAR 실행 가능 (java -jar)
시작 속도복잡하고 설정이 많음빠르게 시작 가능 (개발 친화적)
구조 설계개발자가 일일이 설정대부분 자동으로 구성됨

💙 Lombok

자바에서 반복되는 코드(보일러플레이트, boilerplate)를 자동으로 생성해주는 라이브러리

다양한 어노테이션을 통해 코드 간결성, 생산성, 가독성을 높여준다.

주요 어노테이션

어노테이션설명
@Getter, @Setter필드에 대해 getter, setter 자동 생성
@ToStringtoString() 메서드 자동 생성
@EqualsAndHashCodeequals(), hashCode() 자동 생성
@NoArgsConstructor파라미터 없는 생성자 자동 생성
@AllArgsConstructor모든 필드를 파라미터로 받는 생성자 생성
@RequiredArgsConstructorfinal 또는 @NonNull 필드만 포함한 생성자 생성
@Data@Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor 조합
@Builder빌더 패턴 지원 (체이닝 방식 생성자)
@Slf4j로그 객체 log 자동 생성 (log.info() 등 사용 가능)

주의사항

  • IDE 플러그인 설치 필요
  • 코드가 자동 생성되어 디버깅 시 보이지 않음
  • 공식 문서에서 각 어노테이션의 사용 조건 확인이 필요

설치 (Gradle)

dependencies {
    compileOnly 'org.projectlombok:lombok:1.18.30' // 최신 버전 확인
    annotationProcessor 'org.projectlombok:lombok:1.18.30'
}

💙 enum

Java에서 열거형(Enumeration)을 정의할 때 사용하는 특수한 클래스

미리 정의된 상수들의 집합을 만들귀 위한 클래스이다.
ex) 요일, 상태값, 등급 등

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

// 사용법
// Day.MONDAY

enum 사용하는 이유

  • 가독성 향상 : 코드에 의미 있는 이름 부여 가능
  • 타입 안전성 보장 : 지정된 상수 외에는 허용되지 않음 (컴파일 시 에러)
  • switch 문 사용 가능 : 각 enum 값에 따라 분기 처리
  • 값 비교 용이 : == 연산자로 비교 가능 (주소 비교 OK)
  • 클래스처럼 필드, 생성자, 메소드 포함 가능 : 확장 가능성 있음

// 필드와 메소드 가진 enum
public enum Grade {
    BASIC(0),
    SILVER(1),
    GOLD(2);

    private final int level;

    // 생성자
    Grade(int level) {
        this.level = level;
    }

    public int getLevel() {
        return level;
    }
}

Grade g = Grade.GOLD;
System.out.println(g);             // GOLD
System.out.println(g.getLevel());  // 2

switch (g) {
    case BASIC:
        System.out.println("기본 회원");
        break;
    case GOLD:
        System.out.println("골드 회원");
        break;
}

💙 Repository 설계

DAO 역할을 하는 Repository 인터페이스 설계

JpaRepository 또는 CrudRepository를 상속받아 데이터 접근 기능을 갖는 인터페이스를 정의한다.

제네릭 타입

첫 번째 제네릭에 엔티티 클래스,
두 번째 제네릭에 기본키 타입을 넣어
데이터 접근 기능을 설계한다.


@Entity
public class User {
    @Id
    private Long id;
    private String name;
    // ... 기타 필드
}


public interface UserRepository extends JpaRepository<User, Long> { 
	 // 기본적인 CRUD 메서드는 자동 생성됨
     // 추가로 사용자 정의 메서드 작성 가능
}

위치제네릭 타입의미
첫 번째User엔티티 클래스 이름 (DB 테이블과 매핑되는 클래스)
두 번째Long기본키(PK)의 타입 (@Id에 해당하는 필드 타입)

Spring Data JPA

구현 클래스 없이 인터페이스만 작성해도 동작한다.

Spring이 런타임에 자동으로 구현체를 생성해주기 때문

Dynamic Proxy (동적 프록시)

자바에서 Proxy클래스를 사용하면 인터페이스 기반으로 런타임에 클래스 없이 객체를 생성할 수 있다.

이 기능을 활용하여 Spring은 인터페이스에 대한 구현체를 자동으로 생성한다.

UserRepository repo = new 프록시_객체();
repo.findByUsername("kim");  // -> 내부적으로 쿼리 생성해서 DB 호출

🤍 회고

오늘은 스프링 부트와 JPA에 대해 공부했다.
스프링 부트는 복잡한 설정 없이 빠르게 웹 애플리케이션을 시작할 수 있게 해주며, 내장 톰캣과 자동 설정 기능이 있다. JPA는 객체와 테이블을 매핑하여 SQL 없이도 데이터베이스를 다룰 수 있게 해주고, 생산성과 유지보수성을 높여준다. 특히 Spring Data JPA는 Repository 인터페이스만 정의하면 동적 프록시로 구현체를 자동 생성해주는 점이 편리했다. 쿼리 메서드나 @Query를 통해 다양한 방식으로 쿼리를 작성할 수 있는 것도 유용했다.
전체적으로 반복되는 코드가 줄고 구조가 깔끔해져 실무에 유용하겠다는 생각이 들었다.

profile
친애하는 개발자

0개의 댓글