Hello JPA - 애플리케이션 개발
주의할점 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 구동 방식⭐️
- persistence.xml 파일을 JPA가 읽어서 데이터베이스 연결 및 엔티티 관련 설정 정보 로드.
- ex. 데이터베이스 URL, 사용자명, 비밀번호, 하이버네이트 등 JPA 구현체에 대한 설정이 포함 - JPA는 이 설정 파일을 읽고, 이를 기반으로 Persistence Unit 생성
- 이과정에서 Persistence.createEntityManagerFactory() 메서드를 통해 애플리케이션에서 사용할 EntityManagerFactory객체를 생성 되며, 이는 여러 EntityManager 객체를 생성할 수 있는 팩토리 역할
- EntityManagerFactory객체 : 애플리케이션 전체에서 단일하게 생성되는 팩토리 객체 - 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 : 데이터베이스 테이블을 대상으로 개발
'Study Platform📚 > 김영한👨🏻🏫의 스프링 부트와 JPA 실무 완전 정복 로드맵' 카테고리의 다른 글
연관관계 매핑 기초 (0) | 2024.11.25 |
---|---|
엔티티 매핑 - 객체와 관계형 데이터베이스 매핑(설계)하기(Object Relational Mapping) (2) | 2024.11.20 |
영속성 관리 - 내부동작 방식 (0) | 2024.11.04 |
자바 ORM 표준 JPA 프로그래밍 - JPA 시작하기(맞는 버전 찾기) (1) | 2024.10.23 |