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를 쉽게 사용할 수 있도록 지원한다. 이를 통해 데이터베이스와 상호작용을 간편하게 구현할 수 있고 코드를 간소화할 수 있다.

- JPA 추상화 Repository 제공
- CrudRepository, JpaRepository 인터페이스를 제공한다.
- SQL이나 EntityManager를 직접 호출하지 않아도 기본적인 CRUD 기능을 손쉽게 구현할 수 있다.
- JPA 구현체와 통합
- 일반적으로 Hibernate를 통해 자동으로 SQL이 생성된다.
- QueryMethods
- Method 이름만으로 SQL을 자동으로 생성한다.
- @Query 를 사용하여 JPQL 또는 Native Query를 정의할 수 있다.
- 복잡한 SQL을 직접 구현할 때 사용
- 트랜잭션 관리와 LazyLoading
- 트랜잭션 기능을 Spring과 통합하여 제공한다.
- 연관된 Entity를 필요할 때 로딩하는 지연로딩 기능을 지원한다.
✅ SimpleJpaRepository ⭐
Spring Data JPA의 기본 Repository 구현체로 JpaRepository 인터페이스의 기본 메서드들을 실제로 수행하는 클래스이다. 내부적으로 EntityManager를 사용하여 JPA Entity를 DB에 CRUD 방식으로 저장하고 관리하는 기능을 제공


- 사용방법
- Repository를 interface로 선언한다.
- 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에서 구현된다.
- 해석
- find : Entity에 매핑된 테이블(member)을 조회한다.
- ByName : 조건은 member 테이블의 name 필드이다.
- AndAddress : 또다른 조건은 member 테이블의 address 필드이다.
✅ Spring Data JPA Auditing
엔티티의 생성 및 수정 시간을 자동으로 관리해주는 기능입니다. 이를 통해 개발자는 엔티티가 언제 생성되고 수정되었는지를 자동으로 추적할 수 있다.
- 사용하는 Annotation
- @EnableJpaAuditing
- JPA Auditing 기능을 활성화 한다.
- @MappedSuperClass
- 해당 어노테이션이 선언된 클래스를 상속받는 Entity에 공통 매핑 정보를 제공한다.
- @EntityListeners(AuditingEntityListener.class)
- Entity를 DB에 적용하기 전, 커스텀 콜백을 요청할 수 있는 어노테이션
- AuditingEntityListener
- Auditing 기능을 사용할 수 있도록 Listener를 설정한다.
- 내부적으로 @PrePersist 을 사용한다.
- @CreatedDate
- 생성 시점의 날짜를 자동으로 기록한다.
- @LastModifiedDate
- 수정 시점의 날짜를 자동으로 기록한다.
- @Temporal
- 날짜 타입을 세부적으로 지정한다 (DATE, TIME, TIMESTAMP 등)
- @CreatedBy
- Entity 생성자의 정보를 자동으로 저장한다.
- 생성하는 주체를 지정하기 위해서 AuditorAware<T> 를 지정해야 한다.
- Spring Security에서 다루는 내용
- @LastModifiedBy
- 마지막 수정자의 정보를 자동으로 저장한다.
- 생성하는 주체를 지정하기 위해서 AuditorAware<T> 를 지정해야 한다.
- Spring Security에서 다루는 내용
- @EnableJpaAuditing
⚡ 적용하기 ⚡
[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인 객체를 참조하려고 할 때 발생하는 예외 입니다.

✅ 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 |