티스토리 뷰
| JPA(Java Persistence API)
|| JPA 요약
- 객체 모델과 관계형 데이터베이스 모델의 지향하는 패러다임 불일치를 해결
- 반복되는 SQL 작성과 JDBC API 사용을 해결
- SQL에 의존적인 개발을 해결 --> JPA는 엔티티 중심의 개발 (DB에 대한 처리는 JPA가)
- 개발자는 데이터 중심인 관계형 데이터베이스를 사용해도 객체지향 애플리케이션 개발에 집중
- 자바 ORM 기술에 대한 API 표준 명세
* ORM(Object-Relational Mapping): 객체와 관계형 데이터베이스를 매핑한다는 의미 (패러다임의 불일치 해결)
- JPA는 애플리케이션과 JDBC 사이에서 동작
[애플리케이션 [JPA [JDBC API]]] <-> [DB]
- SQL을 개발자 대신 생성해서 DB에 전달
- 객체 측면에서 정교한 객체 모델링 가능
- 관계형 데이터베이스는 데이터베이스에 맞도록 모델링
- 다양한 ORM 프레임워크가 있는데 그 중에 Hibernate framework가 가장 많이 활용
=> Hibernate 기반으로 새로운 자바 ORM 기술 표준이 만들어진 것이 JPA
- 특정 데이터베이스에 종속적이지 않음
1 2 3 4 5 | <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> </dependency> | cs |
|| JPA 장점
> 생산성
- JPA에게 저장할 객체를 전달 (반복적인 일은 JPA가 대신 처리)
1 2 3 | jpa.persist(member) // 저장 Member member = jpa.find(memberId); // 조회 | cs |
> 유지보수
- SQL에 의존적인 개발문제 해결
> 패러다임의 불일치 해결
- 상속, 연관관계, 객체 그래프 탐색, 비교
> 성능
- 애플리케이션과 데이터베이스 사이에서 다양한 성능 최적화 기회를 제공
- SQL을 한 번만 데이터베이스에 전달하고 두 번째는 조회한 객체를 재사용
> 데이터 접근 추상화와 벤더 독립성
- 애플리케이션이 특정 데이터베이스 기술에 종속되지 않음
> 표준
- 자바 진영의 ORM 기술 표준
|| 객체 매핑
- JPA는 매핑 어노테이션을 분석해서 어떤 객체가 어떤 테이블과 관계가 있는지 알아냄
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import javax.persistence.*; @Entity @Table(name="MEMBER") public class Member { @Id @Column(name = "ID") private String id; @Column(name = "NAME") private String username; private Integer age; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } | cs |
@Entity
- 이 클래스를 테이블과 매핑한다고 JPA에게 선언
- @Entity가 사용된 클래스를 엔티티 클래스라고 부름
@Table
- 엔티티 클래스에 매핑할 테이블 정보
- Name 속성을 사용하여 Member 엔티티를 MEMBER 테이블 매핑
@Id
- 엔티티 클래스의 필드를 테이블의 기본 키에 매핑
- @Id 필드가 사용된 필드를 식별자 필드
@Column
- 필드를 컬럼에 매핑
- Name 속성을 사용해서 Member 엔티티의 username 필드를 MEMBER 테이블의 NAME 컬럼에 매핑
@매핑 정보가 없는 필드
- 필드명을 사용해서 컬럼명으로 매핑
- 데이터베이스가 대소문자를 구분하지 않는다면 @Column(name="")로 명시적 매핑 필요
|| persistence.xml 설정
데이터베이스 방언 설정 시 참고.
https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#configuration-optional-dialects
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1"> <!-- 영속성 유닛 --> <!-- 일반적으로 연결할 데이터베이스당 하나의 영속성 유닛을 등록 --> <persistence-unit name="jpabook"> <properties> <!-- 필수 속성 --> <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/> <!-- JDBC 드라이버 --> <property name="javax.persistence.jdbc.user" value="sa"/> <!-- DB 접속 ID --> <property name="javax.persistence.jdbc.password" value=""/> <!-- DB 접속 PW --> <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/> <!-- DB 접속 URL --> <!-- DB Dialect 설정 --> <!-- DB 변경 시 DB 방언(Dialect)만 교체 --> <!-- 오라클 10g : org.hibernate.dialect.oracle10gdialect MySQL : org.hibernate.dialect.mysql5innodbdialect SQL Server : org.hibernate.dialect.sqlserver2012dialect --> <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" /> <!-- 옵션 --> <property name="hibernate.show_sql" value="true" /> <!-- hibernate가 실행한 SQL을 출력 --> <property name="hibernate.format_sql" value="true" /> <!-- hibernate가 실행한 SQL 출력 시 정렬 --> <property name="hibernate.use_sql_comments" value="true" /> <!-- 쿼리 출력 시 주석도 함께 출력 --> <property name="hibernate.id.new_generator_mappings" value="true" /> <!-- JPA 표준에 맞춘 새로운 키 생성 전략 사용 --> <!--<property name="hibernate.hbm2ddl.auto" value="create" />--> </properties> </persistence-unit> </persistence> | cs |
|| 엔티티 매니저 설정
ㅇ 엔티티 매니저 팩토리 생성
- 엔티티 매니저를 만드는 공장
- persistence.xml 설정 정보를 사용해서 엔티티 매니저 팩토리 생성
- 엔티티 매니저 팩토리 생성 비용이 크므로 애플리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야 함
- 엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하므로 서로 다른 스레드 간에 공유해도 되지만,
엔티티 매니저는 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 스레드 간에 절대 공유하면 안됨!
ㅇ 엔티티 매니저 생성
- 엔티티 매니저 팩토리에서 엔티티 매니저 생성
- JPA 대부분 기능은 엔티티 매니저가 제공 (엔티티를 데이터베이스에 등록 / 수정 / 삭제 / 조회)
- 내부에 데이터소스(데이터베이스 커넥션)를 유지하면서 데이터베이스와 통신
- 데이터 베이스 연결이 꼭 필요한 시점까지 커넥션을 얻지 않음(트랜젝션 시작 시 커넥션 획득)
ㅇ 종료
- 사용이 끝난 엔티티 매니저는 반드시 종료해야 함.
- 애플리케이션을 종료할 때 엔티티 매니저 팩토리도 종료
|| 트랜잭션 관리
- JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야 함 (그렇지 않을 경우 예외 발생)
- 트랜잭션 시작은 엔티티 매니저에서 트랜잭션 API를 받아와야 함
- 정상 동작 시 commit, 예외 발생 시 rollback
|| 비즈니스 로직
> 등록
- 엔티티 매니저의 persist() 메소드에 저장할 엔티티를 넘겨주자
- JPA는 회원 엔티티의 매핑 정보(Annotation)을 분석해서 SQL을 생성 후 DB에 전달
1 2 3 4 5 6 7 8 | String id = "id1"; Member member = new Member(); member.setId(id); member.setUsername("지한"); member.setAge(2); //등록 em.persist(member); | cs |
> 수정
- JPA는 어떤 엔티티가 변경되었는지 추적하는 기능을 갖춤
- Set() 메서드로 엔티티 값만 변경하면 Update SQL을 생성해서 DB에 값을 변경
1 2 | //수정 member.setAge(20); | cs |
> 삭제
1 | em.remove(member); | cs |
> 한 건 조회
- find() : 조회할 엔티티 타입과 @Id로 DB 테이블의 기본 키와 매핑한 식별자 값으로 엔티티 하나를 조회
1 2 | Member findMember = em.find(Member.class, id); System.out.println("findMember=" + findMember.getUsername() + ", age=" + findMember.getAge()); | cs |
> 목록 조회
- 검색 조건이 포함된 SQL을 사용
- JPQL(Java Persistence Query Language) : 엔티티 객체를 대상으로 쿼리
1 2 | List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList(); System.out.println("members.size=" + members.size()); | cs |
출처 : 자바 ORM 표준 JPA 프로그래밍
'Books' 카테고리의 다른 글
[JPA] 고급 매핑(상속관계, 복합키, 식별/비식별, 조인 테이블) (0) | 2020.12.21 |
---|---|
[JPA] 다양한 연관관계 매핑 (0) | 2020.12.21 |
[JPA] 연관관계 매핑이란.? (0) | 2020.12.19 |
[JPA] 엔티티와 매핑. @Entity, @Table, @Id, @Column.. (0) | 2020.12.18 |
[JPA] 영속성(persistence)이란? (0) | 2020.12.18 |