<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