JPA 프로그래밍

Bryan, Choi
11 min readJul 28, 2015

--

https://www.facebook.com/groups/jpastudy

인텔리제이 프로젝트 설정하기

위 그림처럼 아이콘을 클릭하여 클립보드 복사!

Check out from Version Control 드롭다운 박스에서 GitHub 선택!

Git Repository URL 붙여넣고 Parent Directory에 워크스페이스 경로 잡아주고 프로젝트 루트 디렉토리를 jpabook으로 지정하고 Clone 버튼 클릭!

Yes 클릭!

Next 클릭!

Next 클릭!

Next 클릭!

Next 클릭!

Finish 클릭!

자~! 이제 책을 보며 정리를 시작해봅시다~!

다음은 직접 소스를 다운로드 받아서 메이븐 프로젝트를 Import하는 형태를 살펴보자.

download 링크를 클릭하여 프로젝트 소스를 다운로드한다.

워크스페이스 경로에 다운로드한 소스(jpabook-master)폴더를 복사한다.

인텔리제이를 실행하고 Import Project를 클릭!

jpabook-master 프로젝트 폴더를 선택하고 OK 클릭!

Next 클릭!

체크 항목들 확인 하고 Next 클릭!

Next 클릭!

Next 클릭!

Finish 클릭!

이제 진짜로 해봅시다~ ㅎㅎ

H2 데이터베이스 로컬 서버로 구동하기

http://www.h2database.com/html/download.html 이 곳에서 Version 1.3.176 (2014–04–05), Last Stable 버전에 Platform-Independent Zip 파일을 다운로드 하고 압축 해제를 한다.

위 그림과 같이 h2/bin 경로에서 java -jar h2–1.3.176.jar 명령을 실행한다.

한국어 선택, Generic H2 (Server) 선택하고 연결 버튼 클릭!

쿼리 입력 -> 실행 버튼 클릭 -> 메시지 확인 -> MEMBER 테이블 확인

2장 예제 실행

JpaMain 클래스에 마우스 우클릭하여 Run ‘JpaMain.main()’ 선택!

H2 쉘을 실행하기 위한 설정

책의 설명대로 h2/bin/h2.sh 를 실행하면 에러가 발생한다.

다운로드 받은 h2.sh 파일의 파일 포맷이 dos이기 때문에 unix로 변경해주어야 한다. 다음은 변경 하는 과정을 설명한다.

vim 명령을 이용하여 h2.sh 파일을 실행한다.

:set fileformat=unix 명령을 입력하고 엔터!

:wq 명령을 입력하고 엔터!

이제 h2.sh 파일을 직접 실행해도 에러가 발생하지 않고 정상적으로 실행된다. 이 후 과정은 이미 위에서 설명한 것과 동일하므로 생략한다.

1. 엔티티 클래스

@Entity

이 클래스를 테이블과 매핑한다고 JAP에게 알려준다. 이렇게 @Entity가 사용된 클래스를 엔티티 클래스라 한다.

문제1) @Entity 적용시 주의사항이 아닌것은?

  1. public 또는 protected 기본 생성자는 필수다.
  2. final 클래스에 사용할 수 없다.
  3. inner 클래스에 사용할 수 없다.
  4. enum 클래스에 사용할 수 없다.
  5. interface 에 사용할 수 없다.
  6. 저장 할 필드에 final을 사용하면 안된다.
  7. name 속성에 값이 반드시 있어야 한다.

@Table

엔티티 클래스에 매핑할 테이블 정보를 알려준다. 이 어노테이션을 생략하면 클래스 이름을 테이블 이름으로 매핑한다(더 정확히는 엔티티 이름을 사용한다).

문제2) @Table의 속성에 대한 설명이다. 잘못된 것은?

  1. name 속성에 매핑할 테이블 이름을 지정한다.
  2. catalog 속성과 schema 속성은 데이터베이스에 기능이 있을 때 매핑한다.
  3. uniqueConstraints(DDL) 속성은 DDL 생성 시에 유니크 제약조건을 만든다. 2개 이상의 복합 유니크 제약 조건은 만들 수 없다.
  4. uniqueConstraints 속성은 스키마 자동 생성 기능을 사용해서 DDL을 만들 때만 사용된다.

@UniqueConstraints

DDL 자동 생성 시 @Table에 유니크 제약 조건 지정시 사용한다.

name, columnNames

@Id

엔티티 클래스의 필드를 테이블의 기본 키에 매핑한다. 이렇게 @Id가 사용된 필드를 식별자 필드라 한다.

문제3) @Id로 사용되는 필드의 타입으로 사용할 수 없는 것은?

  1. 기본형
  2. Wrapper 형
  3. String
  4. Date
  5. BigDecimal
  6. BigInteger
  7. Object

@GeneratedValue

식별자가 생성되는 경우에 사용된다. (예-MySQL의 자동 증가)

