<aside> ❗
스프링 홈페이지에서 Spring-boot에 맞는 라이브러리 버전을 명시해놨는데 찾아서 넣으면 됨
</aside>
<aside> ❗
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="<http://xmlns.jcp.org/xml/ns/persistence>"
xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"
xsi:schemaLocation="<http://xmlns.jcp.org/xml/ns/persistence> <http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd>">
<persistence-unit name="hello">
<properties>
<!-- 필수 속성 -->
<property name="jakarta.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="jakarta.persistence.jdbc.user" value="sa"/>
<property name="jakarta.persistence.jdbc.password" value=""/>
// 접근 URL - JDBC URL과 동일해야 함
<property name="jakarta.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
// 어떤 방언을 쓰는지 지정해주는 것 -> 그래야 JPA가 알아서 방언을 해석해서 쓴다.
// hibernate 전용 옵션
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
// Start 다른 라이브러리 사용 시 모두 바꿔 줘야 함
<!-- 옵션 -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
// End 다른 라이브러리 사용 시 모두 바꿔 줘야 함
</properties>
</persistence-unit>
</persistence>
JPA 영속성 유닛의 이름을 정의
보통 데이터베이스 당 하나씩 설정
JPA에서는 Persistence.createEntityManagerFactory("hello")를 호출할 때 이 name을 사용하여 해당 설정을 로드
<aside> ❗
JPA는 특정 데이터베이스에 종속적이지 않음
→ Mysql을 사용하다 Oracle로 바꿔도 바꿀 수 있어야 함 (이론적)SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능
!!!! [hibernate.dialect 속성에 지정 ]
하이버네이트는 40가지 이상의 데이터베이스 방언 지원
</aside>
<aside> ❗
persistence.xml 설정 정보를 읽어서
EntityManageFactory 클래스를 생성
EntityManagerFactory
는 애플리케이션 로딩 시점에 하나만 생성
해서
애플리케이션 전체에서 공유
실제 데이터를 저장하는 트랜잭션 단위
에서는 EntityManager를 만들어줘야 한다.
즉, 커넥션 얻어서 DB 사용할 때 마다 생성해야 함
**** 엔티티 매니저는 쓰레드 간에 공유 X (사용하고 버려야 함)
→ 멀티 스레드 환경에서 동시 접근 시 문제가 발생할 수 있음
(데이터 일관성, 동시성 문제)EntityManageFactory
에서 필요할 때마다
EntityManager
만들어서 수행한다.public static void main(String[] args( {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
// 실제 애플리케이션 실행이 끝나면 EntityManagerFactory를 닫아줘야 한다.
em.close();
emf.close();
}
</aside>
<aside> ❗
@Entity - JPA가 관리할 객체
@Id - 데이터베이스 PK와 매핑
@Entity
public class Member {
@Id
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Table(name= "USER")
애너테이션을 붙이면
INSERT는 USER 테이블에 대해 수행@Column(name = “username”)
애너테이션에 붙이면
객체에 저장된 name 값이 username 컬럼에 저장
된다.****** 매우 중요 ******
JPA에서는 데이터를 변경하는 모든 작업은 트랜잭션 안에서 작업을 수행
해야 한다.
단순 데이터 조회의 경우 가능EntityManagerFactory
는 애플리케이션 로딩 시점에
하나만 생성
해서 애플리케이션 전체에서 공유
(DB당 하나씩 생성)실제 데이터를 저장하는 트랜잭션 단위
에서는 EntityManager를 만들어줘야 한다.
즉, 커넥션 얻어서 DB 사용할 때 마다 생성해야 함
(고객 요청이 올 때마다 생성해서 사용)
EntityManager는 쓰레드 간에 공유해서는 안 됨
[회원 등록]
public static void main(String[] args) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("hello");
// 데이터베이스 커넥션 하나 받았다고 생각하면 편하다.
EntityManager em = emf.createEntityManager();
//code
// 트랜잭션 제어에 필요한 EntityTransaction 객체 반환
EntityTransaction ts = em.getTransaction();
// 트랜잭션 시작
ts.begin();
try {
Member member = new Member();
member.setId(1L);
member.setName("HelloA");
em.persist(member);
// 트랜잭션 종료
ts.commit()
} catch(Exception e) {
ts.rollback();
} finally {
// 반드시 수행해줘야 함
em.close();
}
emf.close();
}
EntityManager
가 내부적으로 DB 커넥션을 물고 동작하기 때문에
사용하고나면 닫아줘야 한다.EntityManagerFactory
도 닫아줘야 한다.[회원 수정]
public static void main(String[] args) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("hello");
// 데이터베이스 커넥션 하나 받았다고 생각하면 편하다.
EntityManager em = emf.createEntityManager();
//code
// 트랜잭션 제어에 필요한 EntityTransaction 객체 반환
EntityTransaction ts = em.getTransaction();
// 트랜잭션 시작
ts.begin();
try {
Member findMember = em.find(Member.class, 1L);
// 객체값 변경
findMember.setName("HelloJPA");
// 값 변경을 감지하고 자동으로 UPDATE SQL 실행
// 트랜잭션 종료
ts.commit()
} catch(Exception e) {
ts.rollback();
} finally {
// 반드시 수행해줘야 함
em.close();
}
em.close();
emf.close();
}
[회원 삭제]
public static void main(String[] args) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("hello");
// 데이터베이스 커넥션 하나 받았다고 생각하면 편하다.
EntityManager em = emf.createEntityManager();
//code
// 트랜잭션 제어에 필요한 EntityTransaction 객체 반환
EntityTransaction ts = em.getTransaction();
// 트랜잭션 시작
ts.begin();
try {
Member findMember = em.find(Member.class, 1L);
// find로 찾은 객체를 넣어주면 된다.
em.remove(findMember);
ts.commit()
} catch(Exception e) {
ts.rollback();
} finally {
// 반드시 수행해줘야 함
em.close();
}
em.close();
emf.close();
}
em.remove()
를 수행하면 된다.
</aside><aside> ❗
JPQL을 사용
해야 한다.
</aside><aside> ❗
JPQL
은 테이블 대상이 아닌 객체를 대상으로 쿼리를 한다
고 보면 된다.
그래서실제 쿼리는 SELECT 문에 필드를 나열
했지만
JPQL은 나열하지 않음
즉, MemberEntity를 선택해서 검색한 것 (즉, 엔티티 객체를 직접 조회
한 것)List<Member> selectMFromMember
= em.createQuery("SELECT m FROM Member as m", Member.class)
.getResultList();
for (Member member : selectMFromMember) {
System.out.println("member = " + member.getName());
}
<aside> ❗
애플리케이션이 필요한 데이터만 DB에서 불러오려면
결국 검색 조건이 포함된 SQL이 필요
→ 엔티티 객체를 대상으로 쿼리를 할 수 있는 JPQL 사용JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
SQL과 문법 유사
, SELECT FROM, WHERE, GROUP BY, HAVING, JOIN 지원JPQL은 엔티티 객체를 대상으로 쿼리
SQL은 데이터베이스 테이블
을 대상으로 쿼리객체를 대상으로 검색하는 객체 지향 쿼리
특정 데이터베이스 SQL에 의존 X