Super Kawaii Cute Cat Kaoani [자바 ORM 표준 JPA 프로그래밍 - 기본편] 2. JPA 시작하기

[자바 ORM 표준 JPA 프로그래밍 - 기본편] 2. JPA 시작하기

2024. 1. 23. 11:41
728x90
SMALL
반응형

📌 프로젝트 생성

✔ 새프로젝트 생성 -> Maven 선택

  • groupId : jpa-basic
  • artifactId : ex1-hello-jpa
  • version : 1.0.0

pom.xml에 의존성 추가

    <dependencies>
        <!-- JPA 하이버네이트 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.3.20.Final</version>
        </dependency>
        <!-- H2 데이터베이스 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.2.224</version>
        </dependency>
    </dependencies>
  • h2 version : 2.2.224
  • hibernate version : 5.3.20.Final
  • hibernate-entitymanager -> hibernate-core로 변경
  • javax.persistence:javax.persistence-api:2.2에 모든 jpa 인터페이스들이 들어있음

➡ 꼭 reload 해주기!

 

📌 JPA 설정하기 - persistence.xml

  • JPA 설정 파일
  • /META-INF/persistence.xml
    • main/.../resources 아래에 META-INF 디렉토리 생성
    • 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>
  • persistence-unit name으로 이름 지정
  • javax.persistence로 시작 : JPA 표준 속성
  • hibernate로 시작 : 하이버네이트 전용 속성

 

데이터베이스 방언

  • JPA는 특정 데이터베이스에 종속 X (MySQL을 쓰다가 Oracle로 바꾸기 쉬움)
  • 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다름
    • 가변 문자 : MySQL은 VARCHAR, Oracle은 VARCHAR2
    • 문자열을 자르는 함수 : SQL 표준은 SUBSTRING(), Oracle은 SUBSTR()
    • 페이징 : MySQL은 LIMIT, Oracle은 ROWNUM
  • 방언 : SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능
  • hibernate.dialect 속성에 지정
    • H2 : org.hibernate.dialect.H2Dialect
    • Oracle 10g : org.hibernate.dialect.Oracle10gDialect
    • MySQL : org.hibernate.dialect.MySQL57DBDialect
  • 하이버네이트는 40가지 이상의 데이터베이스 방언 지원

 

 

 

 

 

📌 HelloJPA 개발

  • Persistence에서 시작해서 설정 정보를 조회하고 EntityManagerFactory를 생성
  • 필요할 때마다 EntityManager를 만듦

 

JpaMain.class

🔶 main/hellojpa/JpaMain 

package hellojpa;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
    }
}

🔶 createEntityManagerFactory() 안에 앞에 설정파일에서 정한 persistenceUnitName을 적어줘야 함 (xml)

➡ 실행했을 때 빨간 글씨로 ~~ 에러없이 뜨면 성공!

 

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager entityManager = emf.createEntityManager();

        entityManager.close();

        emf.close();
    }
}
  •  잘 꺼지는지 확인

 

 

테이블 생성

  • h2.sh를 실행하고 들어가서 Member 테이블을 생성할 것임
create table Member (

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

 

클래스 생성

  • 위에서 만든 테이블과 매핑할 객체 생성
package hellojpa;

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

@Entity

public class Member {

    @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;
    }
}

🔶 @Entity를 꼭 넣어야 JPA가 인식
🔶 @Id (javax.persistence 사용)
🔶 필요한 Getter, Setter 생성

 

Member가 잘 만들어졌는지 Test

🔶 main/hellojpa/JpaMain.class

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();


        Member member = new Member();
        member.setId(2L);
        member.setName("HelloB");
        em.persist(member);

        tx.commit();

        em.close();

        emf.close();
    }
}

🔶 EntityManagerFactory는 애플리케이션 로딩 시점에 딱 한번 만들어야 함

  • 어떤 상황이 생길 때마다 EntityManager를 만들어서 사용

🔶 member를 하나 만들어서 em.persist()를 이용해 저장해줌

  • member.setId(), member.setName()을 이용해서 값 넣어줘야 함

❗JPA에서는 트랜잭션이라는 단위가 매우 중요함
모든 데이터를 변경하는 등의 작업은 트랜잭션 안에서 해야함

 

🔶 em.getTransaction();을 이용해서 호출해서 트랜잭션 생성

  • tx.begin()으로 시작
  • tx.commit()하면 쿼리가 날라감

 

  • 설정에서 hibernate.show_sql을 true로 해놨기 때문에 쿼리가 보임
  • hibernate.use_sql_comments true로 해놨기 때문에 설명도 해줌

 

 

