Spring Boot JPA는 Spring Data JPA의 간단하고 강력한 사용법을 제공하는 도구입니다. JPA(Java Persistence API)는 Java에서 객체를 관계형 데이터베이스에 매핑할 수 있도록 설계된 ORM(Object-Relational Mapping) 기술 표준입니다. Spring Data JPA는 이를 기반으로 데이터 액세스를 더 간편하게 만들고, Spring Boot는 설정을 최소화하여 개발 속도를 높여줍니다.
Spring Data JPA
Spring Data JPA는 JPA를 기반으로 데이터 액세스 계층을 단순화합니다.
예를 들어, CrudRepository나 JpaRepository와 같은 인터페이스를 통해 기본적인 CRUD(Create, Read, Update, Delete) 작업을 구현할 수 있습니다.
Hibernate
Hibernate는 JPA의 구현체 중 하나로, Spring Boot에서 기본적으로 사용됩니다. JPA는 표준이고, Hibernate는 실제로 이를 실행하는 라이브러리입니다.
Entity
데이터베이스 테이블과 매핑되는 클래스입니다.
예시
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Getters and Setters
}
Repository
데이터베이스와의 상호작용을 담당하는 계층입니다.
예시
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByName(String name);
}
JPQL(Java Persistence Query Language)
객체지향 쿼리 언어로, SQL과 비슷하지만 엔티티를 대상으로 작업합니다.
자동 구성(Auto Configuration)
Spring Boot는 spring-boot-starter-data-jpa 의존성을 추가하면 JPA와 관련된 대부분의 설정을 자동으로 구성합니다.
간단한 CRUD
JpaRepository를 상속받기만 하면 기본 CRUD 메서드를 바로 사용할 수 있습니다.
JPQL 및 Native Query 지원
복잡한 쿼리도 JPQL 또는 네이티브 SQL로 작성할 수 있습니다.
트랜잭션 관리
Spring Boot JPA는 트랜잭션 관리를 쉽게 처리하며, @Transactional 어노테이션으로 특정 메서드나 클래스에 트랜잭션 처리를 적용할 수 있습니다.
페이징 및 정렬 지원
데이터 페이징 및 정렬을 쉽게 처리할 수 있는 기능을 제공합니다.
Page<User> findByEmail(String email, Pageable pageable);
@Entity
@Entity
로 선언해야 합니다.@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
@Table
로 다른 이름을 지정할 수 있습니다.@Entity
@Table(name = "users")
public class User {
@Id
private Long id;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
AUTO
: JPA 구현체에 따라 자동으로 생성 전략 선택.IDENTITY
: 데이터베이스의 IDENTITY 열 사용.SEQUENCE
: 데이터베이스 시퀀스를 사용.TABLE
: 키 생성 전용 테이블 사용.@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
name
: 열 이름.nullable
: NULL 허용 여부.unique
: 유니크 제약 조건.length
: 문자열 길이 (기본 255).@Column(name = "username", nullable = false, unique = true, length = 100)
private String name;
@Transient
private int temporaryField;
@OneToOne
mappedBy
: 관계의 주인이 아닌 경우 사용.cascade
: 연관된 엔티티를 함께 저장/삭제.@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "profile_id")
private Profile profile;
@OneToMany
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Order> orders;
@ManyToOne
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@ManyToMany
@JoinTable
)을 사용합니다.@ManyToMany
@JoinTable(
name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles;
@Query
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);
@NamedQuery(
name = "User.findByEmail",
query = "SELECT u FROM User u WHERE u.email = :email"
)
@Entity
public class User {
@Id
private Long id;
}
@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);
@EntityListeners(AuditingEntityListener.class)
와 함께 사용해야 합니다.@EntityListeners(AuditingEntityListener.class)
@Entity
public class User {
@CreatedDate
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
@CreatedBy
private String createdBy;
@LastModifiedBy
private String modifiedBy;
}
@Embeddable
public class Address {
private String city;
private String state;
}
@Entity
public class User {
@Embedded
private Address address;
}
SINGLE_TABLE
: 하나의 테이블에 모든 엔티티 저장.TABLE_PER_CLASS
: 각 엔티티마다 별도의 테이블 생성.JOINED
: 상속 구조에 따라 테이블 연결.@Inheritance(strategy = InheritanceType.JOINED)
@Entity
public class User { ... }