JPA 뿌셔버리기 - 2부
자 여러분 2부입니다.
열심히 정리하고 있습니다.
실 사용까지 가려면 아직 멀었습니다. 힘내야합니다.ㅋㅋㅋ
이제는 예제 직접 한 걸 정리하겠습니다.
환경
DB
h2
- h2
- 실습하기 아주 좋은 DB
- 엄청 가볍고
- 웹용 Query Tool 제공하고
- MySQL, Oracle DB 시뮬레이션 가능하고
- 만능임
Maven
- Java Library, Build Management
- Library 자동 다운로드 및 Dependency Management
- 최근에는 Gradle 이 점점 쓴다고함
ℹ️ Gradle
- 솔직히 Maven 보다 간단하고 쓰기 좋은 듯
- 새로 만드는 프로젝트는 무조건 Gradle 로 하고 있음
Project 구성
Java
- Java 8 이상 사용 권장
- 나는 Amazon Correcto openJDK 11 사용
Library - pom.xml
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.5.5.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
</dependencies>
실습해서 뿌셔버리기
JPA 설정
persistence.xml
- JPA 설정 파일
- 위치
/META-INF/persistence.xml
- persistence-unit name 으로 이름 지정
- javax.persistence 로 시작 : JPA 표준 속성
- hibernate 로 시작 :
Hibernate
전용 속성
<?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.jdbc.batch_size" value="10"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
Database 방언(Dialect)
JPA
는 특정 Database 종속 XOracle
쓰다가MySql
로 DB 가 변경되었을 경우,JPA
설정 중 Database 방언만 바꿔주면 바로 사용 가능- 단, DB 에 사용중이던 Custom Function을
JPA
에 등록해서 사용중인 경우 쫌..수정이 필요할듯
- 단, DB 에 사용중이던 Custom Function을
- 각 Database 가 제공하는 SQL 문법과 함수는 조금씩 다름
- 가변문자
Oracle
: VARCHAR2MySQL
: VARCHAR
- 문자열 자르는 함수
ANSI SQL
: SUBSTRING()ORACLE
: SUBSTR()
- Pagination
Oralce
: ROWNUMMySQL
: LIMIT
- 가변문자
Dialect
:ANSI SQL
을 지키지 않는 특정 Database 만의 고유한 기능
ℹ️ ANSI SQL
-
DBMS(Oracle, My-SQL, DB2 등등)들에서 각기 다른 SQL를 사용하므로, 미국 표준 협회(American National Standards Institute)에서 이를 표준화하여 표준 SQL문을 정립 시켜 놓은 것
-
특징
- 표준 SQL문이기 때문에 DBMS의 종류에 제약을 받지 않음
- 테이블간의 Join 관계가 FROM 에서 명시되기 때문에 WHERE 문에서 조건만 확인하면 된다.
Database Dialect 설정
-
hibernate.dialect 속성에 지정
H2
: org.hibernate.dialect.H2DialectOracle
: org.hibernate.dialect.Oracle10gDialectMySQL
: org.hibernate.dialect.MySQL5InnoDBDialect
-
Hibernate
는 40가지 이상의 Database Dialect 지원
JPA 구동 방식
객체와 테이블을 생성하고 맵핑하기
@Entity
: JPA 가 관리할 객체@ID
: Database Table 의 기본키(PK) 와 맵핑
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
}
실습해보자
⚠️ 주의사항
EntityManagerFactory
는 하나만 생성해서 Application 전체에서 공유EntityManager
는 Thread 간 공유 X (사용하고 버려야 한다.)JPA
의 모든 데이터 변경은Transaction
안에서 실행
EntityManagerFactory
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
- DB 당 1개만 생성됨
- Container 가 생성 시점에 생성됨
EntityManager
EntityManager em = emf.createEntityManager();
Transaction
단위 또는 작업 단위마다EntityManager
를 생성하여 사용해야 한다.
EntityTransaction
EntityTransaction tx = em.getTransaction();
JPA
의 모든 변경사항은Transaction
안에서 실행되어야 한다.
기본 코드
// EntityManagerFactory 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
// EntityManagerFactory 에서 EntityManager 생성
EntityManager em = emf.createEntityManager();
// EntityManager 에서 Transaction 가져오기
EntityTransaction tx = em.getTransaction();
tx.begin(); // Transaction 시작
try {
Member member = new Member();
member.setUsername("memberA");
em.persist(member);
} catch(Exception e){
tx.rollback(); // rollback
} finally {
em.close(); // 사용 후 반드시 닫아주어야 한다.
}
emf.close(); // 사용 후 반드시 닫아주어야 한다.
JPQL
- 가장 단순한 조회 방법
em.find(Member.class, 1);
ℹ️ 그렇다면, 나이가 18살 이상인 회원을 모두 검색하고 싶다면?
- 가장 단순한 조회 방법은 PK 로 밖에 검색이 되지 않아 불가능
- 이떄, JPQL 사용하여 PK 가 아닌 조건으로 조회하거나, 더 복잡한 조건으로 조회가 가능
실습
JPQL 사용하기
- 전체 회원 검색
List<Member> resultList = em.createQuery("select m from Member", Member.class).getResultList();
- ID 가 2 이상인 회원 검색
List<Member> resultList = em.createQuery("select m from Member where id >= 2", Member.class).getResultList();
JPQL 이 등장한 배경
JPA
를 사용하면Entity
객체를 중심으로 개발- 문제는 검색 쿼리
- 검색할떄도 테이블이 아닌
Entity
객체를 대상으로 검색 - 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
- Application 이 필요한 데이터만 DB 에서 불러오려면, 결국 검색조건이 포함된 SQL 필요
JPQL 특징
JPA
는 SQL 을 추상화한 JPQL 이라는 객체 지향 쿼리 언어 제공- SQL과 문법 유사
- SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원
- JPQL 은
Entity
객체를 대상으로 쿼리 - SQL 은 Database Table을 대상으로 쿼리
- 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
- SQL 을 추상화해서 특정 Database SQL 의존 X
- JPQL 을 한마디로 정의하면 객체 지향 SQL
👍 자세한 JPQL 내용은 나중에 다루겠음
댓글남기기