250 lines
6.0 KiB
Markdown
250 lines
6.0 KiB
Markdown
# Spring Boot의 Model 및 JPA Entity
|
|
|
|
|
|
## Model 및 JPA 관련 어노테이션 정리
|
|
|
|
| 어노테이션 | 설명 |
|
|
|------------------------|----------------------------------|
|
|
| `@Entity` | JPA 엔티티 클래스임을 명시 |
|
|
| `@Table` | 데이터베이스의 테이블과 매핑 |
|
|
| `@Id` | 기본 키(PK) 지정 |
|
|
| `@GeneratedValue` | 기본 키 값 자동 생성 전략 설정 |
|
|
| `@Column` | 데이터베이스 컬럼과 매핑 |
|
|
| `@Transient` | 특정 필드를 영속성에서 제외 |
|
|
| `@Embedded` | 내장(Embeddable) 타입을 포함 |
|
|
| `@Embeddable` | 내장 타입을 정의 |
|
|
| `@Enumerated` | Enum 타입을 컬럼에 매핑 |
|
|
| `@Lob` | 대용량 데이터(Long Text, Blob) 저장 |
|
|
| `@Temporal` | 날짜/시간 타입 매핑 |
|
|
| `@ManyToOne` | 다대일 관계 설정 |
|
|
| `@OneToMany` | 일대다 관계 설정 |
|
|
| `@OneToOne` | 일대일 관계 설정 |
|
|
| `@ManyToMany` | 다대다 관계 설정 |
|
|
| `@JoinColumn` | 외래 키(FK) 설정 |
|
|
| `@JoinTable` | 다대다 관계에서 조인 테이블 설정 |
|
|
| `@MappedSuperclass` | 공통 속성을 가지는 부모 클래스 지정 |
|
|
| `@Inheritance` | 상속 매핑 전략 설정 |
|
|
| `@DiscriminatorColumn`| 상속 엔티티 구분 컬럼 설정 |
|
|
| `@NamedQuery` | JPQL로 미리 정의된 쿼리 설정 |
|
|
| `@Query` | 사용자 정의 JPQL 쿼리 작성 |
|
|
| `@Modifying` | 데이터 수정 JPQL 쿼리 작성 |
|
|
| `@Transactional` | 트랜잭션 범위 설정 |
|
|
| `@Repository` | 데이터 액세스 계층을 나타냄 |
|
|
| `@EnableJpaRepositories` | JPA 리포지토리 활성화 |
|
|
|
|
|
|
### `@Entity`
|
|
JPA에서 엔티티 클래스를 나타냅니다. 해당 클래스는 데이터베이스 테이블과 매핑됩니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class User {
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
private String name;
|
|
}
|
|
```
|
|
- `User` 클래스가 `users` 테이블과 매핑됩니다.
|
|
|
|
|
|
### `@Table`
|
|
엔티티와 매핑될 테이블의 이름을 지정합니다.
|
|
|
|
```java
|
|
@Entity
|
|
@Table(name = "user_table")
|
|
public class User {
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
private String name;
|
|
}
|
|
```
|
|
- `User` 엔티티가 `user_table`과 매핑됩니다.
|
|
|
|
|
|
### `@Id`
|
|
엔티티의 **기본 키(PK)** 를 지정합니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class Product {
|
|
@Id
|
|
private Long productId;
|
|
}
|
|
```
|
|
- `productId`가 **기본 키**가 됩니다.
|
|
|
|
|
|
### `@GeneratedValue`
|
|
기본 키를 자동 생성하도록 설정합니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class Order {
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
}
|
|
```
|
|
- `GenerationType.IDENTITY`는 **AUTO_INCREMENT** 방식으로 기본 키를 생성합니다.
|
|
|
|
|
|
### `@Column`
|
|
필드를 특정 컬럼과 매핑할 때 사용합니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class Employee {
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
@Column(name = "emp_name", length = 100, nullable = false)
|
|
private String name;
|
|
}
|
|
```
|
|
- `emp_name`이라는 컬럼에 매핑되고, 길이는 100이며, **NULL을 허용하지 않음**.
|
|
|
|
|
|
|
|
### `@Transient`
|
|
해당 필드를 **DB에 저장하지 않도록** 설정합니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class Person {
|
|
@Id
|
|
private Long id;
|
|
|
|
@Transient
|
|
private int age;
|
|
}
|
|
```
|
|
- `age` 필드는 **DB에 저장되지 않음**.
|
|
|
|
|
|
### `@Enumerated`
|
|
Enum 타입을 컬럼에 저장할 때 사용합니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class Task {
|
|
public enum Status { PENDING, COMPLETED }
|
|
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
@Enumerated(EnumType.STRING)
|
|
private Status status;
|
|
}
|
|
```
|
|
- `EnumType.STRING`을 사용하여 `"PENDING"`, `"COMPLETED"` 형태로 저장됩니다.
|
|
|
|
|
|
### `@ManyToOne`
|
|
**다대일(N:1) 관계**를 정의합니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class Order {
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
@ManyToOne
|
|
@JoinColumn(name = "user_id")
|
|
private User user;
|
|
}
|
|
```
|
|
- `Order` 엔티티는 **User와 다대일 관계**.
|
|
|
|
|
|
### `@OneToMany`
|
|
**일대다(1:N) 관계**를 정의합니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class User {
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
@OneToMany(mappedBy = "user")
|
|
private List<Order> orders;
|
|
}
|
|
```
|
|
- 한 명의 `User`가 여러 개의 `Order`를 가질 수 있음.
|
|
|
|
|
|
### `@OneToOne`
|
|
**일대일(1:1) 관계**를 정의합니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class Passport {
|
|
@Id
|
|
private Long id;
|
|
|
|
@OneToOne
|
|
@JoinColumn(name = "user_id")
|
|
private User user;
|
|
}
|
|
```
|
|
- 한 `User`는 하나의 `Passport`를 가짐.
|
|
|
|
|
|
### `@ManyToMany`
|
|
**다대다(N:M) 관계**를 정의합니다.
|
|
|
|
```java
|
|
@Entity
|
|
public class Student {
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
@ManyToMany
|
|
@JoinTable(
|
|
name = "student_course",
|
|
joinColumns = @JoinColumn(name = "student_id"),
|
|
inverseJoinColumns = @JoinColumn(name = "course_id")
|
|
)
|
|
private List<Course> courses;
|
|
}
|
|
```
|
|
- `Student`와 `Course`는 다대다 관계이며 **중간 테이블(`student_course`)** 을 가짐.
|
|
|
|
|
|
### `@Query`
|
|
JPQL을 사용하여 **사용자 정의 쿼리**를 작성합니다.
|
|
|
|
```java
|
|
@Repository
|
|
public interface UserRepository extends JpaRepository<User, Long> {
|
|
@Query("SELECT u FROM User u WHERE u.name = :name")
|
|
List<User> findByName(@Param("name") String name);
|
|
}
|
|
```
|
|
- `name`이 특정 값인 `User`를 조회하는 쿼리.
|
|
|
|
|
|
### `@Transactional`
|
|
**트랜잭션 범위를 설정**합니다.
|
|
|
|
```java
|
|
@Service
|
|
public class UserService {
|
|
@Transactional
|
|
public void updateUser(Long id, String name) {
|
|
User user = userRepository.findById(id).orElseThrow();
|
|
user.setName(name);
|
|
}
|
|
}
|
|
```
|
|
- 메서드 실행 중 예외 발생 시 **자동 롤백**.
|