[Spring Boot] JPA

handa·2024년 12월 12일
0
post-thumbnail

Spring Boot JPA는 Spring Data JPA의 간단하고 강력한 사용법을 제공하는 도구입니다. JPA(Java Persistence API)는 Java에서 객체를 관계형 데이터베이스에 매핑할 수 있도록 설계된 ORM(Object-Relational Mapping) 기술 표준입니다. Spring Data JPA는 이를 기반으로 데이터 액세스를 더 간편하게 만들고, Spring Boot는 설정을 최소화하여 개발 속도를 높여줍니다.


주요 구성 요소

  1. Spring Data JPA
    Spring Data JPA는 JPA를 기반으로 데이터 액세스 계층을 단순화합니다.
    예를 들어, CrudRepository나 JpaRepository와 같은 인터페이스를 통해 기본적인 CRUD(Create, Read, Update, Delete) 작업을 구현할 수 있습니다.

  2. Hibernate
    Hibernate는 JPA의 구현체 중 하나로, Spring Boot에서 기본적으로 사용됩니다. JPA는 표준이고, Hibernate는 실제로 이를 실행하는 라이브러리입니다.

  3. Entity
    데이터베이스 테이블과 매핑되는 클래스입니다.
    예시

      @Entity
      public class User {
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          private Long id;
    
          private String name;
          private String email;
    
          // Getters and Setters
      }
  4. Repository
    데이터베이스와의 상호작용을 담당하는 계층입니다.
    예시

    public interface UserRepository extends JpaRepository<User, Long> {
       List<User> findByName(String name);
    }
  5. JPQL(Java Persistence Query Language)
    객체지향 쿼리 언어로, SQL과 비슷하지만 엔티티를 대상으로 작업합니다.


주요 특징

  1. 자동 구성(Auto Configuration)
    Spring Boot는 spring-boot-starter-data-jpa 의존성을 추가하면 JPA와 관련된 대부분의 설정을 자동으로 구성합니다.

  2. 간단한 CRUD
    JpaRepository를 상속받기만 하면 기본 CRUD 메서드를 바로 사용할 수 있습니다.

  3. JPQL 및 Native Query 지원
    복잡한 쿼리도 JPQL 또는 네이티브 SQL로 작성할 수 있습니다.

  4. 트랜잭션 관리
    Spring Boot JPA는 트랜잭션 관리를 쉽게 처리하며, @Transactional 어노테이션으로 특정 메서드나 클래스에 트랜잭션 처리를 적용할 수 있습니다.

  5. 페이징 및 정렬 지원
    데이터 페이징 및 정렬을 쉽게 처리할 수 있는 기능을 제공합니다.

    Page<User> findByEmail(String email, Pageable pageable);

1. Entity 관련 어노테이션

1.1 @Entity

  • 데이터베이스 테이블과 매핑되는 클래스임을 지정합니다.
  • JPA에서 엔티티는 반드시 @Entity로 선언해야 합니다.
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
}

1.2 @Table

  • 엔티티와 매핑될 데이터베이스 테이블의 이름을 지정합니다.
  • 기본적으로 클래스 이름과 같은 이름의 테이블로 매핑되지만, @Table로 다른 이름을 지정할 수 있습니다.
@Entity
@Table(name = "users")
public class User {
    @Id
    private Long id;
}

1.3 @Id

  • 엔티티의 기본 키를 지정합니다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

1.4 @GeneratedValue

  • 기본 키 값을 자동으로 생성하는 전략을 설정합니다.
  • 주요 전략:
    • AUTO : JPA 구현체에 따라 자동으로 생성 전략 선택.
    • IDENTITY : 데이터베이스의 IDENTITY 열 사용.
    • SEQUENCE : 데이터베이스 시퀀스를 사용.
    • TABLE : 키 생성 전용 테이블 사용.
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

1.5 @Column

  • 데이터베이스 열(Column)의 속성을 정의합니다.
  • 주요 속성:
    • name : 열 이름.
    • nullable : NULL 허용 여부.
    • unique : 유니크 제약 조건.
    • length : 문자열 길이 (기본 255).
@Column(name = "username", nullable = false, unique = true, length = 100)
private String name;