문제4) 기본 키 할당 전략으로 사용할 수 없는 전략은?

  1. 직접 할당 전략
  2. IDENTITY 전략 (선DB입력 후 캐싱:쓰기지연 불가)
  3. SEQUENCE 전략 (선DB 시퀀스 조회 후 캐싱)
  4. TABLE 전략
  5. AUTO 전략
  6. DYNAMIC 전략

@SequenceGenerator

오라클, PostgreSQL, DB2, H2 데이터베이스에서 시퀀스를 지원한다. 시퀀스 생성기를 등록한다.

name, sequenceName, initialValue(DDL), allocationSize, catalog, schema

@TableGenerator

테이블 키 생성기를 등록한다. @SequenceGenerator 대신에 사용하여 모든 데이터베이스에 사용할 수 있다.

name, table, pkColumnName, valueColumnName, pkColumnValue, initalValue, allocationSize, catalog, schema, uniqueConstraints(DDL)

@Column

필드를 컬럼에 매핑한다. 매핑 정보가 없는 엔티티 클래스의 필드는 필드명을 사용해서 컬럼명으로 매핑한다. (대소문자를 구분하는 데이터베이스라면 @Column(name=”컬럼명대문자") 형태로 명시적으로 매핑해야 한다.

name, insertable, updatable, table, nullable(DDL), unique(DDL), columnDefinition(DDL), length(DDL), precision(DDL), scale(DDL)

@Enumerated

자바의 enum 타입을 매핑할 때 사용한다.

EnumType.ORDINAL, EnumType.STRING

@Temporal

날짜 타입을 매핑할 때 사용한다.

TemporalType.DATE, TemporalType.TIME, TemporalType.TIMESTAMP

@Lob

데이터베이스 BLOB, CLOB 타입과 매핑한다.

문자 : CLOB, 나머지 : BLOB

@Transient

데이터베이스에 저장하지 않고 조회하지도 않고, 객체에 임시로 어떤 값을 보관하고 싶을 때 사용한다.

@Access

JPA가 엔티티 데이터에 접근하는 방식을 지정한다.

AccessType.FIELD, AccessType.PROPERTY

2. 연관관계 매핑

@ManyToOne

다대일 관계

optional, fetch, cascade, targetEntity

@OneToMany

일대다 관계

@OneToOne

일대일 관계

@JoinColumn

외래 키 매핑

name, referencedColumnName, foreignKey(DDL)

unique, nullable, insertable, updatable, columnDefinition, table

@JoinTable

조인 테이블 매핑

@IDClass

복합 기본 키 매핑

3. 고급 매핑

@MappedSuperclass

여러 엔티티에서 공통으로 사용하는 매핑 정보만 상속받는 기능

@Inheritance

상속 매핑을 위해 부모 클래스에 선언해야 한다.

@DiscriminatorColumn

부모 클래스에 구분 컬럼을 지정한다. 이 컬럼으로 자식 테이블을 구분할 수 있다.

@DiscriminatorValue

엔티티를 저장할 때 구분 컬럼에 입력값을 지정한다.

@PrimaryKeyJoinColumn

자식 테이블의 기본 키 컬럼명을 변경한다.

@AttributeOverrides, @AttributeOverride

부모로 부터 물려받은 매핑 정보를 재정의 한다.

@EmbededId

부모 엔티티에서 식별자 클래스를 직접 사용하고 싶은 경우 사용한다.

@Embedable

부모 클래스에 @EmbededId를 사용하려면 지정한다.

@ MapsId

@EmbededId로 식별 관계를 구성할 때 사용한다.

@SecondaryTable, @SecondaryTables

하나의 엔티티에 여러 테이블 매핑.

애플리케이션

  1. 엔티티 매니저 팩토리 생성 (Persistence)

2. 엔티티 매니저 생성 (emf)

3. 트랜잭션 API 취득 (em)

4. 트랜잭션 시작

5. CRUD 로직

6. 트랜잭션 커밋

7. 예외 처리 : 트랜잭션 롤백

8. finally : em.close()

9. 애플리케이션 종료 처리 : emf.close()

영속성 컨텍스트

  • 영속 상태 : 1차 캐쉬에 @Id값을 키로 엔티티 인스턴스가 저장된 상태 (스냅샷 포함 — 최초 저장된 엔티티 객체의 복사본 : 변경 감지용)
    (입력,수정,삭제 시 “쓰기 지연 SQL 저장소”에 쿼리 저장)
  • 비영속 상태 : 엔티티 객체를 생성하고 1차 캐쉬에 저장되지 않은 상태
  • 준영속 상태 : 영속성 컨텍스트로 부터 분리된 상태
  • 삭제 상태 : 영속성 컨텍스트에서 삭제된 상태

em.find(Entity.class, id), em.persist(entity), entity.setXXX(), em.remove(entity), JPQL (TypedQuery<Entity>)

em.detech(entity), em.clear(), em.close(), em.merge()

tx.begin(), tx.commit(), tx.rollback(), em.flush()

--

--