spring

[Spring] JPA란?

허몽구 2023. 9. 24. 13:53

혼자 하거나, 지인들과 프로젝트 진행할 때는 Mybatis보다는 JPA를 선호하여 사용하는데,

요즘 김영한 선생님!!!! 의 자바 ORM 표준 JPA 프로그래밍 책을 읽는데 내가 정확히 JPA가 무엇인지 모르고 공부하는 것 같아서..

정리하면서 확실하게 알아보려고 한다!

 

1. JPA란? 

JPA란 Java Persistence API의 약자로, Java 언어를 위한 ORM(Object-Relational Mapping) 기술의 표준 인터페이스이다.

여기서 ORM은 객체 지향 프로그램이 언어와 RDMBS 간의 데이터를 변환하고 매핑하는 기술을 말한다.

즉, 실제적으로 구현된 것이 아니라 구현된 클래스와 매핑하기 위해 사용되는 프레임워크인 것이다.

JPA는 자바 어플리케이션과 JDBC 사이에서 동작하며, 자바 인터페이스로 정의되어 있다.

 

2. JPA의 장점

1) 생산성 향상

JPA는 객체 지향적인 개발 방식을 지원하므로, 개발자는 SQL 쿼리를 직접 작성하지 않고 객체를 통해 데이터베이스에 접근할 수 있다. 따라서 개발 생산성을 향상시킬 수 있고, 코드의 가독성과 유지보수성을 높여준다.

(내가 JPA를 사용했던 가장 큰 이유 중 하나이다...)

 

2) 데이터베이스 독립성

JPA는 데이터베이스에 종속적인 SQL 쿼리를 작성하는 것이 아니라, 객체를 조작하는 방식으로 DB에 접근하므로 데이터베이스 종류에 상관없이 동일한 코드로 작동 가능하며, DB를 변경하더라도 코드 수정이 최소화된다.

 

3) 트랜잭션 관리

JPA는 트랜잭션을 자동으로 관리해주는 기능을 제공한다. (정말... 너무 좋다!!!!!)

개발자는 별도의 코드를 작성하지 않아도 JPA가 트랜잭션을 시작하고 커밋 또는 롤백하는 과정을 처리해주기 때문에,

데이터의 일관성과 안전한 데이터 조작이 보장된다.

 

4) 캐싱 지원

JPA는 영속성 컨텍스트라는 메모리 내의 캐시를 제공한다. (영속성 컨텍스트에 대해서는 이후에 포스트 작성하도록 하겠다!)

이를 통해서 반복적으로 조회되는 데이터를 메모리에 캐시하여 성능을 향상시킬 수 있다. 

또한, 변경된 데이터만 데이터베이스에 동기화하므로 네트워크 부하를 줄일 수 있다.

 

5) 객체 지향적인 쿼리

JPA는 JPQL(Java Persistence Query Language)를 제공하여 객체 지향적인 쿼리 작성이 가능하다.

SQL과는 다르게 엔티티와 속성을 기반으로 쿼리를 작성할 수 있으며, 동적 쿼리 작성에도 유연한 대응이 가능하다. 

 

3. JPA의 단점

1) 성능 문제

JPA는 편리한 개발 환경을 제공하지만, 예를 들어 지나치게 많은 쿼리를 실행하거나 대량의 데이터를 로딩해야 하는 경우에는 성능 저하가 발생할 수 있다.

따라서, JPA를 사용할 때는 쿼리 튜닝캐싱 등의 성능 최적화 기법을 적용해야 한다.

 

2) 데이터베이스 제한

JPA는 다양한 데이터베이스를 지원하지만 각 데이터베이스의 특성과 제약 조건을 모두 지원하지는 않느다.

특정 데이터베이스에만 특화된 기능이나 SQL 문법을 사용하려면 네이티브 쿼리를 작성해야 한다.

 

3) 복잡성과 오버헤드

프로젝트의 규모와 복잡성이 증가할수록 JPA의 설정과 관리에 대한 오버헤드가 발생할 수 있다.

또한, JPA는 객체와 데이터베이스 간의 매핑을 처리하기 위해 추가적인 메모리와 CPU 자원을 사용하므로 어플리케이션의 성능에 영향을 줄 수 있다.

 

4) 유연성 제한

JPA는 객체와 데이터베이스 간의 매핑을 위한 규칙과 제약 조건을 가지고 있기 때문에, JPA의 제약을 회피하기 위해 네이티브 쿼리나 저장 프로시저를 사용해야 할 수도 있다.

 

하지만 나는 단점은 충분히 보완 가능하다고 생각하여 JPA를 (너무... 너무..) 선호하는 편이다!

반복적인 CRUD SQL 처리가 쉽게 가능하며, 개발할 때도 쿼리 중심이 아닌 객체 중심으로 개발 가능하다는 점이 너무 큰 장점같다.

 

