TIL 30 [ Spring ( Data JPA ), 스탠다드반 ( Optional ) ]

2025. 4. 1. 16:43·[내일배움캠프-Sparta]/Spring 6기
반응형

1️⃣ Spring Data JPA

✅ Spring Boot와 JPA

Spring Boot는 JPA 설정을 자동으로 구성해 주어 JPA를 쉽게 사용할 수 있도록 도와주며, 기본적으로 필요한 EntityManagerFactory와 TransactionManager를 자동으로 설정하고 데이터베이스 관련 설정을 application.properties 파일에서 간단히 지정할 수 있게 해준다.

 

  • JPA는 Spring에 종속적인 것이 아니다.
  • Spring Boot 에서 JPA를 사용하기 위해서는 build.gradle에 의존성 추가가 필요하다.
    • spring-boot-starter-data-jpa
    • 필요한 JPA 설정과 Entity 관리를 자동으로 해준다.
  • 자동으로 내부에서 EntityManagerFactory 를 하나만 생성해서 관리(싱글톤)한다.
    • 자동으로 Bean으로 등록된다.
    • 직접 만들지 않아도 된다.
    • 직접 연결을 close() 하지 않아도 된다.
    • application.properties 에 설정된 DB 정보로 생성된다.
  • @PersistenceContext를 통해 자동으로 생성된 EntityManager를 주입받아 사용할 수 있다.

✅ Spring Data JPA

Spring Data JPA는 Spring Framework에서 제공하는 모듈로 JPA를 쉽게 사용할 수 있도록 지원한다. 이를 통해 데이터베이스와 상호작용을 간편하게 구현할 수 있고 코드를 간소화할 수 있다.

  1. JPA 추상화 Repository 제공
    • CrudRepository, JpaRepository 인터페이스를 제공한다.
    • SQL이나 EntityManager를 직접 호출하지 않아도 기본적인 CRUD 기능을 손쉽게 구현할 수 있다.
  2. JPA 구현체와 통합
    • 일반적으로 Hibernate를 통해 자동으로 SQL이 생성된다.
  3. QueryMethods
    • Method 이름만으로 SQL을 자동으로 생성한다.
    • @Query 를 사용하여 JPQL 또는 Native Query를 정의할 수 있다.
      • 복잡한 SQL을 직접 구현할 때 사용
  4. 트랜잭션 관리와 LazyLoading
    • 트랜잭션 기능을 Spring과 통합하여 제공한다.
    • 연관된 Entity를 필요할 때 로딩하는 지연로딩 기능을 지원한다.

✅ SimpleJpaRepository  ⭐

Spring Data JPA의 기본 Repository 구현체로 JpaRepository 인터페이스의 기본 메서드들을 실제로 수행하는 클래스이다. 내부적으로 EntityManager를 사용하여 JPA Entity를 DB에 CRUD 방식으로 저장하고 관리하는 기능을 제공

  •  사용방법
    1. Repository를 interface로 선언한다.
    2. JpaRepository<[@Entity 클래스], [@Id 데이터 타입]> 상속 ⭐
public interface MemberRepository extends JpaRepository<Member, Long> {
}

 

  • Spring이 실행되면서 JpaRepository 인터페이스를 상속받은 인터페이스가 있다면, 해당 인터페이스의 정보를 토대로 SimpleJpaRepository 를 생성하고 Bean으로 등록한다.
  • 인터페이스의 구현 클래스를 직접 만들지 않아도 JpaRepository 의 기능을 사용할 수 있다.
  • 개발자가 직접 SimpleJpaRepository를 사용하거나 참조할 필요는 없다
  • save() : 대상 Entity를 DB 테이블에 저장한다.
  • findAll() : Entity에 해당하는 테이블의 모든 데이터를 조회한다.
  • delete() : 대상 Entity를 데이터베이스에서 삭제한다.
  • 이외에도 수많은 기능(Paging, Sorting 등)이 있다.

✅ Query Methods

Spring Data JPA에서 메서드 이름을 기반으로 데이터베이스 쿼리를 자동 생성하는 기능이다. 직접 SQL을 작성하지 않고도 복잡한 쿼리를 쉽게 수행할 수 있게된다.

  • Spring Data JPA에서 메서드 이름을 기반으로 SQL을 자동으로 생성하는 기능
  • JpaRepository는 findAll(), save()와 같은 기본적인 기능만 제공한다.
  • 실제 Application 개발에는 상황에 따라 조건에 맞는 메서드가 필요하다.

  • JpaRepository의 제네릭에 선언된 Entity와 매핑되는 테이블의 SQL이 생성된다.
  • 개발자가 규칙에 맞게 메서드를 선언하면 SimpleJpaRepository에서 구현된다.
  • 해석
    1. find : Entity에 매핑된 테이블(member)을 조회한다.
    2. ByName : 조건은 member 테이블의 name 필드이다.
    3. AndAddress : 또다른 조건은 member 테이블의 address 필드이다.

✅ Spring Data JPA Auditing 

