쿄코코 2024. 10. 24. 20:30
반응형

주의할점 1. h2와 persistence.xml 의 url 값을 동일, 사용자(user) 값 동일, 비밀번호(password) 값 동일

<property name="jakarta.persistence.jdbc.user" value="sa"/>
<property name="jakarta.persistence.jdbc.password" value=""/>
<property name="jakarta.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>


 

<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>

데이터베이스 방언⭐️

  • 특정 데이터베이스에 종속 X ( ex. MySQL쓰다가 Oracle로 변경해도 변경되어야함)
  • 각각의 데이터 베이스가 제공하는 SQL 문법과 함수가 다름
    • 가변 문자: MySQL- VARCHAR, Oracle- VARCHAR2
    •  문자열을 자르는 함수: SQL - SUBSTRING(), Oracle - SUBSTR()
    • 페이징 : MySQL - LIMIT, Oracle - RWONUM
  • 방언 : SQL표준을 지키지 않는 특정 데이터베이스만의 고유한 기능
  • H2를 사용할 때 방언이 중요한 이유는, 만약 H2를 테스트 용도로 사용하고 실제 운영에서는 다른 DBMS(MySQL, PostgreSQL 등)를 사용한다면, SQL 쿼리가 두 DBMS에서 동일하게 동작하는지 확인작업 필요.
  • 각 DBMS마다 지원하는 SQL 기능이 조금씩 다를 수 있기 때문에, 이를 해결하기 위해 "방언"을 고려하여 SQL을 작성하거나 변환하는 작업이 필요

 


 

JPA 구동 방식⭐️

  1.  persistence.xml  파일을 JPA가 읽어서 데이터베이스 연결 및 엔티티 관련 설정 정보 로드.
    - ex. 데이터베이스 URL, 사용자명, 비밀번호, 하이버네이트 등 JPA 구현체에 대한 설정이 포함
  2. JPA는 이 설정 파일을 읽고, 이를 기반으로 Persistence Unit 생성
  3. 이과정에서  Persistence.createEntityManagerFactory()  메서드를 통해 애플리케이션에서 사용할 EntityManagerFactory객체를 생성 되며, 이는 여러 EntityManager 객체를 생성할 수 있는 팩토리 역할
    - EntityManagerFactory객체 : 애플리케이션 전체에서 단일하게 생성되는 팩토리 객체
  4. EntityManager는 실제 데이터베이스와 상호작용하며 트랜잭션을 관리하고, 엔티티 객체를 통해 데이터베이스 작업을 수행
    - EntityManager : 이런 엔티티 객체를 통해 데이터베이스의 데이터를 저장, 조회, 수정, 삭제 등의 작업을 할 수 있도록 도와줌.

‼️ JPA 구동방식은 애플리케이션 전체에서 EntityManagerFactory는 한 번만 생성, 각 트랜잭션마다 여러 개의 EntityManager를 만들어서 데이터를 관리 ‼️

 


 

주의할점 2. 자바 파일에서는 @Entity 라는 걸 꼭 넣기..! > 이걸 넣어야지만 jpa 파일이라는 것을 인식 할 수 있음

 

참고 - IntelliJ 맥북에서 Getter Setter 단축키는  Commnad + N  이용해서 만들기...!

 

주의할점 3. 모든 JPA에서 트랜잭션이라는 단위가 중요하다. 

 

EntityTransaction tx = em.getTransaction();
tx.begin();

em.persist(member);
tx.commit(); //커밋하기

 

트랜잭션⭐️

여러 작업을 하나의 논리적 작업 단위로 묶는 개념으로, 이 작업 단위가 완전히 성공하거나, 완전히 실패하는것을 보장.

트랜잭션의 중요한 틀성(ACID)

  • 원자성(Atomicity): 트랜잭션 안의 모든 작업은 모두 성공하거나 모두 실패
  • 일관성(Consistency): 트랜잭션은 데이터베이스의 일관성을 깨지 않도록 보장
  • 고립성(Isolation): 하나의 트랜잭션이 완료되기 전까지 다른 트랜잭션이 영향을 받지 않도록 격리
  • 지속성(Durability): 트랜잭션이 커밋되면 그 결과는 영구적으로 데이터베이스에 반영

