프로젝트 불러오기
책 저자는 이클립스를 사용했지만, 나는 인텔리제이를 사용했다. 프로젝트는 메이븐으로 불러오면 된다. (메이븐은 미리 설치해야 한다. 예전에 깐 이력이 있어서 따로 적지는 않았다.)
H2 데이터 베이스 설치
•
My sql 이 있다면 그걸 사용해도 되지만, 책에서 H2 를 사용했기 때문에 H2 를 사용하였다. (어차피 인텔리제이로 연결할 거긴 하지만,,,)
•
H2 를 실행하기 위해서는 압축을 푼 지점으로 가서 bin 폴더까지 가야한다. (윈도우기준) 그리고 h2.bat 을 입력하면 자동으로 실행이된다.
◦
내 H2 위치 : C:\Program Files (x86)\H2\bin
•
포트번호나 url 의 경우 책과 같이 했다.
•
인텔리제이로 연결할 때 로그인 화면에 나오는 jdbc url 을 url 에 복붙했다.
◦
포트 번호 : 8082
◦
ID : sa
◦
테스트 연결 후 OK 표시가 났다면 MEMBER 테이블이 나타날 것이다
pom.xml 설정
메이븐은 라이브러리를 관리해주는 도구라고 할 수 있다. pom.xml 에 사용할 라이브러리를 적어주면 라이브러리를 자동으로 내려받아서 관리해준다.
다음과 같이 dependency 를 넣어주면 된다.
<dependencies>
<!-- JPA, 하이버네이트 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.10.Final</version>
</dependency>
<!-- H2 데이터 베이스 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.187</version>
</dependency>
</dependencies>
XML
복사
객체매핑
JPA 를 사용하려면 가장 먼저 클래스와 테이블을 매핑해야 한다.
매핑 정보를 표시하는 어노테이션
JPA 어노테이션의 패키지는 javax.persistence 이다.
@Annotation | 설명 |
@Entity | 이 클래스를 테이블과 매핑한다고 JPA 에게 알려준다. |
@Table | 엔티티 클래스에 매핑할 테이블 정보를 알려준다. 이 어노테이션을 생략하면 클래스 이름을 테이블 이름으로 매핑한다. |
@Id | 엔티티 클래스의 필드를 테이블의 기본 키에 매핑한다. 이 어노테이션이 사용된 필드를 식별자 필드라 한다. |
@Column | 필드를 컬럼에 매핑한다. |
매핑 정보가 없는 필드 | 매핑 어노테이션을 생략하면 필드명을 사용해서 컬럼명으로 매핑한다. |
persistence.xml 설정
JPA 는 persistence.xml 을 사용해서 필요한 설정 정보를 관리한다. 이 설정 파일이 META-INF/persistence.xml 클래스 패스 경로에 있으면 별도의 설정 없이 JPA 가 인식할 수 있다.
[persistence.xml 설정]
<properties>
<!-- 필수 속성 -->
<!-- JPA 속성 -->
<!-- JDBC 드라이버 -->
<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=""/>
<!-- 데이터 베이스 접속 url -->
<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.id.new_generator_mappings" value="true"/>
</properties>
XML
복사
애플리케이션 개발
코드는 크게 3 부분으로 나뉘어 있다.
•
엔티티 매니저 설정
•
트랜젝션 관리
•
비즈니스 로직
엔티티 매니저 설정
•
엔티티 매니저 팩토리에서 엔티티 매니저를 생성한다.
엔티티 매니저 팩토리
•
persistence.xml 의 설정 정보를 사용하여 생성된다.
•
persistence.xml 의 설정 정보를 읽어서 JPA 를 동작시키기 위한 객체를 만들고 JPA 구현체에 따라서는 데이터베이스 커넥션 풀도 생성하므로 엔티티 팩토리를 생성하는 비용은 크다.
•
엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한번만 생성하고 공유해서 사용해야 한다.
•
엔티티 매니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회 할 수 있다.
•
엔티티 매니저는 내부에 데이터소스를 유지하면서 데이터베이스와 통신한다.
•
엔티티 매니저는 스레드간에 공유하거나 재사용하면 안된다.
•
사용이 끝난 엔티티 매니저는 반드시 종료해야 한다. (엔티티 매니저 팩토리도)
트랜잭션 관리
•
JPA 를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야 한다.
•
트랜잭션을 시작하려면 엔티티 매니저에서 트랜잭션 API 를 받아야 한다.
API
•
Application Programming Interface(애플리케이션 프로그램 인터페이스)의 줄임말.
•
API 아키텍처는 일반적으로 클라이언트와 서버 측면에서 설명된다. 요청을 보내는 애플리케이션을 클라이언트라고 하고 응답을 보내는 애플리케이션을 서버라고 한다.
•
비즈니스 로직이 정상 동작하면 트랜잭션을 커밋하고 예외가 발생하면 롤백한다.
비즈니스 로직
•
등록, 수정, 한 건 조회, 목록 조회, 삭제
package jpabook.start;
import javax.persistence.*;
import java.util.List;
public class JpaMain {
// 애플리케이션 시작 코드
public static void main(String[] args) {
// 엔티티 매니저 팩토리 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook");
// 엔티티 매니저 생성
EntityManager em = emf.createEntityManager();
// 트랜잭션 획득
EntityTransaction tx = em.getTransaction(); // 트랜잭션 API
try {
tx.begin(); // 트랜잭션 시작
logic(em); // 비즈니스 로직 실행
tx.commit(); // 트랜잭션 커밋
} catch (Exception e) {
tx.rollback(); // 트랜잭션 롤백
} finally {
em.close(); // 엔티티 매니저 종료
}
emf.close(); // 엔티티 매니저 팩토리 종료
}
// 비즈니스 로직
private static void logic(EntityManager em) {
String id = "id1";
Member member = new Member();
member.setId(id);
member.setUsername("시은");
member.setAge(2);
// 등록
/*
[SQL]
INSERT INTO MEMBER (ID, NAME, AGE) VALUES ('id1', '지한', 2)
*/
em.persist(member);
// 수정
/*
[SQL]
UPDATE MEMBER
SET AGE=20, NAME='시은'
WHERE ID='id1'
*/
member.setAge(28);
// 한 건 조회
/*
[SQL]
SELECT * FROM MEMBER WHERE ID='id'
*/
Member findMember = em.find (Member.class, id);
System.out.println("findMember =" + findMember.getUsername() + ", age = " + findMember.getAge());
// 목록 조회 - JPQL
/*
[SQL]
SELECT M.ID, M.NAME, M.AGE FROM MEMBER M
*/
List<Member> members =
em.createQuery("SELECT m FROM Member m", Member.class)
.getResultList();
System.out.println("members.size=" + members.size());
// 삭제
/*
[SQL]
DELETE FROM MEMBER WHERE ID='id1'
*/
em.remove(member);
}
}
Java
복사
•
JPQL VS SQL
◦
JPQL
▪
엔티티 객체를 대상으로 쿼리한다.
▪
클래스와 필드를 대상으로 쿼리한다.
▪
대소문자를 구분한다.
▪
사용하려면 먼저 em.createQuery() 메소드를 실행해서 쿼리 객체를 생성한 후 쿼리 객체의 getResultList() 메소드를 호출하면 된다.
◦
SQL
▪
데이터 베이스 테이블을 대상으로 쿼리한다.
▪
대소문자를 구분하지 않고 사용한다.