JPA

이재현·2024년 8월 18일

Spring

목록 보기
4/13

JPA는 자바에서 ORM(Object-Relational Mapping) 기술 표준으로 사용되는 인터페이스의 모음이다.

실제적으로 구현된 것이 아니라 구현된 클래스와 매핑을 해주기 위해 사용하는 프레임워크이다.
대표적인 예시로는 Hibernate가 있다.

🤍 JPA

JPA는 Java Persistence API의 약어로, 자바의 ORM 기술 표준 인터페이스이다.

자바 애플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스라고 할 수 있다.

인터페이스이기 때문에, Hibernate, OpenJPA 등이 JPA를 구현한다.

🩵 JPA의 장점

JPA는 여타 다른 ORM 인터페이스들과 같이 반복적인 CRUD SQL을 처리한다.

즉, JPA는 매핑된 관계를 이용해서 SQL을 생성하고 실행하는데, 개발자는 어떤 SQL이 실행될지 생각만 하면 된다.

  • 별도로 JPA는 네이티브 SQL이란 기능을 제공하는데, 관계 매핑이 어렵거나 성능에 대한 이슈가 걱정되는 경우 SQL을 직접 작성하여 사용할 수 있다.

JPA의 최대 장점은 다음과 같다.

SQL이 아닌 객체 중심 개발
간단히 말해서, 기존 데이터베이스 프로그래밍에서는 SQL을 직접 사용해서 데이터를 처리한다.
이 경우 객체와 데이터베이스 간의 변환작업이 필요하고, 이 과정에 시간이 많이 소요된다.
하지만 JPA를 사용하는 경우 SQL 대신 자바 객체인 Entity를 사용하여 데이터를 조작하고, JPA가 내부적으로 SQL을 자동으로 생성하고 실행해준다.
이를 통해 생산성도 향상되며 유지보수 측면에서도 훨씬 수월하다.

패러다임 불일치 문제 해결
객체 지향 언어와 관계형 데이터베이스는 서로 다른 패러다임을 가진다.

  • 상속: 객체지향에서는 쉽지만, 관계형 데이터베이스에서는 테이블 구조로 표현하기가 어렵다.
  • 연관관계: 객체지향에서는 이 관계를 필드로 표현하지만, 관계형 데이터베이스에서는 외래키를 사용하여 표현한다.
  • 다형성: 객체 지향에서 중요한 다형성은 관계형 데이터베이스로 구현하는 것이 복잡하다.
  • 데이터 조작: 객체 지향에서는 컬렉션을 다루듯 데이터를 조작하지만, 관계형 데이터베이스에서는 SQL로 데이터를 다룬다.

JPA를 사용하면 다음과 같이 해당 문제들을 해결할 수 있다.

매핑: JPA가 Entity와 테이블 간의 매핑을 자동으로 처리하여 상속, 연관관계 등을 데이터베이스 구조와 자연스럽게 연결한다.

쿼리 처리: JPQL(Java Persistence Query Language)을 사용하여 객체를 대상으로 쿼리를 작성할 수 있다.

CRUD 자동화: 기본적인 CRUD 작업을 자동으로 처리해준다. 즉 개발자는 별도의 SQL 작성없이 객체를 데이터베이스에 저장하거나 조회할 수 있다.

🩵 JPA 동작 과정

JPA는 Java 애플리케이션과 JDBC 사이에서 동작하는데, Java 애플리케이션에서 JPA를 사용하면 내부에서 JDBC API를 사용해 SQL을 DB에 전달하고 결과를 반환 받는다.

즉, JPA는 데이터베이스와 객체를 매핑하는 기술일 뿐, 내부적으로는 데이터베이스와의 통신을 위해 JDBC를 사용한다.

그리고 JPA 역시 JDBC와 마찬가지로 인터페이스이기 때문에 구현체가 요구되며, 그 구현체들이 바로 Hibernate, OpenJPA 등이다.

💙 객체 매핑

@Entity 어노테이션이 붙은 클래스를 JPA가 각 필드의 어노테이션을 보고 DB 테이블과 매핑하여 관리하게 된다.

Mapping Annotation설명
@Entity테이블과의 매핑, 해당 클래스는 JPA가 관리하며 엔티티명을 지정하지 않으면 기본값인 클래스 명을 사용함
@Id기본 키 매핑
@GeneratedValue기본 키 생성 전략, GenerationType.IDENTITY 옵션은 기본 키 생성을 DB에 위임한다.
@Column객체 필드를 테이블 컬럼에 매핑
Nullable: null값의 허용 여부 설정(기본값 true)
Unique: 유니크 제약조건
Length: 문자 길이 제약조건, String 타입에만 사용(기본값 255)
  • Entity는 접근제어자가 public, protected인 경우 기본 생성자가 필수적으로 필요하며, 저장 속성은 final이면 안된다는 주의사항이 있다.
@Entity
	public class Item {
 
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) 
	private Long id;
 
	// 필드 이름이 카멜 케이스 일 경우 테이블 컬럼 이름을 언더 스코어로 자동 변환 해준다.
	// 따라서 아래 필드이름은 itemName으로 @Column을 사용 시 name 옵션을 사용하지 않아도 자동으로 item_name으로 변환 해준다.
	@Column(name = "item_name")
	private String itemName;
 
	// 컬럼명을 생략하면 필드명을 컬럼명으로 사용
	private Integer price;
	private Integer quantity;
 
	public Item() {} // JPA는 public, protected의 기본 생성자가 필수 !
 
	public Item(String itemName, Integer price, Integer quantity) {
		this.itemName = itemName;
		this.price = price;
		this.quantity = quantity;
	}
}

0개의 댓글