본문 바로가기
JPA Tutorial

[자바 ORM 표준 JPA 프로그래밍 1] SQL 중심적인 개발의 문제점

by 미소5 2023. 9. 12.

애플리케이션은 주로 객체 지향 언어로 개발 - Java, Scala, ...

객체(데이터)는 주로 관계형 DB에 보관 - Oracle, MySQL, ...

 

→ 지금 시대는 객체관계형 DB에 관리한다! 

→ 즉, SQL에 의존적인 개발을 피하기 어렵다!

 


  • SQL 중심적인 개발의 문제점 

 

객체 CRUD
객체 CRUD

  •  수많은 객체 CRUD, 수많은 SQL 작성
    • INSERT INTO …
    • SELECT …
    • UPDATE …
    • DELETE … 
    • 자바 객체를 SQL로... SQL을 자바 객체로...
      • 객체에 필드 추가라도 하게되면..? 

 

→ 무한 반복, 지루한 코드

 


  • 객체 지향 프로그래밍추상화, 캡슐화, 정보은닉, 상속, 다형성 등 시스템의 복잡성을 제어할 수 있는 다양한 장치들을 제공한다.’ 

 

  • 객체(Object)를 영구 보관하는 다양한 저장소(RDB, NoSQL, File, ...) 중, 현실적인 대안은 관계형 데이터베이스(RDB)
    • 객체SQL로 변환하여, 관계형 데이터베이스(RDB)에 저장  

 

  • 객체 관계형 데이터베이스(RDB)의 차이
    1.  상속 
    2.  연관관계 
    3.  데이터 타입
    4.  데이터 식별 방법

 


1. 상속

객체의 경우, 상속 관계
RDB(테이블)의 경우, 슈퍼타입 서브타입 관계로 설계

 

  • Album 저장
    1. 객체 분해
    2. INSERT INTO ITEM ...
    3. INSERT INTO ALBUM …
  • Album 조회
    1.  각각의 테이블에 따른 조인 SQL 작성...
    2.  각각의 객체 생성..
    3.  .....(상상만 해도 복잡)..... 

 

→그래서 DB에 저장할 객체에는 상속 관계 안쓴다.

 

 


  • Album을 자바 컬렉션에 저장하면?
    •  list.add(album); 
  • Album을 자바 컬렉션에서 조회하면?
    •  Album album = list.get(albumId); 
    • 부모 타입으로 조회 후, 다형성 활용
    •  Item item = list.get(albumId); 

 

 


2. 연관관계

 

  • 객체는 참조를 사용
    • member.getTeam()
  • 테이블은 외래키를 사용
    • JOIN ON M.TEAM_ID = T.TEAM_ID

 

 

 

 

 

 

객체를 테이블에 맞추어 모델링한다!

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

 

→ 테이블에 맞춘 객체 저장

INSERT INTO MEMBER(MEMBER_ID, TEAM_ID, USERNAME) VALUES …

 

 


  • 객체다운 모델링
class Member {

	 String id; //MEMBER_ID 컬럼 사용
 	 Team team; /** 참조로 연관관계를 맺는다 */
	 String username;//USERNAME 컬럼 사용
 
	 Team getTeam() {
	 	return team;
	 }
     
}

 

  • 객체 모델링 저장
    • member에서 team을 조회해서, 그 team의 id(PK)가져옴   

객체 모델링 저장

 

  • 객체 모델링 조회
 //member와 team을 join해서 한번에 가져온다.
SELECT M.*, T.*
 FROM MEMBER M
 JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
public Member find(String memberId) {
 	 //SQL 실행 ...
	 Member member = new Member();
	 //데이터베이스에서 조회한 회원 관련 정보를 모두 입력
 	 Team team = new Team();
 	 //데이터베이스에서 조회한 팀 관련 정보를 모두 입력
	 //회원과 팀 관계 설정
 	 member.setTeam(team); //**
	 return member;
}

 


  • 객체 모델링, 자바 컬렉션에 관리한다고 생각해보면?
//member 저장
list.add(member);

//member 조회
Member member = list.get(memberId);
//member의 team 조회
Team team = member.getTeam();

 


3. 객체는 자유롭게 객체 그래프 탐색할 수 있어야 한다.

 

  • 처음 실행하는 SQL에 따라 탐색 범위 결정
    •  member.getTeam();     //OK
    •  member.getOrder();     //null

 

 

 

 

엔티티 신뢰 문제가 생긴다.

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

 

→ 그렇다고 모든 객체를 미리 로딩할 수는 없다. 

/** 상황에 따라 동일한 회원 조회 메서드를 여러개 생성하면.. SQL이 너무 많이 생성된다 */

memberDAO.getMember(); //Member만 조회

memberDAO.getMemberWithTeam();//Member와 Team 조회

//Member,Order,Delivery
memberDAO.getMemberWithOrderWithDelivery();

 

→ 즉, 진정한 의미의 계층 분할이 어렵다. (계층형 아키텍처)

 


4. 비교하기

String memberId = "100";
Member member1 = memberDAO.getMember(memberId);
Member member2 = memberDAO.getMember(memberId);

member1 == member2; //두 인스턴스는 당연히 다르다!
//데이터는 같지만, 실제 인스턴스는 다름

 

자바 컬렉션에서 조회해보면?

String memberId = "100";
Member member1 = list.get(memberId);
Member member2 = list.get(memberId);

member1 == member2; //같다.

 


→ 즉, 객체답게 모델링 할수록 매핑 작업만 늘어난다.  ( 개발자 ≒ SQL 매퍼 )

 

  • 객체를 자바 컬렉션에 저장 하듯이 DB에 저장할 수는 없을까?
    • JPA (Java Persistence API)

 

[자바 ORM 표준 JPA 프로그래밍 -2] ORM 기술, JPA (tistory.com)

 

[자바 ORM 표준 JPA 프로그래밍 -2] ORM 기술, JPA

JPA (Java Persistence API) -자바 진영의 ORM 기술 표준 ORM: Object-relational mapping (객체 관계 매핑) 객체는 객체대로 설계 관계형 데이터베이스(RDB)는 관계형 데이터베이스대로 설계 ORM 프레임워크가 객체

joly156.tistory.com

 

 

728x90
반응형