JPA 시작하기

·2021년 5월 4일
0

Hello JPA 프로젝트를 생성한 후 실제 JPA를 사용해보자

환경 설정

1. DB 설정

H2를 이용해서 MEMBER 테이블을 생성한다


🙄H2가 뭘까

  • 자바 기반의 DB로 가볍고 인메모리로 사용이 가능하다.웹용 쿼리 툴이 있다. (공부, test용 db로 많이 사용)

(1) DB생성

  • H2 사이트 에서 H2 다운 받기
  • JDBC URL 을 jdbc:h2:~/test 로 변경해서 연결
    • 맨 처음엔 파일모드로 설정해서 직접 db파일을 생성해줘야한다
    • 당연히 드라이버 클래스는 org.h2.Driver
    • 한번 접속한 후엔 파일이 생성되어있기 때문에 jdbc:h2:tcp://localhost/~/test 로 네트워크 모드로 접속하면 된다.

(2) 테이블 생성

  • 아래의 쿼리문을 작성해 MEMBER 테이블을 만든다
create table MEMBER
(
    ID   BIGINT not null
        primary key,
    NAME VARCHAR(255)
);
  • MEMBER 테이블 생성 완료

2. 프로젝트 생성

메이븐 프로젝트를 생성한다

(1) 프로젝트 생성

  • 자바 8 이상(8 권장)
  • 메이븐 설정
    • groupId: jpa-basic
    • artifactId: ex1-hello-jpa
    • version: 1.0.0
  • pom.xml에서 프로젝트 정보를 확인가능하다
    ...
    <groupId>jpa-basic</groupId>
    <artifactId>ex1-hello-jpa</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    ...

(2) 라이브러리 추가

  • H2 데이터베이스와 JPA 하이버네이트 디펜던시를 추가한다
    <dependencies>

        <!-- JPA 하이버네이트 -->

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.3.10.Final</version>
        </dependency>

        <!-- H2 데이터베이스 -->

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.199</version>
        </dependency>
    </dependencies>

3. JPA 설정

JPA를 설정해보자

(1) 설정

  • resources에 META-INF 디렉토리를 생성 후 persistence.xml 을 만든다

  • persistence.xml 에 아래와 같이 입력한다

<?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.hbm2ddl.auto" value="create" />-->

        </properties>
    </persistence-unit>
</persistence>

(2) 설정 설명

🙄javax와 hibernate

설정을 보면 javax 로 시작하는 이름이 있고 hibernate 로 시작하는 이름이 있다. javax 는 JPA 표준속성이기 때문에 모든 JPA에서 사용이 가능하고 hibernate 는 JPA 중 하이버네이트에서만 제공하는 기능이기 때문에 만약 Hibernate가 아닌 다른 것으로 바꾼다면 변경해줘야 한다.

[필수속성]

  • javax.persistence.jdbc.driver
    • db 드라이버 설정, 우리는 h2를 사용하기 때문에 value에 h2를 넣었다
  • javax.persistence.jdbc.user
    • db userId를 입력한다 h2 기본값인 sa를 넣음
  • javax.persistence.jdbc.password
    • db password 입력. pw 설정을 따로 안해줬기때문에 공란으로
  • javax.persistence.jdbc.url
    • JDBC URL을 입력한다. H2 네트워크 주소 입력하면 된다
  • hibernate.dialect
    • 사용하는 DB방언(dialect)를 입력한다.

🙄방언

  • JPA는 특정 데이터베이스에 종속되지 않는다
    • 각각의 DB가 제공하는 SQL 문법과 함수는 조금씩 다르다 ( varchar, varchar2, substring, substr..)
    • 어떤 방언 (DB언어) 를 사용하는지 확인이 필요하다
    • 하이버네이트는 40가지 이상의 방언(dialect)를 지원한다
  • 프로퍼티의 value="org.hibernate.dialect.H2Dialect 를 들어가보면 아래와 같이 H2의 방언들을 설정해놓은 것을 볼 수 있다

[옵션]

  • hibernate.show_sql
    • 콘솔에 sql문을 보여준다
  • hibernate.format_sql
    • sql문을 좀 더 가독성있게 보여준다
  • hibernate.use_sql_comments
    • 주석으로 어떤 sql문을 수행시켰는지 추가적으로 보여준다

