

DB와 연동을 위해 제일 먼저 만드는 빈
-> DataSource : 커넥션 풀 탑재
DB계정만 알려주면 Spring Data JPA 의존성을 추가했기 때문에 내부에서 DataSource 빈이 만들어진다.
📃재복습
>docker exec -it oracle-xe /bin/bash
>sqlplus system/oracle
>CREATE USER JPA_STUDY IDENTIFIED BY oracle QUOTA UNLIMITED ON USERS;
>GRANT CONNECT, RESOURCE TO JPA_STUDY;
🔹 DB서버 알려주기

JPA 설정

로거 설정

◻ application-test.yml

복붙해서 똑같이 설정해주기
데이터베이스 설정만 바꾸기 테스트 용으로!

자바 영속성 API
영속성 : 상태 변화 감지 메모리
: 데이터 값이 변경 : UPDATE 쿼리
: 없는 데이터를 추가한 엔티티 : INSERT 쿼리
: 데이터 제거 : DELETE 쿼리

동일한 코드 -> 드라이버 변경 -> 플랫폼에 맞는 쿼리 실행
객체는 객체지향적으로, 데이터베이스는 데이터베이스 대로 설계를 한다. 그리고 ORM은 중간에서 2개를 매핑하는 역할을 함. 이를 통해 개발자는 소스를 조금 더 객체지향적으로 설계하고 비즈니스 로직에 집중할 수 있다.
JPA인터페이스를 구현한 대표적인 오픈소스가 Hibernate이다. 실질적인 기능은 하이버네이트에 구현되어 있음
EntityManagerFactory
-> EntityManager : 엔티티 영속성 관리
member - entities - Member -> 데이터 클래스

🔹 환경변수 설정

main 실행!


Member 테이블이 자동으로 추가되었다.



엔티티 클래스의 정의 : 테이블의 정의, 생성한 인스턴스도 엔티티라고 부름
@Entity가 붙은 클래스는 JPA에서 관리하며 엔티티라고한다.
엔티티 매니저 팩토리: 엔티티 매니저 인스턴스를 관리하는 주체
엔티티 매니저: 영속성 컨텍스트에 접근하여 엔티티에 대한 데이터베이스 작업을 제공함
내부적으로 데이터베이스 커넥션을 사용해서 db에 접근
🔸 엔티티 매니저의 메서드
1) find() : 조회, 기본키로 조회, 이미 영속성에 엔티티가 있으면 DB에서 조회 X - 1차 캐시, 성능상 이점

주소가 같다 -> 같은 객체를 가져옴
🔼 이미 영속성에 엔티티가 있는 상태라 select쿼리가 실행되지 않는다. 쿼리 X -> 영속성 컨텍스트 안에서 꺼내온다.
-> 영속성 컨텍스트는 1차 캐시 역할을 한다.
2) persist() : 영속성 컨텍스트에 엔티티를 영속 : 상태 감지 시작
3) remove() : 영속성 상태 -> 제거 상태 : DELETE/ 특정 엔티티클래스를 데이터 베이스에서 삭제하고자 할때
4) flush() : DB 반영
👩🏫참고) find(..) 조회 메서드 호출시 flush()가 먼저 진행 되고 -> 조회
flush 하지 않고 UPDATE 하는 법
- 자동 flush는 설정을 활성화 시켜줘야함
setFlushMode(FlushModeType.AUTO)- 값 변경 후 조회(find())하기(암묵적으로 flush()) (* 수정)
flush하지 않고 update 위해서는
em.setFlushMode(FlushModeType.AUTO);필요!!! [ex08 테스트 예제 참고]
🔽
테스트 Ex02


5) detach() : 영속성 분리 : 상태감지 X

6) clear() : 영속성 전체 제거, 현재 영속성 컨텍스트에 관리되고 있는 모든 엔티티가 분리(detach)된다. 영속성 컨텍스트를 초기화하고 새로 시작하고 싶을 때 사용
◻ 영속상태 엔티티 비우고 db에서 직접 sql 쿼리 실행되는지 테스트



변화감지하고 select 쿼리 한번 실행됨!
첫번째 find에서는 처음 실행되기때문에 영속성 컨텍스트 안에 존재하지않아서 쿼리문이 실행되지만 두번째 find에서 영속성 컨텍스트는 캐시되기 때문에 쿼리문 실행되지 않는다.
이 상태에서 값을 바꾸면 UPDATE문 실행된다.


7) merge() : 분리된 영속성 -> 영속 상태로 만듦 : 상태 감지 O

detach이후에 변화 감지를 확인하기 위해 select 쿼리가 실행되게 되고 변화 감지가 있다면 update쿼리가 실행되게 된다.

8) close(): 영속성 컨텍스트 종료, 엔티티 매니저와 영속성 컨텍스트가 종료되어 더이상 사용할 수 없게 된다.
-> 다른 엔티티 매니저나 새로운 트랜잭션을 사용하여 데이터베이스에 접근해야함
@SpringBootTest //환경변수, 테스트 설정 파일 직접 명시 할 수 있다.
@TestPropertySource(properties = "spring.profiles.active=test")
public class Ex01 {
@Autowired
private EntityManagerFactory emf;
@Test
void test1(){
EntityManager em = emf.createEntityManager();
Member member = new Member();
member.setSeq(1L);
member.setEmail("user01@test.org");
member.setPassword("12341234");
member.setUserName("사용자01");
member.setCreatedAt(LocalDateTime.now());
//영속성 관리, member라는 엔티티가 변화감지 상태에 담긴다.
em.persist(member);
em.flush();
}
}
🔽

✅ em.persist(member); //영속 상태 - 변화 감지 메모리에 있다. 변화 감지중
테스트 쪽 테이블


insert 쿼리 실행됨
값을 바꾸면 update 쿼리 실행된다.

🔽



트랜잭션 설정



detach: 변화감지를 하지 않는 상태, 영속성 분리 상태
-> merge로 다시 영속 상태 만듦
remove: 제거 상태
처음 insert
이미 관리되고있는 객체라면 update
managed <- find() <- Database

1차 캐시

영속성 컨텍스트에는 1차 캐시가 존재하며 Map<KEY, VALUE>로 저장된다.
엔티티가 존재할 경우 해당 엔티티를 반환하고, 엔티티가 없으면 데이터베이스에서 조회 후 1차 캐시에 저장 및 반환합니다.
동일성 보장
영속성 컨텍스트 쓰기 지연 SQL 저장소
트랜잭션을 지원하는 쓰기 지연
JPQL -> Java Persistence Query Language
- 모든 DB 플랫폼에 호환
- 조회 결과가 영속 상태(변화 감지 가능 상태)
JPA의 데이터베이스 초기화 전략 설정
none : 아무런 변경 X
create : 애플리케이션 시작시에 기존 테이블 DROP, 새로 생성
create-drop : 애플리케이션 시작시에 기존 테이블 DROP, 새로 생성, 종료시에도 DROP
update : 기존 테이블 DROP X, 변경 사항만 반영(한번 추가한 제약 조건은 제거 X)
validate : 기존 테이블 DROP X, 변경 사항 체크(변경 사항이 있으면 예외 발생)
👩💻개발시 : create, update
👩💻배포 서버 : none, validate