[자바 ORM 표준 JPA 프로그래밍] 2. JPA 시작
개발서적/자바 ORM 표준 JPA

[자바 ORM 표준 JPA 프로그래밍] 2. JPA 시작

Reference. 자바 ORM 표준 JPA 프로그래밍

책 목차 및 이전 글

예제 프로젝트 구조
src / main
      -java
            -jpabook/start
                  -JpaMain.java
                  -Member.java

      -resources
            -META-INF
                  -persistence.xml
pom.xml

2.4 객체 매핑 시작

Member.java
@Entity
@Table(name = "MEMBER")
public class Member{
	@Id
	@Column(name = "ID")
	private String id;
	
	@Column(name = "NAME")
	private String username;

	//매핑 정보가 없는 필드
	private Integer age;
	
	...
}
  • @Entity
    - 테이블과 객체 매핑, @Entity가 사용된 클래스를 엔티티 클래스라고 함
  • @Table
    - 엔티티 클래스에 매핑할 테이블을 지정
    - name속성을 통해 Member 엔티티와 MEMBER 테이블을 매핑(생략하면 엔티티 이름을 사용)
  • @Id
    - 엔티티 클래스의 필드를 테이블의 기본키에 매핑 (식별자 필드)
  • @Column
    - 필드를 컬럼에 매핑
    - name 속성을 통해 Member 객체의 username 필드를 MEMBER 테이블의 NAME 컬럼에 매핑

2.5 persistence.xml 설정

persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="hello">
        <class>practice.docs.spring.domain.Member</class>
        <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>
  • JPA 표준 속성
    - javax.persistence.jdbc.driver: JDBC 드라이버
    - javax.persistence.jdbc.user: 데이터베이스 접속 아이디
    - javax.persistence.jdbc.password: 데이터베이스 접속 비밀번호
    - javax.persistence.jdbc.url: 데이터베이스 접속 URL
  • 하이버네이트 속성
    - hibernate.dialect: 데이터베이스 방언(Dialect) 설정

2.5.1 데이터베이스 방언

JPA는 특정 데이터베이스에 종속적이지 않는 기술, 다른 데이터베이스로 손쉽게 교체 가능

그러나, 데이터베이스가 제공하는 SQL 문법과 함수가 아래와 같이 조금씩 다르다.
  • 데이터 타입: MySQL - VARCHAR, 오라클 - VARCHAR2
  • 다른 함수명: SQL 표준 - SUBSTRING(), 오라클 - SUBSTR()
  • 페이징 처리: MySQL - LIMIT, 오라클 - ROWNUM

 

그런 것들을 해결하기 위해 JPA는 다양한 방언 클래스를 제공

방언: JPA에서는 SQL 표준을 지키지 않거나, 특정 데이터베이스만의 고유 기능을 일컬음

2.6 애플리케이션 개발

JpaMain.java
public class JpaMain{

    public static void main(String[] args) {
				//[엔티티 매니저 팩토리] 생성
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook");
				//[엔티티 매니저] 생성
        EntityManager em= emf.createEntityManager();
				//[트랜잭션] - 획득
        EntityTransaction tx= entityManager.getTransaction();

        try {

		tx.begin(); //[트랜잭션] - 시작
		login(em);  //로직 실행
		tx.commit(); //[트랜잭션] - 커밋
						
        } catch (RuntimeException e) {
            tx.rollback(); //[트랜잭션] - 롤백
        } finally {
            em.close(); //[엔티티 매니저] - 종료
        }
        emf.close(); //[엔티티 매니저 팩토리] - 종료
    }

		private static void logic(EntityManager em) {...}
}
  1. 엔티티 매니저 팩토리 생성
    - persistence.xml 설정을 통해 엔티티 매니저 팩토리를 생성
    - 엔티티 매니저 팩토리는 애플리케이션 전체에서 한번만 생성 후 공유 (생성 비용이 크기 때문)
//persistence.xml에 persistence-unit을 찾음(jpabook)
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook");
  1. 엔티티 매니저 생성
    - 엔티티 매니저 팩토리에서 엔티티 매니저를 생성, JPA 기능 대부분을 매니저가 제공
    - 엔티티 매니저를 통해 등록/수정/삭제/조회 가능 (개발자는 가상의 데이터베이스로 생각 가능)
    - 데이터베이스 커넥션과 밀접한 관계를 가지므로, 스레드간의 공유와 재사용은 불가
  1. 트랜잭션 생성
    - JPA를 사용하려면 트랜잭션 안에서 데이터 변경이 필요 (없는 경우 예외 발생)
    - 엔티티 매니저에서 트랜잭션 API를 받아서 처리 (트랜잭션은 commit, rollback 제공)
EntityTransaction tx= entityManager.getTransaction();
try {
	tx.begin(); //[트랜잭션] - 시작
	login(em);  //로직 실행
	tx.commit(); //[트랜잭션] - 커밋
}
  1. 비즈니스 로직 처리
public static void logic(ENtityManager em){
    String id = "id1";
    Member member = new Member();
    member.setId(id); 
    ...

    //등록
    em.persist(member);

    //수정 (em.update() 메소드는 없음)
    member.setAge(20);

    //한건 조회
    Member findMember = em.find(Member.class, id);

    //목록 조회
    List<Member> members = em.createQuery("select m from Member m", Member.class)
    			.getResultList();

    //삭제
    em.remove(member);
}
  1. 종료 - 사용이 끝난 엔티티 매니저, 엔티티 매니저 팩토리는 종료가 필요
em.close(); //[엔티티 매니저] - 종료
emf.close(); //[엔티티 매니저 팩토리] - 종료

 

  • JPQL 애플리케이션이 필요한 데이터만 DB에서 불러오려면 검색 조건이 포함된 SQL 필요
    JPQL(Java Persistence Query Language)로 문제 해결
TypedQuery<Member> query = em.createQuery("select m from Member m", Member.class);
List<Member> members = query.getResultList();

<실행결과>
SELECT M.ID, M.NAME M.AGE FROM MEMBER M
  • JPQL 특징
    - JPQL엔티티 객체를 대상으로 쿼리 (클래스와 필드를 대상으로 쿼리)
    - SQL데이터베이스 테이블을 대상으로 쿼리
    - from Member는 회원 엔티티 객체를 칭함, MEMBER 테이블이 아님
    - JPQL은 데이터베이스 테이블을 알지 못함