JPA 시작하기
Hello JPA - 프로젝트 생성
H2 데이터베이스
- 최고의 실습용 DB
- 가볍다.(1.5M)
- 웹용 쿼리툴 제공
- MySQL, Oracle 데이터베이스 시뮬레이션 기능
- 시퀀스, AUTO INCREMENT 기능 지원
Maven
- 자바 라이브러리, 빌드 관리
- 라이브러리 자동 다운로드 및 의존성 관리
- 최근에는 그래들(Gradle)이 점점 유명
persistence.xml
- JPA 설정 파일
/META-INF/persistence.xml
위치- persistence-unit name으로 이름 지정
javax.persistence
로 시작: JPA 표준 속성hibernate
로 시작: 하이버네이트 전용 속성
데이터베이스 방언 (dialect)
- JPA는 특정 데이터베이스에 종속되지 않음
- 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다름
- 가변 문자: MySQL은
VARCHAR
, Oracle은VARCHAR2
- 문자열을 자르는 함수: SQL 표준은
SUBSTRING()
, Oracle은SUBSTR()
- 페이징: MySQL은
LIMIT
, Oracle은ROWNUM
- 가변 문자: MySQL은
- 방언: SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능
- hibernate.dialect 속성에 지정
- H2 :
org.hibernate.dialect.H2Dialect
- Oracle 10g :
org.hibernate.dialect.Oracle10gDialect
- MySQL :
org.hibernate.dialect.MySQL5InnoDBDialect
- H2 :
- 하이버네이트는 40가지 이상의 데이터베이스 방언 지원
Hello JPA - 애플리케이션 개발
JPA 구동 방식
객체와 테이블을 생성하고 매핑하기
@Entity
public class Member {
@Id
private Long id;
private String name;
// Getter, Setter
}
@Entity
: JPA가 관리할 객체라는 것을 알려줌@Id
: DB의 PK와 매핑
create table Member {
id bigint not null,
name varchar(255),
primary key (id)
}
실습 - 회원 저장
회원 등록
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Member member = new Member();
member.setId(1L);
member.setName("HelloA");
em.persist(member);
tx.commit();
em.close();
emf.close();
}
}
EntityManagerFactory
는 하나만 생성해서 애플리케이션 전체에서 공유EntityManager
는 쓰레드 간에 공유하지 않는다 (사용하고 버려야 한다).- JPA의 모든 데이터 변경은 트랜잭션 안에서 실행해야 한다. (
tx.begin()
-tx.commit()
)
회원 단건 조회
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
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) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
트랜잭션에서 문제가 생겼을 경우 트랜잭션을 ROLLBACK 해야 한다. 또한, 문제 여부와 상관없이 EntityManager
를 닫아서 DB Connection을 종료해야 한다.
회원 삭제
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Member findMember = em.find(Member.class, 1L);
em.remove(findMember);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
회원 수정
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Member findMember = em.find(Member.class, 1L);
findMember.setName("HelloJPA");
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
자바 객체를 수정하듯이 DB를 수정할 수 있다. JPA를 통하여 객체를 가져올 경우 JPA에서 객체를 관리하여 트랜잭션 시점에 객체의 변경 여부를 감지하여 객체가 변경되었을 경우 UPDATE 쿼리를 생성한다.
회원 다수 조회
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
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());
}
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
JPQL을 사용하여 다수의 객체를 조회하고 있다.
JPQL 소개
가장 단순한 조회 방법은 EntityManager.find()
객체 그래프 탐색 방법은 a.getB().getC()
만약, 나이가 18살 이상인 회원을 모두 검색하고 싶다면?
- JPA를 사용하면 엔티티 객체를 중심으로 개발
- 문제는 검색 쿼리
- JPA는 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
- 그러나 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
- 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요
- JPQL
- JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
- SQL과 문법 유사, SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원
- JPQL은 엔티티 객체를 대상으로 쿼리
- SQL은 데이터베이스 테이블을 대상으로 쿼리
- 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
- SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않음
- JPQL을 한마디로 정의하면 객체 지향 SQL