JPA이용한 DB연동

노건우·2023년 10월 10일
0

Spring

목록 보기
13/22
post-thumbnail

1. 🖊️영속성 컨텍스트

1-1. 엔티티 등록 - 트랜잭션을 지원하는 쓰기 지연

트랜잭션을 지원하는 쓰기 지연"은 데이터베이스 엔티티를 생성, 수정 또는 삭제할 때, 이러한 변경 내용을 데이터베이스에 즉시 반영하지 않고, 트랜잭션 내에서 변경 내용을 모아두었다가 트랜잭션이 커밋될 때 한 번에 데이터베이스에 적용하는 기술을 가리킨다.

Entitymanager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
ts.begin();	//트랜잭션 시작

em.persist(memberA);
em.persist(memberB);
//여기까지 InsertSQL을 데이터베이스에 보내지 않는다.

//커밋하는 순간 데이터베이스에 insert SQL을 보낸다.

ts.commit();	//트랜잭션 커밋(종료)

1-2. 엔티티 수정 - 변경감지

Entitymanager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
ts.begin();	//트랜잭션 시작

 // 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");

//엔티티 데이터 수정 - 변경감지(dirty checking)
memberA.setUsername("admin")
memberA.setAge(20);

//em.update(memberA); 이런 코드가 있어야하지 않을까?(아님)


ts.commit();	//트랜잭션 커밋(종료)

em.update(memberA); 이 코드가 필요하지 않은 이유는, JPA는 엔티티 객체의 상태를 관리하고, 변경을 감지하고, 트랜잭션 커밋 시에 변경 내용을 데이터베이스에 자동으로 반영해주기 때문에 굳이 쓸 필요가 없다.
그렇다면 옳은 코드는

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
Member memberA = em.find(Member.class, "memberA");
memberA.setUsername("admin");
memberA.setAge(20);
// 여기서 명시적인 업데이트 호출은 필요하지 않다.
transaction.commit();

이런 코드이다. 즉 JPA가 변경 내용을 감지하고 자동으로 데이터베이스에 반영합니다. 명시적인 em.update(memberA); 호출이 필요하지 않으며, JPA가 관리하는 엔티티의 변경은 트랜잭션 커밋 시에 자동으로 처리된다.

-> flush()가 호출되는 시점에 Entitiy와 스냅샷을 전부 비교 후(최적화된 알고리즘으로 진행)변경이 된 것을 감시(Dirty Checking)한 후에 update쿼리를 작성 후,
update쿼리를 날린다.

1-3. 엔티티 삭제

//삭제 대상 엔티티 조회
Member memberA = em.find(Member.class,"memberA");

em.remove(memberA);

2. 💻플러시

✍️flush가 무엇인가?
JPA(Java Persistence API)에서 사용되는 메서드로, 영속성 컨텍스트(Persistence Context)에 있는 변경 내용을 데이터베이스에 동기화하는 역할을 합니다. 즉, flush를 호출하면 영속성 컨텍스트에 저장된 엔티티의 변경 내용이 데이터베이스에 반영된다.

2-1. 플러시 발생

  • 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영
  • 변경감지
  • 수정된 엔티티 쓰기 지연 sql 저장소에 등록
  • 쓰기 지연 SQL저장소의 쿼리를 데이터베이스에 전송
    (등록,수정,삭제 쿼리)

2-2. 영속성 컨텍스트를 플러시 하는 방법

  • 트랜잭션 커밋 - 플러시 자동 호출

  • em.flush() - 직접 호출

  • jpql 쿼리 실행 - 플러시 자동 호출

    2-3. 플러시 주요사항

  • 영속성 컨텍스트를 비우지 않음

  • 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화

  • 트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화 하면 됨

  • JPA는 동시성, 데이터를 맞추거나 모두 트랜잭션에 위임한다.

2-4. 준영속 상태

  • 영속상태 -> 준영속 상태
  • 준영속 : 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)
  • 영속성 컨텍스트가 제공하는 기능을 사용 못함

2-5. 준영속 상태로 만드는 방법(알아만 둘 것)

  • em.detach(entity)
    :특정 엔티티만 준영속 상태로 전환
  • em.clear()
    : 영속성 컨텍스트를 완전히 초기화
    -em.close()
    :영속성 컨텍스트를 종료

3. 🤜🤛엔티티 매핑 소개

  • 객체와 테이블 매핑 :@Entity, @Table
  • 필드와 컬럼 매핑:@Column
  • 기본 키 매핑 : @Id
  • 연관관계 매핑 : @ManyToOne, @JoinColumn

