자바 ORM 표준 JPA 표준 프로그래밍 1장

임종혁·2024년 1월 24일

그동안 단순 CRUD만 쓸줄 알뿐 정확한 JPA , JPA과 어떤 동작으로 수행하는지 모르고 사용하였다. 그리고 그동안 너무 효율성이 안좋게 쓴 느낌이 없잖아 있어 이참에 JPA 를 확실히 잡고 가기 위해 해당 책을 읽게 되었다.

1. 1장

처음으로는 SQL을 직접 다룰때 발생하는 문제점에 대해서 다룬다
무순 문제점이 있을까

  • 우선 처음으로는 반복되는 문제이다
public class Main{
	private String memberId;
    private String name;
}

다음 같이 회원 객체가 있을때 이를 CRUD 시킬 생각이다

public class MemberDAO{
	public Member find(String memberId){}
}
// sql쿼리 작성
SELECT MEMBER_ID,NAME FROM MEMBER M WHERE MEMBER_ID = ?

// sql jdbc 사용하여 실행
ResultSet rs = stmt.executeQury(sql);

//조회결과를 Member에 매핑 
String memberld = rs.getString("MEMBER_ID”》;
String name = rs.getString("NAME”);
Member member = new Member();
member.setMemberld(memberld);
member.setName(name);

이처럼 조회 쿼리가 완성 되었다

이제 등록 쿼리를 줄 차례이다

//회원 등록 sql 쿼리 작성
String sql = "INSERT INTO MEMBER(MEMBER_ID, NAME) VALUES(?,?)";

//회원 객체 값 꺼내 등록 sql 작성
pstmt.setstring(1, member.getMemberld());
pstmt.setstring(2Z member.getName());

//실행
pstmt.executeUpdate(sql);

수정과 삭제도 이와 비슷하게 JDBC API를 사용하는 일을 반복적으로 수행한다

만약 컬랙션이였다면

list.add(member);

다음과 같이 저장 하면 된다 (필드를 일일이 조회하고 일일이 저장 쿼리를 안만들어도 됨)

하지만 데이터 베이스는 객체 구조와 다른 데이터 중심 구조 이므로 객체를 직접 저장 조회 가 불가능 하다
따라서 중간에 sql과 jdbc api를 사용하여 변환 작업을 직접 해주어야한다
여기서 발생 문제는 앞서 본

"" 반복 반복 반복 ""

SQL 의존 적인 개발

또한 앞서 본 코드는 SQL 에 너무 의존적이다
만약 앞서 본 코드에서 회원에 다른 필드도 추가 하고 싶다면

그럼 우리는 등록 쿼리, 업데이트 쿼리, 조회 쿼리 등등 연관된 SQL 쿼리들은 모두 변경해줘야 한다

애플리케이션에서 SQL을 직접 다룰때 문제점을 요약하면

  • 진정한 의미의 계층 분할이 어렵다
  • 엔티티를 신뢰할 수 없다
  • SQL에 의존적인 개발을 피할수 없다

JPA 문제해결

그럼 JPA는 이와 같은 문제를 어떻게 해결 할까

JPA를 사용하면 객체를 데이터베이스에 저장하고 관리 할 때 개발자가 직접 SQL을 작성하는 것이 아닌 JPA 제공 API를 사용하면 됨 그럼 JPA가 적절한 SQL을 생성하여 데이터 베이스 전달

  • persist() 저장 기능이다 -> ISERT SQL 을 생성하여 데이터 베이스 전달 한다
  • find() -> 조회 SELECT SQL 을 생성하여 데이터 베이스 전달하낟
  • JPA 는 수정 기능을 따로 제공하진 않지만, 객체를 조회해 값을 변경하면 TRANSACTION하면 commit 할때 UPDATE SQL 이 전달된다
  • 연관된 객체를 사용하게 되면 JPA가 적절한 SELECT SQL 을 실행한다

패러다임 불일치

  • 데이터를 저장할때 가장 현실적인 방법은 객체를 관계형 데이터베이스에 저장하는 것
    하지만 둘은 지항하는 목적이 다르고 기능과 표현 방법도 다르다
    이것을 객체와 RDB의 패러다임의 불일치 문제라 한다
    - RDB : 데이터를 잘 정규화 해서 보관하는 것이 목표
    - 객체 지향 : 속성과 기능등을 캡슐화 하여 쓰는것이 목표

패러다임 불일치 문제 1. 상속

객체는 상속이라는 기능을 가지고 있지만 테이블은 상속이라는 기능이 없다
그나마 데이터 베이스 모델링에서 이야기하는 슈퍼타입 서브 타입 관계를 사용하면 유사항 형태로 설계 할 수 있지만 쿼리가 복잡하다

abstract class Item{
	Long id;
    String name;
    int price;
    
}

lass Album extends Item {
String artist;
}
class Movie extends Item {
String director;
String actor;
}
class Book extends Item{
String author;
String isbn;
}
// ALBUM 객체 저장시 
NSERT INTO ITEM ...
INSERT INTO ALBUM ...
// MOVIE객체 저장시
INSERT INTO ITEM ...
INSERT INTO MOVIE ...

DBC API를 사용해서 이 코드를 완성하려면 부모 객체에서 부모 데이터만 꺼내
서 ITEM용 INSERT SQL을 작성하고 자식 객체에서 자식 데이터만 꺼내서 ALBUM
용 INSERT SQL을 작성 해야 하는데, 작성 해야 할 코드량이 만만치 않다

이는 곳 패러다임 불일치를 해결하려고 소모하는 비용 ..

JPA에서는 상속과 관련된 패러다임 불일치 문제를 개발자 대신 해결해준다

// 다음 같이 JPA 사용하여 저장시
jpa.persist(album);


// JPA에서 다음과 같이  SQL 생성
INSERT INTO ITEM ...
INSERT INTO ALBUM ...

2. 연관 관계

  • 개발자가 객체간 관계를 설정하고 저장하면 JPA 참조를 외래키로 변환해서 적절한 INSERT SQL 을 데이터 베이스에 전달함, 객체 조회시 외래키 참조로 변환하는 것도 JPA가 처리
// 객체 
class Member {
	Team team; // 참조 
	Team getTeam() {
	return team;
	}
}
class Team {
}

// RDB
class Member {
	String id; //MEMBER_ID 컬럼 사용
	Long teamld; //TEAM_ID FK 컬럼 사용
	String username; / /USERNAME 컬럼 사용
}
class Team {
	Long id; //TEAM_ID PK 사용
	String name; //NAME 컬럼 사용
}

3. 객체 그래프 탐색

객체에서 조회할대 참조를 사용해서 연관된 객체를 찾는것

객체
마음껏 그래프를 탐색할 수 있어야함 그러나 처음 실행하는 SQL에 따라 탐색할 수 있는 객체 그래프 범위가 정해져 그외 객체 그래프는 데이터 없으므로 탐색 불가

SELECT M.*, T.*
FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID


member.getOrder(》; //null > 다음과 같이 탐색 불가 
  • 비즈니스 로직에 따라 사용하는 객체 그래프가 다른데 언제 끊어질지 모를 객체 그래프 탐색 불가
class MemberService {
public void process() {
	Member member = memberDAO.find (memberId);
    member.getTeam(); //member->team 객체 그래프 탐색이 가능한가?
  	member.getOrder().getDelivery(); //???
	}
}

이는 엔티티가 sql 에 논리적 종속 되어 있어 문제

memberDAO. getMember (); //Member만 조회
Team 조회
meinberDAO.getMenmberWithOrderWithDeliveryO "/Member와 Order외- Delivery 조회

다음과 같이 여러 메소드를 상황에 따라 만들어 사용해야함

JPA는 객체 그래프를 마음껏 탐색 가능하다

JPA는 연관된 객체를 사용하는 시점에서 적절한 SQL을 실행한다 따라 실 객체를 사용하는 시점까지 데이터베이스 조회를 미룬다 해서 지연로딩이라 한다
JPA 지연로딩을 투명하게 처리한다

지연 로딩 예시 
//처음조회 시점에 SELECT MEMBER SQL
Member member = jpa .find (Member. class, memberld);
Order order = member.getOrder();
order. getOrderDate (); "Order를 사용하는 시점에 SELECT ORDER SQL

Member 를 사용할때 마다 Order를 함께 사용하면 이렇게 한 테이블씩 조회 하는 것보다 Member를 조회하는 시점에 sql 조인을 사용해 Member 와 Order를 함께 조회하는 것이 효과적

JPA는 이런 지연로딩을 설정을 통해 간단하게 정의할 수 있다.

4. 비교

  • 데이터 베이스 기본 키 값으로 각 로우 구분
  • 객체는 동일성과 동등성 비교라는 두가지 비교 방법 사용
    따라서 테이블 로우 구분하는 방법과 객체 구분하는 방법에는 차이 존재
class MemberDAO {
	public Member getMember(String memberld) {
	String sql = "SELECT * FROM MEMBER WHERE MEMBER_ID = ?";
	//JDBC API, SQL 실행
	return new Member();
	}
   }
String memberld = "100”;
Member member1 = memberDAO.getMember(memberld);
Member member2 = memberDAO.getMember(memberld);
member1 == member2; //다르다

DAO 를 다음과 같이 정의 하면 같은 ID 로 조회를 했어도 new를 통해 새로운 각 인스턴스가 생겨 == false 가 나온다

이러한 패러다임 불일치 문제를 해결하기 위해 데이터베이스 같은 로우를 조회 할때 같은 인스턴스 반환하도록 구현하는 것은 쉽지 않다

JPA 비교

String memberId = "100";
Member member1 = jpa.find (Member.class, memberld);
Member member2 = jpa. find (Member. class z memberld);
member1 == member2; //같다.

JPA는 같은 트랜잭션일 때 같은 객체가 조회된다는 것이 보장한다

JPA는 객체 모델과 관계형 데이터 베이스 모델의 지향하는 서로 다른 패러다임 문제를 해결해주고 유지하게 도와준다

JPA 란 무엇인가

  • JPA는 자바 진영의 ORM 기술 표준, 자바 ORM 기술 대한 API 표준 명세
  • 특정 구현 기술에 대해 의존도를 줄일 수 있고 다른 구현 기술로 손쉽게 이동 가능

ORM: 객체와 관계형 데이터베이스 매핑

  • ORM 프래임 워크가 객체와 테이블을 매핑해 패러다임 불일치 문제를 개발자 대신 해결

  • 객체를 자바 컬렉션에 저장하듯이 ORM 프레임 워크 저장 -> ORM 프레임 워크 적절한 INSERT SQL 생성 -> 데이터베이스 객체 저장

  • 다양한 패러다임 불일치 문제 해결

    JPA 는 어플리케이션과 JDBC 사이에서 동작

JPA 사용했을때 장점

  1. 생산성
  • JPA를 사용하면 자바 컬렉션에 객체 저장하듯 JPA 저장할 객체를 전달하면 됨
  • INSERT SQL 을 작성하고 API를 사용하는 반복적인 일은 JPA 가함
  • JPA 사용하면 데이터베이스 설계 중심의 패러다임을 객체 설계 중심으로 역전 시킬수 잇음
  1. 유지 보수
  • 엔티티에 필드를 수정하거나 삭제해도 수정해야할 코드 감소 -> 유지보수 해야하는 코드 감소
  1. 패러다임 불일치 해결
  • JPA 가 패러다임의 불일치 문제 해결 -> 객체 지향 언어의 장점을 활용해 유연하고 유지보수 하기 좋은 도메인 모델을 편리하게 설계 할 수 있음
  1. 성능
  • JPA 애플리케이션과 데이터베이스 사이에서 동작 -> 애플리케이션과 데이터베이스 사이에 계층이 하나 더 있으면 최적화 관점에서 시도해 볼 수 있는 것들이 많음
  1. 데이터 접근 추상화 벤더 독립성
  • 관계형 데이터베이스는 같은 기능도 벤더마다 사용법이 다른 경우가 많음
  • JPA는 애플리케이션과 데이터베이스 사이 추상화된 데이터 접근 계층 제공
    애플리케이션이 특정 데이터베이스 기술에 종속되지 않도록 함, 데이터베이스를 변경하면 JPA 에 달느 데이터베이스를 쓴다고 알려주면 도미
  1. 표준
  • JPA 자바 진영의 ORM 기술 표준

0개의 댓글