<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jpabook</groupId>
<artifactId>jpashop</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- JPA 하이버네이트 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.13.Final</version>
</dependency>
<!-- H2 데이터베이스 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
</project>
✓ Java 11
✓ Maven
✓ groupId: jpa-basic
✓ artifactId: ex1-hello-jpa
✓ version: 1.0-SNAPSHOT
<?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/~/jpashop;MODE=MySQL"/>
<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.jdbc.batch_size" value="10"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
✓ 경로 : resources/META-INF/persistence.xml
create table Member
(
id bigint not null,
name varchar(255),
primary key (id)
);
public class JpaMain {
public static void main(String[] args) {
// EntityManagerFactory는 애플리케이션 로딩 시점에 하나만 만들어야 한다.
// persistence.xml에서 설정했던 'persistence-unit name' 값을 넘긴다.
// 예제에서는 "hello"로 설정했다.
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello");
// EntityManager는 트랜잭션마다 만들어줘야 한다.
EntityManager entityManager = entityManagerFactory.createEntityManager();
// JPA의 모든 작업은 트랜잭션 내에서 해야 적용된다.
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
try {
Member member = new Member();
member.setId(1L);
member.setName("helloA");
// 저장
entityManager.persist(member);
// commit 시 Query가 DataBase로 전달된다.
tx.commit();
} catch (Exception e) {
// 실패 시 롤백
tx.rollback();
} finally {
// EntityManager 꼭 닫기
entityManager.close();
}
// 전체 애플리케이션이 끝나면 팩토리까지 닫는다.
entityManagerFactory.close();
}
}
@Entity
public class Member {
// PK를 지정
@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;
}
}
JpaMain.java 실행 시 아래와 같은 쿼리가 작성된다.
Hibernate:
insert into Member(name, id) values(?, ?)
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
try {
// 1차 캐시에 존재하지 않을 경우 DB에서 조회
Member findMember = entityManager.find(Member.class, 1L);
System.out.println("id: " + findMember.getId());
System.out.println("name: " + findMember.getName());
findMember.setName("JPA");
// 수정한 객체를 따로 저장하지 않아도, commit시점에 업데이트 쿼리를 생성한다.
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
entityManager.close();
}
entityManagerFactory.close();
}
}
JpaMain.java 실행 시 아래와 같은 쿼리가 작성된다.
update Member set name=? where id=?
EntityManager.find()
a.getB().getC()
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
try {
// JPA는 DB가 아닌 객체를 대상으로 Query를 작성한다.
// 객체를 대상으로 쿼리를 짜기 때문에
// 여기서 Member는 테이블이 아니라 객체를 가리킨다.
List<Member> result = entityManager
.createQuery("select m from Member as m", Member.class)
// 페이지네이션을 할 수도 있다. 아래는 1번부터 10개 가져온다.
.setFirstResult(1)
.setMaxResults(10)
.getResultList();
for (Member member : result) {
System.out.println("name: " + member.getName());
}
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
entityManager.close();
}
entityManagerFactory.close();
}
}
JPA를 사용하면 Entity 객체를 중심으로 개발한다.
검색 또한 테이블이 아닌 Entity 객체를 대상으로 한다.
모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능하다.
필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요하다.
-> 이때 객체를 대상으로 검색할 수 있게 하는 기술이 JPQL이다.
참고 :
김영한. 『자바 ORM 표준 JPA 프로그래밍』. 에이콘, 2015.