트랜잭션이 중요한 이유

 

  • 데이터의 일관성 유지: 여러 데이터 수정 작업이 하나의 트랜잭션 안에서 이루어지면, 중간에 실패할 경우 모든 작업을 되돌려서 데이터베이스의 일관성을 보장
  • 오류 처리: 트랜잭션 안에서 작업이 실패하면 쉽게 롤백하여 오류 발생 시 안전하게 데이터를 복구
  • 다중 사용자 환경에서의 안정성: 여러 사용자가 동시에 데이터베이스에 접근하는 경우, 트랜잭션을 사용하면 한 트랜잭션이 다른 트랜잭션의 작업에 영향을 주지 않도록 격리

그렇기에 트랜잭션을 시작하는 부분이 에러가 발생한다. 그렇기에 아래 코드처럼 실행할 경우에는 에러가 발생

EntityManager em = entityManagerFactory.createEntityManager();
em.persist(member);  // 트랜잭션 없이 persist 시도

 

 

 


 

참고사항 1. member 테이블에 insert 하도록 만들어지고. 만약 table이랑 다른 경우에는 @Table(name ="USER") 쓴다.

//member 테이블에 insert 하도록 
Member member =new Member();
member.setId(2L);
member.setName("helloB");

 

@Entity
@Table(name ="USER")
@Getter
@Setter
public class Member {

    @Id
    private Long id;
    
    @Column(name="username")
    private String name;
}

 

 

참고사항 2. EntityManager member 조회하기

try{
    //member 찾아오기
    Member findMember = em.find(Member.class, 1L);
    System.out.println("findMember.id: "+findMember.getId());
    System.out.println("findMember.name: "+ findMember.getName());

    tx.commit();
}catch (Exception e){
    //잘못하면 rollback
    tx.rollback();
}finally {
    em.close();
}

 

참고사항 3. EntityManager member 삭제하기

//member 삭제
Member findMember = em.find(Member.class, 1L);
em.remove(findMember);

 

참고사항 4. EntityManager member 이름 변경

 - JPA가 트랜잭션이 바꼈는지 확인해서 UPDATE 쿼리 이용해서 날리기에 Java JPA만 변경해도 변경이 된다.

//member 이름 변경
Member findMember = em.find(Member.class, 1L);
findMember.setName("helloJPA");//JAVA JPA만 변경해도 변경됨

tx.commit();

 

참고사항 5. Query문 넣어서 list 객체 반환 > 이렇게 할 수 있는게 어떤 메리트가 있을까?는 바로 밑 코드 참고

- 인텔리제이 맥북에서 자동으로 변수 명명해주는 명령어 (Option + Enter )

//Member 객체를 대상으로 QUERY를 가져옴
List<Member> result = em.createQuery("select m from Member as m", Member.class).getResultList();
for(Member member:result)
{
    System.out.println("member.name = "+member.getName());
}
//방언에 맞춰서 여러가지 Query들을 가져올 수 있음
List<Member> result = em.createQuery("select m from Member as m", Member.class)
        .setFirstResult(5)
        .setMaxResults(8)
        .getResultList();



JPQL⭐️

 

  • JPQL 사용: Member 객체를 대상으로 객체 지향 쿼리를 작성하여, SQL을 직접 작성하지 않고도 데이터베이스에서 데이터를 가져올 수 있습니다.
  • JPQL의 장점: 데이터베이스에 독립적인 쿼리를 작성할 수 있으며, 페이징 같은 기능도 자동으로 처리. 방언을 변경해도 변경해야하는 코드가 없다..!
  • 엔티티 대상 쿼리: JPA는 테이블이 아닌 엔티티 객체를 대상으로 쿼리를 작성합니다. JPA가 이를 데이터베이스에 맞는 SQL로 변환하고 실행
  • 결국,애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검 색 조건이 포함된 SQL이 필요

 


 

 

결론. 
EntityManagerFactory는 애플리케이션 하나만 생성해서 공유
EntityManger는 고객의 요청이 올때마다 썼다가 버렸다가 하는 것이다.(여러 Thread 공유 절대 X)
JPA의 모든 데이터 변경은 트랜잭션 안에서 실행

JPQL:  엔티티 객체를 중심으로 개발 <-> SQL : 데이터베이스 테이블을 대상으로 개발


 

 

 

반응형