프로그래밍/Spring

[Spring Boot] JPA란?

I'm_ 2024. 1. 24. 08:33

✅ 들어가며

오늘은 JPA를 이용하여 기능을 구현하기 위해 사용방법을 공부한 후 내 프로젝트에 적용해 보았다.

 

✅ JPA(Java Persistence API)

✔️ JPA란?

자바 응용 프로그램에서 관계형 데이터베이스의 관리를 할 수 있도록 하는 자바 API로 관계형 데이터베이스와 객체의 패러다임 불일치 문제를 해결할 수 있다.

JPA는 인터페이스이기 때문에 구현체가 필요한데, 스프링 JPA는 하이버네이트(Hibernate)라는 구현체를 포함해서 제공하고 있다.

 

✔️ Entity

JPA에서의 엔티티란 DB 테이블에 대응하는 하나의 클래스라고 생각하면 된다.

 

엔티티를 위한 어노테이션

📌 @Entity : JPA가 관리하며 DB의 테이블과 자바 클래스가 매핑된다. 

  • 접근제어자가 public 혹은 protected인 기본 생성자가 필수이다.
  • final, enum, interface, inner 클래스에는 사용이 불가하다.
  • 저장하려는 속성은 final이면 안된다.
속성 기능
name - Entity의 이름 지정
- 보통 기본값을 사용하지만 다른 패키지에 같은 이름이 있을 경우 다른 이름을 지정하여 충돌 방지

 

📌 @Table : DB에서 쓸 테이블 이름 또는 매핑하고 싶은 테이블 이름을 쓴다.

속성 기능
name - 매핑할 테이블 이름
- Entity의 이름을 사용
catalog DB catalog 매핑
schema DB schema 매핑
uniqueConstraints DDL 생성 시 유니크 제약 조건 생성

 

📌 @Id, @GeneratedValue : 기본키(primary key)를 설정한다.

기본키를 매핑하는 방법은 직접 할당과 자동 생성이 있다. 

@Id만 사용하면 직접 할당할 수 있고, @GeneratedValue를 추가하고 키 생성 전략을 선택하면 그에 맞게 기본키가 생성된다.

❗자동 생성 전략
IDENTITY : 기본키 생성을 DB에 위임 (예: MySQL의 AUTO_INCREMENT)
SEQUENCE : DB 시퀀스를 사용해서 기본키를 할당
TABLE : 키 생성 테이블을 사용
AUTO : 선택한 DB에 따라 IDENTITY, SEQUENCE, TABLE 중 하나를 자동으로 선택

 

📌 @Column : 컬럼과 매핑한다.

속성 기능 사용 예시
name 필드와 매핑할 컬럼 이름  
insertable, updatable - 등록, 변경 가능 여부
- 기본값 TRUE
 
nullable null 값 허용 여부  
unique DDL 생성 시 한 컬럼에 유니크 제약 조건 생성  
columnDefinition DB 컬럼 정보 직접 설정 varchar(100) default 'EMPTY'
length 문자 길이 제약 조건, String타입에만 사용 length=255
precision, scale BigDecimal 타입에서 사용
precision : 소수점 포함 전체 자릿 수
scale : 소수의 자릿 수
precision=19
scale=2

 

📌 @Transient : 특정 필드를 컬럼에 매핑하지 않는다. 

 

📌 타입 매핑

@Temporal : 날짜 타입 매핑

@Enumberated(EnumType.STRING) : enum 타입 매핑

@Lob : BLOB, CLOB 매핑

 

✔️ Query Methods(쿼리 메서드)

JPA의 쿼리를 생성하는 기능 중 하나로 메서드명을 규칙에 맞게 작성하며 자동으로 쿼리가 생성된다.

 

📌 쿼리 키워드

키워드 설명
find...By, read...By, get...By,
query...By, search...By, stream...By
- List<Food>와 같은 Collection타입으로 리턴
- 조회 대상이 PK인 경우 단일 객체로 리턴
exists...By boolean 타입으로 리턴
count...By int/long 등으로 해당되는 데이터 수 리턴
delete...By, remove...By void타입 (결과없음) 혹은 int/long 타입으로 삭제된 데이터 수 리턴
...First<숫자>..., ...Top<숫자>... 제일 첫번째 데이터부터 해당 숫자만큼 Collection타입으로 리턴

 

📌 메서드 이름 내 키워드

키워드 샘플 JPQL
Distinct findDistinctByLastnameAndFirstname select distinct …​ where x.lastname = ?1 and x.firstname = ?2
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is, Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull, Null findByAge(Is)Null … where x.age is null
IsNotNull, NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection<Age> ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection<Age> ages) … where x.age not in ?1
TRUE findByActiveTrue() … where x.active = true
FALSE findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstname) = UPPER(?1)

 


📚 참고자료