1장 JPA 소개
0. JPA 장점
- 조회된 결과를 객체로 매핑하는 작업도 대부분 자도응로 처리.
- 네이티브 SQL 기능을 사용해서 직업 SQL을 작성
- 객체 중심으로 개발하니 생산성 유지보수가 좋고
- 테스트를 작성하기도 편리하다.
- 데이터베이스 간의 호환이 편리 하다.ㄷ
1.1 SQL의 단점
- 진정한 의미의 계층 분할이 어렵다
- 물리적으로 SQL과 JDBC API를 데이터 접근 계층에 숨기는 데 성공했을지라고
- 논리적으로는 엔티티와 아주 강한 의존관계를 가진다.
- 엔티티를 신뢰할 수 없다.
- DAO을 열어서 SQL 확인
- SQL에 의존적인 개발을 피하기 어렵다
- 많은 SQL 수정 반복
public class Member {
private String name;
private String tel; // add
}
// sql 수정
String sql = "INSERT INTO MOMVER (MEMBER_ID, NAME, TEL) VALUES(?, ?, ?)";
// SQL 등록
pstmt.setString(3, member.getTel());
// 조회 코드 변경
SELECT MEMBER_ID, NAME, TEL FROM MEMBER WHERE MEMBER_ID = ?
// 추가적인 매핑
String tel = rs.getString("TEL");
member.setTel(tel); // 추가
// 수정 코드 변경
list.add(member); // 등록
Member member = list;get(xxx); // 조회
member.setTel("xxx") // 수정
1.1.3 JPA와 문제 해결
- JPA를 사용하면 객체를 데이터베이스에 저장하고 관리할 때
- JPA가 개발자 대신에 적절한 SQL을 생성해서 데이터베이스에 전달한다.
저장 기능
jpa.persist(member); // 저장
조회 기능
String memberId = "helloId";
Member member = jpa.find(Member.class, memberId); // 조회
수정 기능
별도의 함수 제공 없음, find을 하고 set을 하면 적용이된다.
Member member = jpa.find(Member.class, memberId);
member.setName("이름변경"); // 수정
연관된 객체 조회
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam(); // 연관된 객체 조회
1.2 관계형DB와 객체 관리JPA의 패러다임의 불일치
- 객체지향 언어는 복잡한 APP관리를 위해 추상화, 캡슐화, 정보은닉, 상속, 다형성등 시스템의 복잡성을 제어할 수 있는 다양한 장치들을 제공한다.
- 도메인 모델도 객체로 모델링하면 객체지향 언어가 가진 장점들을 활용할 수 있다.
- 문제는 이렇게 정의한 도메인 모델을 저장할때 발생
- 객체지향의 패러다임
- 객체는 속성과 (필드)과 기능(메소드)을 가진다.
- 부모 객체를 상속 받았거나, 다른 객체를 참조하고 있다면 객체의 상태를 저장하기는 쉽지 않다.
- 저장하는 직렬화 기능과 저장된 파일을 객체로 복구하는 역 직렬화 기능을 지원한다.
- 이 방법은 직렬화된 객체를 검색하기 어렵다는 문제가 있으므로 현실성이 없다.
- 관계형 데이터베이스의 패러다임
- 데이터 중심으로 구조화
- 집학적인 사고를 요구
- 객체지향에서 이야기하는 추상화, 상속, 다형성 개념이 없다.
1.2 (추가) 패러다임의 불일치
- 상속
- 연관관계 (참조)
- 객체 그래프 탐색 (참조를 사용해서 연관된 팀을 찾는다.)
- 비교 (동일성 - 동등성
1.2.1 패러다임의 불일치 - 상속
- 객체는 상속 이라는 기능을 가지고 있지만 테이블은 상속이라는 기능이 없다.
- 데이터베이스 모델링에서 이야기하는 슈퍼타입, 서브타입 관계를 사용하면
- 객체 상속과 가장 유사한 형태로 테이블을 설계할 수 있다.
만약 Itme.class을 상속받은 Album.class이 있다면 Album을 조회 한다면 ITEM과 ALBUM테이블을 조인해서 조회한 다음 그결과로 Album객체를 생성해야한다.
1.2.1.1 JPA와 상속(상속 패러다임 불일치을 해결)
- JPA는 상속과 관련된 패러다임의 불일치 문제를 개발자 대신 해결해준다.
- 객체를 저장하듯이 JPA에게 객체를 저장하면 된다.
Album album = new Album();
jpa.persist(album);
String albumId = "id100";
Album album = jpa.find(Album.class, albumId);
1.2.2 패러다임의 불일치 - 연관 관계
- 객체는 참조를 사용해서 다른 객체와 연관 관계를 가지고 참조에 접근해서 연관된 객체를 조회한다.
- 반면
- 테이블은 외래 키를 사용해서 다른 테이블과 연관 과계를 가지고 조인을 사용해서 연관된 테이블을 조회
class Member{
Team team;
Team getTeam(){
return team;
}
}
class Team{...}
RDB은
- 외래 키를 사용해서 MEMBER 테이블과 TEAM 테이블을 조인하면 MEMBER 테이블과 연관된 TEAM 테이블을 조회할 수 있다.
객체는
- 객체는 참조가 있는 방향으로만 조회할 수 있다.
- member.getTeam()은 가능하지만 반대인 team.getMember()는 참조가 없으므로 불가능하다.
- 반면에 테이블은 외래 키 하나로 MEMBER JOIN TEAM도 가능하지만 TEAM JOIN MEMBER도 가능하다.
- Member 객체와 연관된 Team 객체를 참조를 통해서 조회할 수 없다.
- 이런 방식을 따르면 좋은 객체 모델링은 기대하기 어렵고 결국 객체지향의 특징을 잃어 버린다.
- Member 객체와 연관된 Team 객체를 참조를 통해서
객체지향 모델링 (연관관계)
-
class Member{ Team team; // 참조로 연관관계를 맺는다. } class Team {}
객체를 테이블에 맞추어 모델링
- Long teamId; // TEAM_ID FK 컬럼을 사용해 연결
- 이렇게 객체를 테이블에 맞추어 모델링하면 객체를 테이블에 저장하거나 조회할 때는 편리하다.
- 객체는 연관된 객체의 참조를 보관해야 다음처럼 참조를 통해 연관된 객체를 찾을 수 있다.
-
Team team = member.getTeam();
- 가장 객체지향적인 방법은 이처럼 참조를 사용하는 것이다.
- 객체지향 모델링을 사용하면 객체를 테이블에 저장하거나 조회하기가 쉽지 않다.
- member 객체는 team 필드로 연관 관계를 맺고
- MEMBER 테이블은 TEAM_ID 외래 키로 연관 관계를 맺기 때문이다.
JPA와 연관관계 (참조 패러 다임의 불일치)
- JPA는 연관관계와 관련된 패러다임의 불일치 문제를 해결해준다.
-
JPA는 team의 참조를 외래 키로 변환해서 적절한 INSERT SQL을 데이터 베이스에 전달한다.member.setTeam(team); // 회원과 팀 연관 관계 설정 jpa.persist(member); // 회원과 연관관계 함께 저장
-
Member member = jpa.find(Member.class, memberId); Team team = member.getTeam();
1.2.3 패러다임의 불일치 - 객체 그래프 탐색
- 자유로운 객체 그래프 서칭
- JPA는 연관된 객체를 사용하는 시점에 적절한 SELECT SQL을 실행한다.
- 이 기능은 실제 객체를 사용하는 시점까지 DB 조회를 미룬다고 해서 지연 로딩이라한다
- JPA는 지연 로딩을 투명(transparent)하게 처리한다
class Member {
private Order order;
public Order getOrder(){
return order;
}
}
// Member 객체를 보면 getOrder() 메소드의 구현 부분에 JPA와 관련된 어떤 코드도 직접 사용하지 않는다.
- 실제 지연 로딩의 jpa 지연로딩의 처리 방법이다.
// 처음 조회 시점에 SELECT MEMBER SQL Member member = jpa.find(Member.class, memberId); Order order - member.getOrder(); order.getOrderDate(); // Order을 사용하는 시점에 SELEECT ORDER SQL
- Member을 사용할 때마다 Order를 함께 사용하면,
- 한테이블식 조회하는 것보다는 Member를 조회하는 시점에 SQL 조인을 사용해서 Member와 Order를 함께 조회하는 것이 효과적
- 즉시 로딩 : JPA는 연관된 객체를 즉시 함께 조회할지 아니면
- 지연 조회 : 실제 사용되는 시점에 지연해서 조회할지를 간단한 설정으로 정의 할 수있다.
지연 조회 : 필요한 시점에 연관 데이터 처리
즉시 로딩 : 연관 데이터 한번에
SQL 처리 갯수는 지연 조회가 적다.
1.2.4 비교 (패러다임 불일치 - 동일성, 동등성)
- 데이터베이스는 기본 키의 값으로 각 로우(row)를 구분하낟.
- 객체는 동일성(identity)비교와 동등성(equality) 비교라는 두 가지 비교 방법이 있다.
- 동일성 비교는 ==비교다. 객체 인스터스의 주소 값을 비교한다.
- 동등성 비교는 equals() 메소드를 사용해서 객체 내부의 값을 비교한다.
dao로 만든 get()
String memberId = "100";
Member member1 = memberDAO.getMember(memberId);
Member member2 = memberDAO.getMember(memberId);
member1 == member2 // false
- 키 값이 같은 회원의 객체를 두번 조회했다.
- 그런데 동일성(==) 비교를 하면 false가 반환 된다.
- 왜냐하면 로우로 조회을 하면 -> 객체 측면에서 볼때 둘은 다른 인스턴스이기 때문이다.
만약 컬랙션에 보관을 했으면 동일성 비교에 성공했을 것이다.
Member member1 = list.get(0);
Member member2 = list.get(0);
member1 == member2
JPA와 비교 (동일성 보장)
String memberId = "100";
Member member1 = jpa.find.getMember(memberId);
Member member2 = jpa.find.getMember(memberId);
member1 == member2 // True
정리 (객체 모델과 RDB의 차이)
- 패러다임이 다르다. (상속, 연관 관계(참조), 객체그래프 탐색, 비교(동등, 동일))
- DAO의 문제 : 객체 모델링은 힘을 잃고 점점 데이터 중심의 모델로 변해간다.
오후 9:09 나
객체지향으로 데이터베이스를 제어하고자 만든 JPA에서
객체지향을 사용하는 이유는 복잡한 어플리 케이션을 위해 제공한 추상화, 캡슐화, 정보은닉, 상속, 다형성등 다양한 장치들을
데이터 베이스에 이용하고자 만들어진건가요?
JPA을 사용하는 이유는 기존 JDBCTemplate의 SQL에 의존된 메소드들의 많은 반복 수정때문에 JPA을 사용하는 것이고요?
맞는 것같나용?
오후 9:09 불코딩 제이크 얼추 맞아보이는...
JPA는 객체지향 프로그래밍을 활용하여 데이터베이스를 조작하기 위해 만들어진 기술입니다. 객체지향을 사용하는 이유와 JPA를 사용하는 이유에 대한 설명은 아래와 같이 정리할 수 있습니다:
- 객체지향을 사용하는 이유:
- 추상화: 객체지향 프로그래밍은 복잡한 어플리케이션을 추상화하여 간단한 개념으로 표현할 수 있게 해줍니다. 이로써 개발자는 복잡한 데이터베이스 구조나 비즈니스 로직을 더 쉽게 이해하고 다룰 수 있습니다.
- 캡슐화: 객체지향은 데이터와 관련된 메서드를 하나의 단위로 캡슐화하여 데이터의 무결성을 보호하고 잘못된 접근을 방지합니다.
- 정보은닉: 객체지향 언어는 데이터의 접근을 제한하고, 필요한 경우에만 데이터에 접근할 수 있도록 하는 정보은닉을 제공합니다. 이는 데이터의 보안과 유지보수성을 향상시킵니다.
- 상속: 상속을 통해 코드의 재사용성을 높일 수 있으며, 객체 간의 계층 구조를 만들어 복잡한 시스템을 관리하기 용이하게 합니다.
- 다형성: 다형성은 같은 인터페이스나 추상 클래스를 공유하는 객체들을 다양하게 활용할 수 있도록 해주며, 코드의 유연성을 높입니다.
- JPA를 사용하는 이유:
- JPA는 객체지향 프로그래밍과 데이터베이스 간의 매핑을 제공합니다. 이로써 개발자는 객체를 데이터베이스 테이블로 매핑하고, 데이터베이스와 상호 작용할 수 있습니다.
- JPA는 SQL에 의존된 메서드들의 반복적인 수정을 줄여줍니다. 개발자는 객체를 조작하고 조회하기 위해 SQL 쿼리를 직접 작성하는 대신, JPA를 사용하여 객체를 CRUD (Create, Read, Update, Delete) 할 수 있습니다.
- JPA는 데이터베이스와의 상호 작용을 추상화하고, 개발자가 데이터베이스 구조에 대한 자세한 지식 없이도 효과적으로 작업할 수 있도록 돕습니다.
- JPA는 ORM (Object-Relational Mapping) 기술을 사용하여 객체와 데이터베이스 간의 변환을 자동으로 처리하므로, 유지보수 및 확장이 용이하며 개발 생산성을 높여줍니다.
1.3 JPA란 무엇인가?
- JPA(Java Persistence API)는 자바 진영의 ORM 기술 표준이다.
그림 1.6 JPA
ORM(Object-Relational Mapping)
- 객체와 관계형 데이터베이스를 매핑한다는 뜻이다.
- ORM 프레임워크는 객체와 테이블을 매핑해서 패러다임의 불일치 문제를 개발자 대신 해결해 준다.
- ORM 프로임워크를 사용하면 객체를 데이터베이스에 저장할 때 INSERT SQL을 직접 작성하는 것이 아니라
- 객체를 마치 자바 컬렉션에 저장하듯이 ORM 프레임워크에 저장하면 된다.
- ORM 프레임워크가 적절한 INSERT SQL을 생성해서 데이터베이스에 객체를 저장해 준다. 그림 1.7을 보자
그림 1.7 JPA 저장
jpa.persist(member); // 저장
조회할때도 JPA를 통해 객체를 직접 조회
그림 1.8 JPA 조회
- JPA를 사용해서 객체를 조회하는 코드는 다음과 같다.
-
Mmeber member = jpa.find(memberId); // 조회
- ORM 프레임워크는 단순히 SQL을 개발자 대신 생성해서 데이터베이스에 전달 해주는 것뿐만 아니라
- 패러다임의 불일치 문제들도 해결해준다.
- 객체 측면에서는 정교한 객체 모델링을 할 수 있고
- 관계형 데이터베이스는 데이터베이스에 맞도록 모델링하면 된다.
- 어떻게 매핑해야 하는지 매핑 방법만 ORM 프레임워크에게 알려주면 된다.
- 하이버 네이트는 거의 대부분의 패러다임 불일치 문제를 해결해주는 성숙한 ORM 프레임워크이다.
1.3.1 JPA 소개 (자바 hibernate을 기반한 ORM 기술에 대한 API 표준 명세- 인터페이스를 모아둔 것)
역사속 JPA
- 과거 자바 진영은 언터프라이즈 자바 빈즈(EJB)라는 기술 표준을 만들었는데
- 엔티티 빈이라는 ORM 기술도 포함되어있다.
- 하지만 너무 복잡하고 기술 숙성도도 떨어졌으며
- 자바 엔터프라이즈(j2EE) 애플리케이션 서버에서만 동작했다
- 하이버네이트(hiberante.org)라는 오픈 소스 ORM 프레임워크가 등장했는데 EJB의 ORM 기술과 비교해서 가볍고 실용적인 데다 기술 성숙도도 높았다.
- 결국 EJB 3.0에서 하이버 네이트를 기반으로 새로운 자바 ORM 기술표준이 만들어졌는데 이것이 JPA다
그림 1.9 JPA 표준 인터페이스와 구현체
- 그림 1.9를 보자.
JPA는 자바 ORM 기술에 대한 API 표준 명세다.
쉽게 이야기 해서인터페이스
를 모아둔 것이다.
JPA라는 표준 덕분에 특정 구현 기술에 대한 의존도를 줄일 수 있다
다른 구현기술로 손쉽게 이동할 수 있는 장점이 있다.
JPA 구현체가 제공하는 버전별 특징
- JPA 1.0 (JSR 220) 2006년: 초기 버전. 복합 키와 연관관계 기능이 부족했다.
- JPA 2.0 (JSR 317) 2009년: 대부분의 ORM 기능을 포함, JPA CriteriaRk 추가.
- JPA 2.1 (JSR 338) 2013년: 스토어드 프로시저 접근, 컨버터(Converter,) 엔티티 그래프 기능 추가.
1.3.2 왜 JPA를 사용해야 하는가?
생산성
- INSERT SQL을 작성하고 JDBC API를 상요하는 지루하고 반복적인 일은 JPA가 대신 처리해준다.
-
jpa.persist(member); // 저장 Member member = jpa.find(memberId); // 조회
- CREATE TABLE 같은 DDL 문을 자동으로 생성해주는 기능도 있다.
- 데이티베이스 설계 중심의 패러다임을 객체 설계 중심으로 역전시킬 수 있다
유지보수
DAO
- 직접 다루면 엔티티에 필드를 하나만 추가해도 관련된 등록, 수정, 조회 SQL과 결과를 매핑하기 위해 JDBC API 코드를 모두 변경해야 했다
JPA
- 개발자가 작성해야 했던 SQL과 JDBC API 코드를 JPA가 대신 처리해주므로 유지보수해야 하는 코드 수가 줄어든다.
- JPA가 패러다임의 불일치 문제를 해결해주므로 객체 지향 언어가 가진 장점들을 활용해서
- 유연하고 유지보수하기 좋은 도메인 모델을 편리하게 설계할 수 있다.
패러다임의 불일치 해결(상속, 연관 관계, 객체 그래프 탐색 비교)
- JPA는 상속, 연관관계, 객체 그래프 탐색, 비교하기와 같은 패러다임의 불일치 문제를 해결해준다.
성능(동일성 확보)
- JPA는 애플리케이션과 데이터베이스 사이에서 다양한 성능 최적화 기회를 제공한다.
- JPA는 애플리케이션과 데이터베이스 사이에서 동작한다.
String memberId = "helloId";
Member member1 = jpa.find(memberId);
Member member2 = jpa.find(memberId);
member1 == member2 // True
- SQLSWLWCT SQL을 사용해서 데이터베이스와 두 번 통신했을 것이다.
- JDBC API를 사용해서 해당 코드를 직접 작성했다면 회원을 조회할 때마다
- JPA
- 회원을 조회하는 SELECT SQL을 한 번만 데이터베이스에 전달하고 두 번째는 조회한 회원 객체를 재사용한다.
데이터 접근 추상화와 벤더 독립성
- DAO 기술에 종속
- 애플리케이션은 처음 선택한 데이터베이스 기술에 종속되고 다른 데이터베이스로 변경하기는 매우 어렵다.
- JPA는 그림 1.10처럼 애플리케이션과 데이터베이스 사이에 추상화된 데이터 접근 계층을 제공해서
- 데이터베이스 기술에 종속되지 않도록 한다.
- 만약 데이터베이스를 변경하면 JPA에게 다른 데이터베이스를 사용한다고 알려주면된다.
그림 1.10 벤더 독립성
1.4 정리
- 다양한 문제와 객체지향 언어와 관계형 데이터베이스 사이의 패러다임 불일치 문제를 설명
- JPA가 각 문제를 어떻게 해결하는지 알아보았다.
- 마지막으로 JPA가 무엇인지 설명하고 JPA의 장점들을 소개했다.
Q & A
- ORM 프레임워크를 사용하면 SQL과 데이터베이스는 잘 몰라도 되나요?
매핑을 올바르게 하려면 객체와 관계형 데이터베이스 양쪽을 모두 이해해야한다. 따라서 데이터베이스 테이블 설계나 SQL을 잘 몰라서 ORM 프레임워크를 사용한다는 것인 ORM의 본질을 잘못 이해한 것이다.
- 성능이 느리진 않나요?
N + 1 문제와 같은 성능 저하가 발생 N + 1 문제는 예를 들어 SQL 1번으로 회원 100명을 조회했는데 각 회원마다 주문한 상품을 추가로 조회하기 위해 100번의 SQL을 추가로 실행하는 것을 말한다. SQL을 실행해서 조회한 수만큼 N번 SQL을 추가로 실행한다고 해서 N + 1문제라고 한다.
- 마이바티스와 어떤 차이가 있나요?
- 마이 바티스 마이바티스나 스프링 JdbcTemplate을 보통 SQL 매퍼라 한다. 그대로 객체와 SQL을 매핑한다. 따라서 SQL과 매핑할 객체만 지정하면 지루하게 반복되는 JDBC API 사용과 응답 결과를 객체로 매핑하는 일은 SQL 매퍼가 대신 처리해준다. 이런 SQL매퍼가 편리하긴 하지만 결국 개발자가 SQL을 직접 작성해야 하므로 SQL에 의존하는 개발을 피할 수 없습니다. - JPA (ORM) 반면에 ORM은 객체와 테이블을 매핑만하면 ORM 프레임워크가 SQL을 만들어서 데이터베이스와 관련된 처리를 해주므로 SQL에 의존하는 개발을 피할 수이다.
- 학습곡선이 높다고 하던데요?JPA가 어려운 근복적인 이유는 ORM이 객체지향과 관계형 데이터베이스라는 두 기둥 위에 있기 때문이다.
- JPA의 핵심 개념인 영속성 컨텍스트에 대한 이해가 부족하면 SQL을 직접 사용해서 개발하는 것보다 못한 상황이 벌어질수 있다.
- 패러다임이 다르다. (상속, 연관 관계(참조), 객체그래프 탐색, 비교(동등, 동일))
- DAO의 문제 : 객체 모델링은 힘을 잃고 점점 데이터 중심의 모델로 변해간다.
- 하이버 네이트 패러다임의 불일치를 해결해주는 ORM 프레임워크
'개인공부 > JPA' 카테고리의 다른 글
6장 다양한 연관관계 매핑 (1) | 2024.02.05 |
---|---|
5장 연관관계 매핑 기초 (1) | 2024.02.05 |
4장 엔티티 매핑 (1) | 2024.01.30 |
3장 영속성 관리 (1) | 2024.01.23 |
2장 JPA 시작 (0) | 2024.01.20 |