241115 TIL - Spring Data JPA 정리

J_log·2024년 11월 15일
0
post-thumbnail

JPA란 무엇인가?

JPA는 Java Persistence API의 약자로, 자바 어플리케이션에서 데이터베이스와 상호작용하기 위한 표준이다.
ORM 기술을 기반으로 동작하며, 자바 객체와 데이터베이스 테이블 간의 매핑을 간단히 처리할 수 있도록 도와준다.

JPA의 장점

  • 데이터베이스 테이블과 자바 객체를 매핑해 반복적인 SQL 쿼리 작성을 줄여준다.
  • 객체 중심의 프로그래밍 환경을 제공한다.
  • 데이터베이스 구조 변경이 코드 전반에 미치는 영향을 최소화해서 유지보수성이 향상된다.

Spring Data JPA는 JPA 위에서 동작하며, 레포지토리 인터페이스를 통해 데이터 접근 계층을 쉽게 구현할 수 있도록 도와준다.


JPA @Entity와 @Column 사용법

JPA의 기본은 Entity이다. 엔티티는 데이터베이스 테이블과 1:1로 매핑되는 자바 클래스이다. 그럼 @Entity, @Column 어노테이션을 이용해 엔티티 클래스를 정의해보자.

@Entity

@Entity 어노테이션은 해당 클래스가 JPA에서 관리되는 엔티티임을 명시한다.

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 50)
    private String name;

    @Column(unique = true, nullable = false)
    private String email;

    // 기본 생성자
    protected User() {}

    public User(String name, String email) {
    	this.name = name;
        this.email = email;
    }
}
  1. 기본 생성자 필요 : JPA는 내부적으로 리플렉션을 사용하므로 기본 생성자가 반드시 있어야 한다. public or protected로 선언할 수 있지만 protected로 선언하는 것이 권장된다.
  • protected로 선언할 때의 장점
    • 외부에서는 기본 생성자에 접근할 수 없어서 불필요한 객체 생성을 방지한다.
    • JPA는 여전히 기본 생성자에 접근할 수 있다(리플렉션 사용)
    • 객체 생성 방법을 명시적으로 제한(팩토리 메서드나 다른 생성자 사용 유도)
  1. @Id필드 필수 : 데이터베이스 테이블의 기본 키를 설정해야 한다.
  2. @GeneratedValue : 기본 키 생성 전력을 지정한다. (auto_increment)

@Column

@Column 어노테이션은 데이터베이스 컬럼의 속성을 설정한다. (생략하면 기본 설정이 적용)

  • nullable : false일 경우 NOT NULL 제약 조건 추가
  • unique : true일 경우 UNIQUE 제약 조건 추가
  • length : 문자열 타입의 최대 길이 지정

Spring Data JPA로 Repository 구현

Spring Data JPA는 JpaRepository 인터페이스를 통해 데이터 접근 계층을 간단히 구현할 수 있도록 도와준다.

Repository란?

Repository는 데이터베이스에 접근하는 로직을 추상화한 인터페이스이다.
JpaRepository는 CRUD 메서드를 기본으로 제공하며, 복잡한 쿼리도 메서드 이름만으로 작성할 수 있다.

public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);
}

커스텀 쿼리

복잡한 조건이 필요하면 @Query를 활용해 커스텀 쿼리를 작성할 수 있다.

@Query("SELECT u FROM User u WHERE u.email = :email AND u.name = :name")
Optional<User> findByEmailAndName(@Param("email") String email, @Param("name") String name);

0개의 댓글