엔티티의 생성 및 수정 시간을 자동으로 관리해주는 기능입니다. 이를 통해 개발자는 엔티티가 언제 생성되고 수정되었는지를 자동으로 추적할 수 있다.

  • 사용하는 Annotation
    1. @EnableJpaAuditing
      • JPA Auditing 기능을 활성화 한다.
    2. @MappedSuperClass
      • 해당 어노테이션이 선언된 클래스를 상속받는 Entity에 공통 매핑 정보를 제공한다.
    3. @EntityListeners(AuditingEntityListener.class)
      • Entity를 DB에 적용하기 전, 커스텀 콜백을 요청할 수 있는 어노테이션
      • AuditingEntityListener
        • Auditing 기능을 사용할 수 있도록 Listener를 설정한다.
        • 내부적으로 @PrePersist 을 사용한다.
    4. @CreatedDate
      • 생성 시점의 날짜를 자동으로 기록한다.
    5. @LastModifiedDate
      • 수정 시점의 날짜를 자동으로 기록한다.
    6. @Temporal
      • 날짜 타입을 세부적으로 지정한다 (DATE, TIME, TIMESTAMP 등)
    7. @CreatedBy
      • Entity 생성자의 정보를 자동으로 저장한다.
      • 생성하는 주체를 지정하기 위해서 AuditorAware<T> 를 지정해야 한다.
      • Spring Security에서 다루는 내용
    8. @LastModifiedBy
      • 마지막 수정자의 정보를 자동으로 저장한다.
      • 생성하는 주체를 지정하기 위해서 AuditorAware<T> 를 지정해야 한다.
      • Spring Security에서 다루는 내용

⚡ 적용하기 ⚡

[1] @EnableJpaAuditing

@EnableJpaAuditing  // 선언
@SpringBootApplication
public class SpringDataJpaApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringDataJpaApplication.class, args);
    }

}
  • Spring Data JPA에서 Auditing을 적용할 때 사용하는 어노테이션
  • 일반적으로 Spring Boot를 실행하는 Application 클래스 상단에 선언한다.

[2] BaseEntity 생성

@Getter
@MappedSuperclass // 선언
@EntityListeners(AuditingEntityListener.class) // 선언
public abstract class BaseEntity { // 추상클래스로 선언

    @CreatedDate // 생성일
    @Column(updatable = false) // 생성일 수정 못하게 설정
    @Temporal(TemporalType.TIMESTAMP) 
    private LocalDateTime createdAt;

    @LastModifiedDate // 수정일
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime modifiedAt;
}
  • updatable = false 설정으로 생성 시간이 수정되지 못하게 설정한다.

[3] BaseEntity 상속

@Entity
public class User extends BaseEntity{ // BaseEntity 상속
    @Id
    private Long id;
    private String name;
}
  • createdAt, modifedAt 필드를 가지게 된다.
  • 상속받는 것만으로 생성, 수정 시간을 자동으로 생성할 수 있다.

📣 스탠다드반 (Optional)

Null은 "없음, 무효"를 뜻하며, 15세기부터 사용되던 개념.

프로그래밍 언어에서 최초의 Null

1965년 토니 호어(Tony Hoare)가 Algol W 언어(이후 Pascal에 영향을 줌)를 개발하면서 Null 개념을 도입

객체지향 언어에서 참조형 변수가 특정 객체를 가리키지 않을 때 이를 표현하는 방법이 당시에는 없었습니다. 토니 호어는 이를 표현하기 위헤 가장 간단한 방법인 Null을 도입하였습니다.

이후에 C, Java, Pascal을 포함하여 많은 프로그래밍 언어에서 Null 개념을 도입

❌ NPE ( Null Pointer Exception )

Null인 객체를 참조하려고 할 때 발생하는 예외 입니다.

 

Arrow Anti Pattern ( 이렇게 코드 작성은 지양해야함! ! )

✅ Optional 

이런 문제들로 인해 자바 진영에서는 이를 해결할 수 있는 방법에 대해서 고민을 하게 되었습니다.

그 결과로 Optional이 탄생하게 됩니다.

Null 참조의 문제점을 해결하고 코드의 안정성과 가독성을 개선을 위함이었습니다.

Optional은 자바 8부터 쓸 수 있습니다.

🟡메소드🟡

생성

메소드 설명
empty() 빈 Optional 생성
of(T value) null을 허용하지 않는 Optional<T> 생성. value가 null인 경우 NPE 발생
ofNullable(T value) null을 허용하는 Optional<T> 생성. value가 null이어어도 Exception 발생하지 않고 orElse() 등으로 처리 가능. 실질적으로 Optional 생성은 대부분 이것으로 한다.

 

// 메뉴 null 일수도 있는 애야.
// if(value == null) 이거 할 필요가 없음.
Optional<Object> nullValue = Optional.empty(); // null 과 같음.
Optional<Long> opValue = Optional.of(1L);
Optional<Long> nullOpValue = Optional.ofNullable(null);

 

활용 ⭐ ( 6개 가장많이 쓰임 )