DB에 저장되었는지 확인!

  • h2에 가서 SELECT * FROM MEMBER; 실행해보면 저장된걸 확인할 수 있음

Table(name="USER")

 

  • USER 테이블에 매핑
@Column(name = "username`)
  • db에서 username과 매핑됨

 

트랜잭션에서 롤백

        try {
            Member member = new Member();
            member.setId(2L);
            member.setName("HelloB");
            em.persist(member);

            tx.commit();

        }catch (Exception e){
            tx.rollback();
        }
        finally {
            em.close();

        }
  • 정상적일땐 커밋을 하고 문제가 생기면 rollback

 

회원 수정하기

        try {
            Member findMember = em.find(Member.class, 1L);
            findMember.setName("UpdateMemberName");
            tx.commit();

        }catch (Exception e){
            tx.rollback();
        }
        finally {
            em.close();

        }

🔶 em.find(Member.class, 1L);

  • entityManager에 있는 find 사용
  • 찾고자하는 Member Id값(Pk) 입력

🔶 수정한 후에 em.persist(findMember)로 저장하지 않아도 알아서 저장됨

  • 수정이 됐는지 감지하고 바꼈으면 update 쿼리를 날리고 commit

 

회원 삭제

        try {
            Member findMember = em.find(Member.class, 1L);
            em.remove(findMember);
            tx.commit();

        }catch (Exception e){
            tx.rollback();
        }
        finally {
            em.close();

        }

주의❗

  • 엔티티 매니저 팩토리는 하나만 생성해서 애플리케이션 전체에서 공유
  • 엔티티 매니저는 쓰레드간에 공유 X (사용하고 버려야 함)
  • JPA의 모든 데이터 변경은 트랜잭션 안에서 실행

 

 

 

 

 

📌 JPQL 소개

  • 가장 단순한 조회 방법
    • EntityManager.find()
    • 객체 그래프 탐색(a.getB().getC())
  • 나이가 18살 이상인 회원을 모두 검색하고 싶다면?

나이가 18살 이상인 회원을 모두 검색하고 싶다면?

➡ JPQL로 전체 회원 검색

  • JPQL로 ID가 2 이상인 회원만 검색
  • JPQL로 이름이 같은 회원만 검색
  • JPQL에 대해 자세한 내용은 객체지향 쿼리에서 학습

 

List<Member> result = em.createQuery("SELECT m from Member as m", Member.class).getResultList();

for(Member member:result){
    System.out.println("member.getName() = " + member.getName());
}
  • 쿼리가 sql과 약간 다름!
List<Member> result = em.createQuery("SELECT m from Member as m", Member.class)
    .setFirstResult(1)
    .setMaxResults(10)
    .getResultList();
  • 1~10번 가져오라는 뜻
  • JPA를 사용하면 엔티티 객체를 중심으로 개발
  • ❗ 문제는 검색 쿼리
    • 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
    • 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
  • 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요
  • JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
    • SQL과 문법 유사, SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원
    • JPQL은 엔티티 객체를 대상으로 쿼리
    • SQL은 데이터베이스 테이블을 대상으로 쿼리
    • 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
    • SQL을 추상화해서 특정 데이터베이스 SQL에 의존 X
    • JPQL을 한마디로 정의하면 객체 지향 SQL

 

 

 

 

 

<자바 ORM 표준 JPA 프로그래밍 - 기본편_김영한>을 수강하고 작성한 글입니다

 

 

 

 

 

 


PREV

 

[자바 ORM 표준 JPA 프로그래밍 - 기본편]1. JPA 소개

❗ 지금은 객체를 관계형 DB에 관리하는 시대 ➡ SQL 사용 📌 SQL이란? Structured Query Language 데이터베이스 시스템에서 자료를 처리하는 용도로 사용되는 구조적 데이터 질의 언어(에스큐엘, 시퀄이

nyeroni.tistory.com

NEXT

 

[자바 ORM 표준 JPA 프로그래밍 - 기본편] 3. 영속성 관리 - 내부 동작 방식

❗ JPA에서 가장 중요한 2가지 객체와 관계형 데이터 베이스 매핑하기 (ORM, Object Relational Mapping) 영속성 컨텍스트 📌 영속성 컨텍스트 ⚡ 영속성 컨텍스트란 JPA를 이해하는데 가장 중요한 용어 "

nyeroni.tistory.com

 

728x90
LIST

BELATED ARTICLES

more