Hello JPA 프로젝트를 생성한 후 실제 JPA를 사용해보자
H2를 이용해서 MEMBER 테이블을 생성한다
jdbc:h2:~/test
로 변경해서 연결org.h2.Driver
jdbc:h2:tcp://localhost/~/test
로 네트워크 모드로 접속하면 된다.create table MEMBER
(
ID BIGINT not null
primary key,
NAME VARCHAR(255)
);
메이븐 프로젝트를 생성한다
...
<groupId>jpa-basic</groupId>
<artifactId>ex1-hello-jpa</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
...
<dependencies>
<!-- JPA 하이버네이트 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.3.10.Final</version>
</dependency>
<!-- H2 데이터베이스 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
</dependencies>
JPA를 설정해보자
resources에 META-INF
디렉토리를 생성 후 persistence.xml
을 만든다
persistence.xml
에 아래와 같이 입력한다
<?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="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- 옵션 -->
<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" />-->
</properties>
</persistence-unit>
</persistence>
설정을 보면 javax
로 시작하는 이름이 있고 hibernate
로 시작하는 이름이 있다. javax
는 JPA 표준속성이기 때문에 모든 JPA에서 사용이 가능하고 hibernate
는 JPA 중 하이버네이트에서만 제공하는 기능이기 때문에 만약 Hibernate가 아닌 다른 것으로 바꾼다면 변경해줘야 한다.
javax.persistence.jdbc.driver
javax.persistence.jdbc.user
javax.persistence.jdbc.password
javax.persistence.jdbc.url
hibernate.dialect
value="org.hibernate.dialect.H2Dialect
를 들어가보면 아래와 같이 H2의 방언들을 설정해놓은 것을 볼 수 있다hibernate.show_sql
hibernate.format_sql
hibernate.use_sql_comments
Member 클래스를 만들어 아래 구조의 Member
를
create table Member (
id bigint not null,
name varchar(255),
primary key (id)
);
이렇게 객체와 연결해준다
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
//@Table(name = "User")
public class Member {
@Id
// @Column(name = "username"
private Long id;
private String name;
//Getter, Setter …
}
Entity
: JPA가 관리할 객체를 의미ID
: DB PK와 매핑한다Table(name=)
: 만약 테이블 이름이 클래스명과 다르면 직접 지정해준다Coulumn(name=)
: 필드명이 변수명과 다르면 직접 지정해준다이제 JpaMain
(이름은 상관없음..) 를 만들어 연결하는 법을 확인해보자
EntityManagerFactory enf = Persistence.createEntityManagerFactory("hello");
EntityManager em = enf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
// 로직
tx.commit();
em.close();
enf.close();
EntityManagerFactory
는 하나만 생성해서 애플리케이션 전체에서 공유한다EntityManagerFactory
의 hello
는 persistence.xml
의 umit name이다EntityManager
는 고객의 요청이 올때마다 사용하고 버려야 한다. (쓰레드간의 공유는 안된다)EntityTransaction
안에서 이루어져야 한다. Member member = new Member();
member.setId(2L); //키 없으면 오류
member.setName("HelloB");
em.persist(member); //영속성 컨텍스트에 저장
em.persist
를 할때 영속성 컨텍스트에 저장 (아직 DB에 저장한 상태가 아님)commit
을 해줘야 저장된다 Member findMember = em.find(Member.class, 1L);
em.remove(findMember);
find
를 통해 찾은 후 remove
를 통해 삭제해준다 Member findMember = em.find(Member.class, 1L);
findMember.setName("HelloJPA");
em.persist
로 저장할 필요가 없다.find
를 이용해 엔티티를 가져오면 그 엔티티는 JPA가 관리한다그냥 연결 - 로직 - 연결해지를 하면 로직부분에서 에러가 날 가능성이 있기 때문에 항상 try/catch
문을 사용해준다
...
//연결
EntityManagerFactory enf = Persistence.createEntityManagerFactory("hello");
EntityManager em = enf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
//트랜젝션을 try catch로 잡는다
try {
//생성
Member member = new Member();
member.setId(2L); //키 없으면 오류
member.setName("HelloD");
em.persist(member);
tx.commit();
}catch (Exception e) {
//문제가 생기면 rollback
tx.rollback();
} finally {
//종료
em.close();
enf.close();
}
조건이 많을때는 JPQL을 사용한다.
JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공한다.
List<Member> result = em.createQuery("select m from Member as m ",Member.class)
.getResultList();
select m from Member as m
필드를 가져온 것이 아니라 Member, 즉 객체를 가져오라고 요청한 것을 알 수 있다hibernate.show_sql
설정을 했다면 log에 나옴) 필드를 다 select 했음을 알 수 있다select
member0_.id as id1_0_,
member0_.name as name2_0_
from
Member member0_
개인 git에 가면 전체 코드를 확인 할 수 있습니다