3-1. 객체와 테이블 매핑 - @Entity

  • @Entity가 붙은 클래스는 jpa가 관리하는 엔티티라 한다.
  • jpa를 사용해서 테이블과 매핑할 클래스는 @Entity필수
  • 주의사항
    ->기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자)
    -> final 클래스, enum, interface, inner 클래스 사용 x
    -> 저장할 필드 final 사용 x

3-2. @Entity 속성 정리

  • 속성 : name
    -> jpa에서 사용할 엔티티 이름을 지정
    -> 기본값 : 클래스 이름을 그대로 사용한다
    -> 같은 클래스 이름 없으면 가급적 기본값을 이용한다.
    ->기본값을 쓸 것

3-3. @Table

  • 엔티티와 매핑할 테이블 지정
  • name : 매핑할 테이블 이름(엔티티 이름을 사용)
  • catalog : 데이터베이스 catalog매핑
  • schema : 데이터베이스 schema
  • uniqueConstraints : DDL 생성시에 유니크 제약 조건 생성

4. 데이터베이스 스키마 자동생성

  • hibernate.hbm2ddl.auto

  • create : 기존 테이블 삭제 후 다시생성(Drop + Create)

  • create-drop : create와 같으나 종료시점에 drop

  • update : 변경문만 반영(운영 DB에는 사용하면 안됨)

  • validate : 엔티티와 테이블이 정상 매핑 되었는지만 확인

  • none : 사용하지 않음
    => 데이터베이스 방언별로 달라진다.

  • 운영장비에는 절대 create, create-drop,update사용하면 안됨

  • 개발 초기 단계는 create 또는 update

  • 테스트 서버는 update 또는 validate

  • 스테이징과 운영서버는 validate 또는 none

create, update등을 함부로 사용했다가는 실제 개발과정에서 큰 문제가 생길 수 있다. 자동생성을 이용하자.

5. DDL 생성 기능

  • 제약조건 추가: 회원이름은 필수, 10자 초과X
    -> @Column(nullable = false, length=10)

  • 유니크 제약조건 추가
    -> @Table(uniqueConstraints={
    @UniqueConstraint(name="NAME_AGE_UNIQUE",
    columnNames={"NAME","AGE"}
    )
    })

=> DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.

6. 필드와 컬럼 매핑

-@Column : 컬럼 매핑
-@Temporal : 날짜 타입 매핑
-@Enumerated : enum타입 매핑
-@Lob :BLOB,CLOB매핑
-@Transient :특정 필드를 컬럼에 매핑하지 않음(매핑 무시)

7. @Column

-name:필드와 매핑할 테이블의 컬럼 이름
-nullable : null값의 허용 여부를 설정한다. false로 설정하면 DDL 생성시에 not null 제약조건이 붙는다.
-unique : uniqueConstraints와 같지만 한 컬럼에 간단히 유니크 제약조건을 걸 때 사용한다.
-length : 문자길이 제약조건, String 타입에만 사용

8. 기본키 매핑 방법

  • 직접 할당 : @Id만 사용

  • 자동 생성 : @GeneratedValue -> 전략
    -> IDENTITY
    : 데이터베이스에 위임, MYSQL,SQL Server, DB2
    ->SEQUENCE
    : 데이터베이스 시퀀스 오브젝트 사용, ORACLE, PostgreSQL, DB2, H2
    @SequenceGenerator 필요
    ->TABLE
    : 키 생성용 테이블 사용, 모든 DB에서 사용
    @TableGenerator필요
    ->AUTO
    :방언에 따라 자동 지정, 기본값

    	-> auto는 DB방언에 맞춰서 IDENTITY,SEQUENCE,TABLE 3개의 방식중 하나가 선택이 된다.

9.@SequencGenerator

  • name :식별자 생성기 이름
  • sequenceName : 데이터베이스에 등록되어 있는 시퀀스 이름
  • initialValue : DDL 생성 시에만 사용됨, 시퀀스 DDL을 생성할 때 처음 생성되는 수를 지정한다.(기본값1)
    -allocationSize : 시퀀스 한 번 호출에 증가하는 수
    (데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 한다.)(기본값 50)
  • catalog, schema : 데이터베이스 catalog,schema

10. TABLE 전략 -> 잘 쓰진 않는다.

  • 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략
  • 장점 : 모든 데이터베이스에 적용가능
  • 단점 : 성능

11. 연관관계 매핑 기초

  • 객체와 테이블 연관관계의 차이를 이해
  • 객체의 참조와 테이블의 외래키를 매핑
  • 용어 이해
    ->방향(Direction): 단방향, 양방향
    -> 다중성(Multiplicity) : 다대일(N:1),일대다(1:N),일대일(1:1),다대다(N:M)
    ->연관관계 주인(Owner) : 객체 양방향 연관관계는 관리하는 주인이 필요하다.
profile
초보 개발자 이야기

0개의 댓글

관련 채용 정보