4. JPA의 동작 (이미지 출처 : https://www.inflearn.com/course/ORM-JPA-Basic)

 

 

JPA는 애플리케이션과 JDBC 사이에서 동작한다.

JPA는 JDBC API를 사용하여 데이터베이스와 데이터를 주고받게 된다.

 

위의 구조에서 만약 User 클래스를 저장해보자.

// User 객체 저장
jpa.persist(user);

 

위 코드에 대해 설명하자면, jpa.persist(user)는 JPA를 사용하여 User 객체를 영속화하는 코드이다.

영속화란 JPA를 통해 객체를 데이터베이스에 저장하기 위해 필요한 작업을 나타낸다.

persist() 메소드는 JPA의 엔티티 매니저(Entity Manager)를 통해 호출되며, 다음 작업을 수행한다.

 

1) 객체를 영속 상태로 만든다. 이는 JPA가 해당 객체를 데이터베이스에 저장하고 관리한다는 의미이다.

2) 영속 상태로 만들기 위해 JPA는 객체의 상태를 추적하고, 데이터베이스에 적절한 SQL 쿼리를 자동으로 생성한다.

따라서 이 쿼리는 객체의 필드값을 데이터베이스에 저장하는 INSERT 쿼리가 된다.

3) PK(객체의 식별자)를 자동으로 처리하여 생성하고 설정한다. 

4) 영속성 컨텍스트(PErsistenct Context)에 객체를 저장한다.

영속성 컨텍스트는 JPA가 객체를 관리하는 논리적인 영역으로, 객체의 상태 변경을 추적하고 DB와의 동기화를 담당한다.

 

따라서, 해당 코드는 주어진 User객체를 JPA를 통해 데이터베이스에 저장하고, 영속성 컨텍스트에 관리되도록 하는 코드이다.

 

그럼 JPA는 위의 코드를 쿼리로 어떻게 변환하는지 알아보자.

INSERT INTO USER (ID, NAME, AGE) .....

 

클래스를 통해 persist()를 실행하면 JPA가 객체를 분석하여 SQL문을 생성한다.

이후, JDBC API를 사용하여 생성한 SQL문을 DB에 보내게 된다.

이 과정에서 JPA는 객체와 데이터베이스 테이블의 패러다임 불일치를 해결해준다.

 

5. 패러다임 불일치

패러다임 불일치 문제는 객체 지향 프로그래밍과 RDBMS의 패러다임 간 발생하는 차이를 의미한다.

객체 지향 프로그래밍은 객체를 중심으로 데이터와 동작을 추상화하고, 상속이나 다형성 등의 개념을 활용하여 유연하고 재사용 가능한 코드를 작성하는 것이 목표인 반면,

RDBMS는 테이블과 열로 구성된 데이터를 관리하며, 데이터 간의 관계를 표현하고 쿼리를 통해 데이터를 조작하는 것이 목표이다.

패러다임 불일치 문제는 이러한 객체 지향과 RDBMS 간 차이로 인해 발생하는데, 다음과 같은 문제가 발생할 수 있다.

 

1) 객체와 테이블 매핑

객체는 상속, 다형성 등의 개념을 가지고 있지만, RDBMS는 이러한 개념을 직접적으로 지원하지 않기 때문에

객체와 테이블 간의 매핑 문제가 발생할 수 있다.

 

2) 객체 그래프 탐색

객체는 연관된 다른 객체들과의 관계를 가지고 있어 이를 통해 객체 그래프를 형성한다.

하지만 RDBMS는 외래키를 통해 테이블간 관계를 표현하므로, 객체 그래프를 RDBMS에 저장하고 조회하는 과정에서 문제가 발생할 수 있다.

 

3)  객체의 상태 관리

객체는 상태를 가지고 있으며 이 상태를 지속적으로 관리해야 한다.

하지만 RDBMS는 데이터의 상태를 테이블에 저장하므로, 객체의 상태를 관리하는 과정에서 데이터베이스와의 일관성을 유지하는 것이 어려울 수 있다.

 

JPA는 이러한 패러다임의 불일치 문제를 해결하기 위해 개발된 기술로써, 

객체와 RDBMS간 매핑을 자동화하고, 객체 그래프 탐색과 상태 관리를 효율적으로 처리할 수 있는 기능을 제공한다.

객체와 데이터베이스는 서로 다른 목적을 가지고 설계되었기 때문에 여러 문제가 발생할 수 있지만,

JPA를 사용하면서 이런 문제를 해결해나갈 수 있다.

 


 

JPA를 공부하면서 그냥 표준 ORM이구나... 하면서 공부한 것 같은데 이 기회에 공부하면서 확실하게 개념 정리를 한 것 같아 좋았다!

앞으로 사용하기 전에 정확하게 알아보고 공부해야겠다고 반성...ㅎㅎ