시작하기

1. 객체와 테이블 매핑

Member 클래스를 만들어 아래 구조의 Member

create table Member ( 
 id bigint not null, 
 name varchar(255), 
 
primary key (id) 
);

이렇게 객체와 연결해준다

import javax.persistence.Entity; 
import javax.persistence.Id; 

@Entity 
//@Table(name = "User")
public class Member { 
 
@Id 
//    @Column(name = "username" 
private Long id; 
 private String name; 
 //Getter, Setter … 
}
  • Entity : JPA가 관리할 객체를 의미
  • ID : DB PK와 매핑한다
  • Table(name=) : 만약 테이블 이름이 클래스명과 다르면 직접 지정해준다
  • Coulumn(name=) : 필드명이 변수명과 다르면 직접 지정해준다

2. 연결과 종료

이제 JpaMain (이름은 상관없음..) 를 만들어 연결하는 법을 확인해보자

        EntityManagerFactory enf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = enf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
     	// 로직
         tx.commit();
         em.close();
         enf.close();
  • EntityManagerFactory 는 하나만 생성해서 애플리케이션 전체에서 공유한다
  • EntityManagerFactoryhellopersistence.xml 의 umit name이다
  • EntityManager 는 고객의 요청이 올때마다 사용하고 버려야 한다. (쓰레드간의 공유는 안된다)
  • JPA의 모든 데이터 변경은 EntityTransaction 안에서 이루어져야 한다.

3. crud

생성

            Member member = new Member();
            member.setId(2L); //키 없으면 오류
            member.setName("HelloB");
            em.persist(member); //영속성 컨텍스트에 저장
  • em.persist 를 할때 영속성 컨텍스트에 저장 (아직 DB에 저장한 상태가 아님)
  • commit 을 해줘야 저장된다
  • 생성할 때 기본키가 있어야한다. 없으면 오류

삭제 / 찾기

            Member findMember = em.find(Member.class, 1L);
            em.remove(findMember);
  • find를 통해 찾은 후 remove를 통해 삭제해준다

수정

            Member findMember = em.find(Member.class, 1L);
            findMember.setName("HelloJPA");
  • em.persist 로 저장할 필요가 없다.
  • find를 이용해 엔티티를 가져오면 그 엔티티는 JPA가 관리한다
  • 트랜잭션을 커밋하는순간 엔티티가 변경이 되었는지 체크를 한다
  • 변경이 감지되면 알아서 update 쿼리를 생성한다

4. 예외처리문

그냥 연결 - 로직 - 연결해지를 하면 로직부분에서 에러가 날 가능성이 있기 때문에 항상 try/catch 문을 사용해준다

	...
    
    	//연결

        EntityManagerFactory enf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = enf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        //트랜젝션을 try catch로 잡는다
        try {

            //생성
            Member member = new Member();
            member.setId(2L); //키 없으면 오류
            member.setName("HelloD");
            em.persist(member);

            tx.commit();


        }catch (Exception e) {
            //문제가 생기면 rollback
            tx.rollback();
        } finally {
            //종료
            em.close();
            enf.close();
        }

5. create Query

조건이 많을때는 JPQL을 사용한다.
JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공한다.

JPQL로 전체회원 조회해보기

            List<Member> result = em.createQuery("select m from Member as m ",Member.class)
		 .getResultList();
  • JPA는 테이블을 상대로 쿼리를 짜지 않는다. 객체를 대상으로 쿼리를 짠다
  • jpql을 보면 select m from Member as m 필드를 가져온 것이 아니라 Member, 즉 객체를 가져오라고 요청한 것을 알 수 있다
  • 실제로 수행된 쿼리문을 보면 (hibernate.show_sql 설정을 했다면 log에 나옴) 필드를 다 select 했음을 알 수 있다
    • 객체지향적으로 요청해도 JPA가 알아서 잘 SQL을 요청한다
select
  member0_.id as id1_0_,
  member0_.name as name2_0_ 
from
  Member member0_

출처 JAVA ORM 표준 JPA 프로그래밍

개인 git에 가면 전체 코드를 확인 할 수 있습니다

profile
💻📝🤯

0개의 댓글