JPA 시작하기

yujamint·2022년 10월 25일
0
post-thumbnail
post-custom-banner

김영한 강사님의 '자바 ORM 표준 JPA 프로그래밍 - 기본편' 강의내용을 정리하는 글이다.


프로젝트 생성

  1. H2 데이터베이스 설치
    • 매우 가볍기 때문에 실습용 DB로 매우 적절하다.
    • 웹용 쿼리툴 제공
  2. Maven 프로젝트 생성
    • 자바 라이브러리, 빌드 관리
    • 라이브러리 자동 다운로드 및 의존성 관리

pom.xml : 설정 파일

  • <dependencies> </dependencies> 안에 필요한 라이브러리 넣으면 된다.
    • org.hibernate : hibernate-entitymanager 받으면 필요한 파일 땡겨온다.

📌 라이브러리 버전 선택하는 방법
(hibernate 기준)
내가 사용하려는 스프링부트 버전의 Reference 문서에 들어가서 org.hibernate를 검색해서 쭉 내려보면 해당 스프링부트 버전에 맞는 hibernate 버전이 나온다. 이를 선택하면 된다.

JPA 설정

persistence.xml : JPA 설정 파일

  • src/resources/META-INF/persistence.xml 파일 생성
  • <persistence version = 2.2 ~ > : JPA 버전이 2.2라는 것을 의미한다.
  • <persistence-unit name="hello"> : 데이터베이스 이름은 “hello”로 할 것이다~
  • 필수 속성을 넣어줘야 된다.
    • 어떤 DB 드라이버 쓸지
    • username
    • password
    • 접근 url
    • hibernate.dialect : 어떠한 DB를 사용한다고 알리는 것. → DB 방언 지정
  • javax.persistence로 시작 : JPA 표준 속성
  • hibernate로 시작 : 하이버네이트 전용 속성

데이터베이스 방언

  • JPA는 특정 DB에 종속적이지 않다. → 어느 DB를 사용해도 무방하다.
  • 그러나 각각의 DB가 제공하는 SQL 문법과 함수는 조금씩 다르다.
  • SQL 표준을 지키지 않는 특정 데이터베이스의 문법, 고유한 기능을 방언이라고 부른다.
    • 가변 문자 : MySQL - VARCHAR / Oracle - VARCHAR2
    • 문자열 자르는 함수 : SQL 표준 - SUBSTRING() / Oracle - SUBSTR()
    • 페이징 : MySQL - LIMIT / Oracle - ROWNUM

JPA 구동 방식

  • JPA 내의 Persistence라는 클래스가 persistence.xml 설정 정보를 읽어서 EntityManagerFactory 라는 클래스를 생성한다.
    • (Java)Persistence.createEntityManagerFatory() 함수에 persistence.xml 파일에서 설정한 unit-name 인자로 주면서 생성한다.
  • EntityManagerFactory에서 필요할 때마다 EntityManager 를 생성해서 사용한다.
    • (Java)emf.createEntityManager() : EntityManager 생성
    • EntityManager를 Java의 Collection과 같이 생각해도 된다.
    • 고객의 요청이 올 때마다 EntityManager를 생성했다가 다 쓴 뒤엔 닫아준다.
      • 쓰레드간에 공유하면 절대 안 된다.
  • EntityManager 사용이 끝나면, 꼭 닫아준다.
    • EntityManager는 DB Connection을 계속 달고 있기 때문에 닫아줘야 한다.

EntityManagerFactory는 애플리케이션이 load될 때, 하나만 만들고 하나의 트랜잭션마다 EntityManager를 생성해서 처리한다.

JPA에서 데이터 변경은 무조건 트랜잭션 안에서 일어나야 된다. 그렇기 때문에, em을 받는 것으로 끝이 아니라, em.getTransaction()을 통해 트랜잭션을 얻고, 시작해준 뒤에 데이터 수정을 하면 된다. (끝난 뒤에는 트랜잭션.commit() 을 통해 변경사항 DB에 반영)

작업에 문제가 생긴다면, 트랜잭션을 commit하지 않기 위해서 try-catch문 안에 코드를 작성한다.

JPA CRUD

  • 저장 : em.persist(member)
  • 조회 : em.find(Member.class, 1L(PK))
  • 삭제 : em.remove(member)
  • 수정 : member.setName("helloJPA") → setter로 이름을 바꿔주기만 해도 DB에 적용된다.
    • JPA를 통해서 엔티티를 가져오면 JPA가 해당 엔티티를 관리한다. 그리고, 트랜잭션이 커밋되는 시점에 JPA가 관리하는 모든 엔티티에 변화가 있는지 체크한다. 만약 변화가 있다면, 트랜잭션 커밋 시점 직전에 UPDATE 쿼리를 날리고 커밋한다.

전체 회원 조회, 이름이 같은 회원 검색 등 조건이 붙은 조회는?

: 가장 단순한 조회 방법인 JPQL을 사용한다

  • JPA에서 제공하는 SQL을 추상화한 객체 지향 쿼리 언어
    • JPQL은 엔티티 객체를 대상으로 쿼리
    • SQL은 데이터베이스 테이블을 대상으로 쿼리
List<Member> result = em.createQuery("select m from Member as m", Member.class)
        .getResultList();

일반 쿼리문과는 다르다.

  • JPA에서는 코드를 짤 때 절대 테이블을 대상으로 쿼리를 작성하지 않는다. Member 객체(엔티티 객체)를 중심으로 쿼리를 작성한다.
  • pagination 가능하다.
    • .setFirstResult()
    • .setMaxResult()

검색을 할 때, 테이블이 아닌 엔티티 객체를 대상으로 검색하지만 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능하기 때문에 애플리케이션에서 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요하다.

객체와 테이블을 생성하고 매핑하기

  1. 자바 객체 클래스에 @Entity 꼭 넣기
    • 애플리케이션이 로딩될 때, JPA가 해당 클래스를 인지하고 관리해야겠다고 인식함
  2. PK(Primary Key)에 @Id 어노테이션
    • 어노테이션은 웬만하면 javax.persistence 의 어노테이션 선택
  3. DB 테이블 이름은 USER이고, 저장하려는 객체의 Class 이름이 Member로 다르다면 @Table(name = "USER") 와 같이 어노테이션을 작성해준다.
    • 쿼리가 나갈 때, USER 테이블에 가도록 함
  4. DB의 Column과 객체의 필드명이 다르다면, @Column(name = "username")과 같이 어노테이션 작성

References

김영한 님 '자바 ORM 표준 JPA 프로그래밍 - 기본편'

profile
개발 기록
post-custom-banner

0개의 댓글