메소드 설명
isPresent(); 값의 null 여부를 판단하는 메소드, null이면 false, 있으면 true 반환
isEmpty(); isPresent()와 반대개념. null이면 true, 값이 있으면 false 반환
get(); 값을 리턴함. null인 값을 get() 하는 경우 NoSuchElementException 발생
orElse(T other)  값이 있으면 주고, 값이 없는 경우 리턴할 기본 값을 지정한다.
orElseGet(Supplier )  값이 없는 경우 리턴할 기본 값을 지정한다. other는 값이 없는 경우에만 생성된다. 일반적으로 orElse보다 이것을 쓰는 것이 더 낫다.
orElseThrow( ) 값이 없는 경우 예외를 발생 시킨다.

이외에도 ifPresent, filter, map 여러개 있지만 잘 쓰이지 않는다. ( 특정한 상황이 아니면 )

Optional<Object> emptyValue = Optional.empty(); // null 과 같음.
Optional<Long> opValue1 = Optional.of(1L);
Optional<String> opValue3 = Optional.of("");
Optional<Long> opValue2 = Optional.ofNullable(null);

emptyValue.isPresent(); // false
opValue1.isPresent(); // true
opValue3.isPresent(); // true
opValue2.isEmpty(); // true

Long value = opValue1.get(); // value == 1
Long value2  = opValue2.get(); // error

 

❗❗  "" 빈 문자열은 null 이 아니기 때문에 true 

🔴 Optional의 단점

NPE를 방지하고 여러 체이닝(Chaining)을 통해 원하는 값을 한줄로 처리할 수 있는 장점이 많은 Optional이지만 단점도 존재합니다. 이번에는 단점에 대해서 알아 보겠습니다.

1. 객체 생성 비용 발생

원래의 값을 Optional로 감싸는 래퍼 클래스입니다.

이에 따라 새로운 객체를 생성합니다.

2. 박싱/언방식 비용 발생

래퍼 클래스이므로 값을 다룰 때 박싱/언박싱이 발생합니다.

과도하게 Optional을 처리하는 경우 이 비용으로 오버헤드가 발생할 수 있습니다.

3. 메모리 사용량 증가

앞서 1번 문제와 동일한 내용인데, 추가 객체를 생성하기 때문에 메모리를 더 사용하게 됩니다.

메모리 사용의 증가는 필연히 GC 개입 확률이 더 올라가는 것을 의미하므로 전체적인 성능저하가 발

반응형

'[내일배움캠프-Sparta] > Spring 6기' 카테고리의 다른 글

TIL 32 [ Spring 일정관리 앱 Lv2~5 ]  (0) 2025.04.04
TIL 31 [ Spring 일정관리 앱 Lv0 ~ 1, + 미니세션 ( 예외처리 ) ]  (0) 2025.04.02
TIL 29 [ Spring ( Filter, 객체와 RDB, JPA , 영속성 컨텍스트, Entity 제작 ) ]  (0) 2025.03.31
Spring ( Session, Token, JWT )  (0) 2025.03.30
TIL 28 [ Spring ( Bean Validation, Cookie ) ]  (0) 2025.03.28
'[내일배움캠프-Sparta]/Spring 6기' 카테고리의 다른 글
  • TIL 32 [ Spring 일정관리 앱 Lv2~5 ]
  • TIL 31 [ Spring 일정관리 앱 Lv0 ~ 1, + 미니세션 ( 예외처리 ) ]
  • TIL 29 [ Spring ( Filter, 객체와 RDB, JPA , 영속성 컨텍스트, Entity 제작 ) ]
  • Spring ( Session, Token, JWT )
dimenshun
dimenshun
한 소년의 개발 일기
    반응형
  • dimenshun
    Dev Life Notes
    dimenshun
  • 전체
    오늘
    어제
    • 분류 전체보기 (268)
      • CS (23)
        • 자료구조 (0)
        • 알고리즘 (0)
        • 컴퓨터 구조 (8)
        • 네트워크 (6)
        • 운영체제 (3)
        • DB ( + SQLD ) (5)
        • SW공학 (1)
      • 프로그래밍 (3)
        • Java (0)
        • Spring (0)
        • HTML,CSS (3)
        • JavaScript (0)
      • 개발 툴 (7)
        • Git(버전관리) (1)
        • Docker (3)
        • AWS (2)
        • JSP (1)
      • 코딩테스트(Algorithm) (125)
        • 백준 (6)
        • 프로그래머스 (119)
      • [내일배움캠프-Sparta] (110)
        • Spring 6기 (106)
        • KPT 회고 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    KPT
    웹
    docker
    백엔드
    컴퓨터구조
    메모리
    network
    트랜잭션
    Til
    cs
    It
    Python
    네트워크
    코딩테스트
    개발자
    알고리즘
    web
    Java
    배포
    OS
    내일배움캠프
    SQLD
    db
    AWS
    CPU
    spring
    SQL
    Testcode
    운영체제
    세션
  • hELLO· Designed By정상우.v4.10.3
dimenshun
TIL 30 [ Spring ( Data JPA ), 스탠다드반 ( Optional ) ]
상단으로

티스토리툴바