섹션1) JPA 소개

개발새발log·2022년 5월 2일
0

✅ 김영한 님의 자바 ORM 표준 JPA 프로그래밍 - 기본편을 공부하며 정리한 글입니다.
자바 ORM 표준 JPA 프로그래밍 서적을 참고하여 작성했습니다.

SQL 중심적인 개발의 문제점

반복, 반복, 반복...

SQL 작성하고 -> JDBC API 사용하고 -> 실행 결과를 객체와 매핑하는 등의 작업 반복

//데이터 접근 객체 회원용 DAO
public class MemberDAO{
	public Member find(String memberId){...} //1. 조회
    public void save(Member member){...} //2. 회원 등록
}
  1. 조회
  • 회원 조회용 SQL 작성
    String sql = "SELECT MEMBER_ID, NAME FROM MEMBER M WHERE MEMBER_ID = ?";

  • JDBC API 사용해서 SQL 실행
    ResultSet rs = stmt.executeQuery(sql);

  • 조회 결과를 Member 객체로 매핑

String memberId = rs.getString("MEMBER_ID");
String name = rs.getString("NAME");

Member member = new Member();
member.setMemberId(memberId);
member.setName(name);
  1. 회원 등록
  • 회원 등록용 SQL 작성
    String sql = "INSERT INTO MEMBER(MEMBER_ID, NAME) VALUES (?, ?)";

  • 회원객체의 값을 꺼내서 등록 SQL에 전달

psmt.setString(1, member.getMemberId());
psmt.setString(2, member.getName());
  • JDBC API를 사용해서 SQL 실행
    psmt.executeUpdate(sql);

👉 개발자가 객체지향 애플리케이션과 데이터베이스 중간에서 SQL과 JDBC API를 사용해서 변환 작업을 직접 해주어야 한다.

너무 많은 SQL과 JDBC API를 코드로 작성한다는 단점이..

SQL에 의존적인 개발

진정한 의미의 계층 분할이 어렵다 + 엔티티를 신뢰할 수 없다
👀 설령 데이터 접근 계층을 사용해서 SQL을 숨긴다한들, 어쩔 수 없이 DAO를 열어서 어떤 SQL이 실행되는지 확인해야 한다

결국, SQL에 의존적인 개발을 피하기 어렵다

패러다임의 불일치

상속

⭐️ 객체는 상속이라는 기능을 가졌지만, 테이블은 상속이라는 기능이 없다
👀 슈퍼타입과 서브타입 관계를 사용하면 유사한 형태로 설계할 순 있지만,
어쨌든 조회하거나 저장할 때

  • Album 객체 저장하는 경우:
    INSERT INTO ITEM..
    INSERT INTO ALBUM..

  • Album 조회: Item, Album 테이블 조인해서 조회한 뒤, 그 결과로 Album 객체 생성

연관관계

⭐️ 객체는 참조를 사용해서 다른 객체와 연관관계를 가지는 반면, 테이블은 외래키를 사용해서 다른 테이블과 연관관계를 가진다
👉 객체지향적으로 모델링한 경우, 개발자가 중간에서 변환 역할을 해야 함 (테이블 - 객체)

public Member find(String memberId){
	//SQL 실행 (회원과 팀 조회)
    ...
    Member member = new Member();
    ...
    
    //데이터베이스에서 조회한 회원 관련 정보를 모두 입력
    Team team = new Team();
    ...
    //데이터베이스에서 조회한 팀 관련 정보를 모두 입력
    
    //회원과 팀 관계 설정
    member.setTeam(team)
    
    return member;
}

객체지향적인 모델링을 지키자고 내가 이런 노가다를....?
결론은 현타 온 개발자다🤦🏻‍♀️

객체 그래프 탐색

객체 그래프 탐색이란?
Team team = member.getTeam();
member.getOrder().getOrderItem()...
와 같이 참조를 사용해서 연관된 객체 자유롭게 찾기

객체는 마음껏 객체 그래프를 탐색할 수 있어야 하는데.. 과연 마음껏 객체 그래프를 탐색할 수 있는가? 답은 NO다.

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

👀 MemberDAO에서 member 객체를 조회할 때 이렇게 회원과 팀에 대한 데이터만 조회했다면 member.getTeam()은 성공하겠지만 member.getOrder()는 탐색할 수 없을 것이다 (결과: null)

class MemberService{
	...
	public void process(){
    	Member member = memberDAO.find(memberId);
        member.getTeam(); //가능?
        member.getOrder().getDelivery(); //가능???
    }

}

👉 결국, 데이터 접근 계층인 DAO를 열어서 SQL을 직접 확인하지 않는 이상 객체 그래프 탐색이 가능한지는 비즈니스 로직만 보고 알 수 없다

  • 그렇다고 member와 연관된 모든 객체 그래프를 데이터베이스에서 조회해서 애플리케이션 메모리에 올려두는 건 현실성 X
  • 결국 MemberDAO에 회원을 조회하는 메소드를 상황에 따라 여러벌 만들어야..
memberDAO.getMember(); //Member
memberDAO.getMemberWithTeam(); //Member, Team
memberDAO.getMemberWithOrderWithDelivery(); //Member, Order, Delivey

동일성 보장

📌 동일성(Identity)와 동등성(Equality)

  • 동일성 비교는 == 비교다. 객체 인스턴스의 주소값을 비교한다.
  • 동등성 비교는 equals() 메소드를 사용해서 객체 내부의 값을 비교한다.
class MemberDAO{
	public Member getMember(String memberId){
    	String sql = "SELECT * FROM MEMBER WHERE MEMBER_ID = ?";
        ...
        //JDBC API, SQL 실행
        return new Member(...);
    }
}
  • 조회한 회원 비교하기
String memberId = "100";
Member member1 = memberDAO.getMember(memberId);
Member member2 = memberDAO.getMember(memberId);

member1 == member2; //다르다

✅ Check Point

  • 객체답게 모델링 할수록 매핑 작업만 늘어난다
  • 객체를 자바 컬렉션에 저장 하듯이 DB에 저장할 수는 없을까?

답은 JPA다!!!!

JPA란 무엇인가

JPA(Java Persistence API)는 자바 진영의 ORM 기술 표준이다.
ORM이란, Object-Relational Mapping 이름 그래도 객체와 관계형 데이터베이스를 매핑한다는 뜻이다. 그리하여 패러다임의 불일치 문제를 개발자 대신 해결해준다‼️

  • JPA 저장의 경우:

    👉 jpa.persist(member);

  • JPA 조회의 경우:

    👉 Member member = jpa.find(memberId);

Why JPA?

  1. 생산성: 지루하고 반복적인 코드와 CRUD용 SQL을 개발자가 직접 작성하지 않아도 된다
  2. 유지보수: SQL와 JDBC API를 JPA가 대신 처리해주므로 필드를 추가하거나 삭제해도 수정해야 할 코드가 줄어든다
  3. 패러다임의 불일치 해결
  4. 성능 최적화: 캐시, 버퍼링 기능
  5. 데이터접근 추상화와 밴더 독립성: 특정 데이터베이스에 종속 X, 변경 가능

출처

이미지 및 코드 출처:
- 자바 ORM 표준 JPA 프로그래밍 - 기본편
- 자바 ORM 표준 JPA 프로그래밍

profile
⚠️ 주인장의 머릿속을 닮아 두서 없음 주의 ⚠️

0개의 댓글