1.6 @Transient

  • 매핑에서 제외될 필드를 지정합니다.
  • 데이터베이스에 저장되지 않으며, 런타임에서만 사용됩니다.
@Transient
private int temporaryField;

2. 관계 매핑 관련 어노테이션

2.1 @OneToOne

  • 두 엔티티 간의 1:1 관계를 매핑합니다.
  • mappedBy : 관계의 주인이 아닌 경우 사용.
  • cascade : 연관된 엔티티를 함께 저장/삭제.
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "profile_id")
private Profile profile;

2.2 @OneToMany

  • 하나의 엔티티가 여러 엔티티와 관계를 가질 때 사용합니다.
  • 일반적으로 mappedBy 속성을 사용하여 관계의 주인을 설정합니다.
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Order> orders;

2.3 @ManyToOne

  • 여러 엔티티가 하나의 엔티티와 관계를 가질 때 사용합니다.
@ManyToOne
@JoinColumn(name = "user_id")
private User user;

2.4 @ManyToMany

  • 다대다 관계를 매핑합니다.
  • 일반적으로 중간 테이블(@JoinTable)을 사용합니다.
@ManyToMany
@JoinTable(
    name = "user_roles",
    joinColumns = @JoinColumn(name = "user_id"),
    inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles;

3. 쿼리 관련 어노테이션

3.1 @Query

  • JPQL 또는 네이티브 SQL 쿼리를 직접 지정할 때 사용합니다.
  • 네이티브 쿼리는 nativeQuery = true로 설정합니다.
@Query("SELECT u FROM User u WHERE u.name = :name")
List<User> findByName(@Param("name") String name);

@Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true)
List<User> findByNameNative(@Param("name") String name);

3.2 @NamedQuery와 @NamedQueries

  • 엔티티에 정의된 이름 있는 쿼리를 설정합니다.
@NamedQuery(
    name = "User.findByEmail",
    query = "SELECT u FROM User u WHERE u.email = :email"
)
@Entity
public class User {
    @Id
    private Long id;
}

3.3 @Modifying

  • @Query와 함께 사용하여 데이터베이스를 수정하는 작업을 정의합니다.
  • INSERT, UPDATE, DELETE 쿼리에 사용됩니다.
@Modifying
@Query("UPDATE User u SET u.name = :name WHERE u.id = :id")
int updateUserName(@Param("id") Long id, @Param("name") String name);

4. Audit 관련 어노테이션

4.1 @CreatedDate와 @LastModifiedDate

  • 엔티티 생성 및 수정 시간을 자동으로 관리합니다.
  • @EntityListeners(AuditingEntityListener.class)와 함께 사용해야 합니다.
@EntityListeners(AuditingEntityListener.class)
@Entity
public class User {
    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;
}

4.2 @CreatedBy와 @LastModifiedBy

  • 엔티티 생성자 및 수정자를 기록합니다.
@CreatedBy
private String createdBy;

@LastModifiedBy
private String modifiedBy;
}

5. 기타 어노테이션

5.1 @Embeddable와 @Embedded

  • 재사용 가능한 값 타입을 정의하고 사용할 때 사용합니다.
@Embeddable
public class Address {
    private String city;
    private String state;
}

@Entity
public class User {
    @Embedded
    private Address address;
}

5.2 @Inheritance

  • 상속 관계를 매핑할 때 사용합니다.
  • 전략
    • SINGLE_TABLE : 하나의 테이블에 모든 엔티티 저장.
    • TABLE_PER_CLASS : 각 엔티티마다 별도의 테이블 생성.
    • JOINED : 상속 구조에 따라 테이블 연결.
@Inheritance(strategy = InheritanceType.JOINED)
@Entity
public class User { ... }

Spring Boot JPA의 장점

  1. 빠른 개발 : 코드 작성량이 줄어듭니다.
  2. 유연한 데이터베이스 변경 : 데이터베이스에 의존하지 않고 객체 중심으로 개발이 가능합니다.
  3. 강력한 커뮤니티 : Spring Boot와 JPA는 활발한 커뮤니티 지원을 받고 있습니다.
profile
진짜 해보자

0개의 댓글