[JPA] JPA 소개

보람·2023년 4월 29일
0

Spring

목록 보기
10/18

📋 JPA

(1) JPA

  • Java Persistence API
  • Java 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용하는 인터페이스 모음
  • 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스
  • JPA는 자바 표준 interface만을 제공 -> 여러 업체에서 구현체 기술을 만들어놓음
    • 인터페이스 = 설계문서
    • 설계문서를 구현한 라이브러리(구현체) : eclipseLink, hibernate, dataNucleus 등등...

(2) ORM (Object-Relational Mapping)

  • 객체와 관계형 데이터베이스의 데이터(= RDB(Relational DataBase)의 테이블)를 자동으로 매핑(연결) 해줌
    • 기술적으로는 어플리케이션의 객체를 RDB테이블에 자동으로 영속화 해주는 것
    • 객체지향 프로그래밍은 클래스를 사용하고, 관계형 데이터베이스는 테이블을 사용한다.
    • 객체 모델과 관계형 모델간에 불일치가 존재한다.
    • ORM을 통해 객체간의 관계를 바탕으로 SQL을 자동으로 생성하여 불일치를 해결한다.
  • 데이터베이스 데이터 <-----mapping-----> object 필드
  • 객체를 통해 간접적으로 데이터베이스 데이터를 다룸
    • 객체는 객체대로, RDB는 RDB대로 설계 후
    • 그 사이의 불일치는 ORM이 SQL을 자동 생성하여 해결해 준다는 뜻
    • JPA는 ORM을 구현한 기술 중 하나 : 객체를 통해 데이터베이스를 조작할 수 있는 API를 제공하는 것

(3) JPA 장단점

1) 장점

① 개발자는 비즈니스 로직을 구성하는데만 집중할 수 있음

  • SQL문이 아닌 method를 통해 DB를 조작하므로 객체 모델을 이용하여 로직을 구성하면 됨. (내부적으로는 쿼리를 생성하여 DB를 조작함. 하지만 개발자는 이를 신경쓰지 않아도 됨)

② 코드의 가독성을 높임

  • Query와 같이 필요한 선언문, 할당 등의 부수적인 코드가 줄어들어 각종 객체에 대한 코드를 별도로 작성하여 가독성 높임

③ 객체지향적인 코드 작성이 가능하여 생산성이 증가

  • 매핑하는 정보가 Class로 명시하므로 ERD를 보는 의존도를 낮출 수 잇음

④ 유지보수 및 리팩토링에 유리

  • 기존방식에서 MySql 데이터베이스를 사용하다가 PostgreSQL (대용량 데이터) 로 변환한다고 가정해보면, 새로운 쿼리를 짜야하는 경우가 발생. 이런 경우에 ORM기술을 사용하면 쿼리를 수정할 필요가 없음

2) 단점

① 크고 복잡한 프로젝트의 설계가 잘못되면 속도 저하 및 일관성을 무너뜨리는 문제점 발생

② 결국엔 SQL문을 써야할 수도 있음

  • 복잡하고 무거운 Query는 속도를 위해 별도의 튜닝이 필요하기 때문

③ 학습비용이 비쌈

(4) 데이터베이스 방언

  • JPA는 특정 데이터베이스에 종속 ❌
  • 각각의 데이터베이스가 제공하는 SQL문법과 함수는 조금씩 다름
    • 가변문자 : Oracle varchar2, MySQL varchar
    • 문자열을 자르는 함수 : Oracle substr(), SQL표준 substring()
  • 데이터베이스 방언은 그 중 특정 데이터베이스 방언으로 쿼리를 작성하라는 뜻
// 오라클 10g 방언으로 사용
	<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />

(5) JPA 사용하기

1) JPA dependencies 설정

  • build.gradle > dependencies에 추가
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    runtimeOnly 'com.oracle.database.jdbc:ojdbc8'
  • 프로젝트 생성 시 추가

2) .xml 파일 생성

  • src/main/resources에 폴더 META-INF생성
  • 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="oracle.jdbc.driver.OracleDriver" />
            <!-- oracle id, password -->
			<property name="javax.persistence.jdbc.user" value="spring" />
			<property name="javax.persistence.jdbc.password" value="spring" />
			<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe" />
<!-- 				오라클 10g 방언으로 사용 -->
			<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<!-- 		 	Postgre : 웬만한 쿼리 다 가능 -->
<!-- 		 	<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL10Dialect" />  -->
			<property name="hibernate.hbm2ddl.auto" value="create" />
			<!-- value = none or value = create -->

			<!-- 옵션 -->
			<!-- 콘솔에 하이버네이트가 실행하는 SQL문 출력 -->
			<property name="hibernate.show_sql" value="true" />
			<!-- SQL 출력 시 보기 쉽게 정렬 -->
			<property name="hibernate.format_sql" value="true" />
			<!-- 쿼리 출력 시 주석(comments)도 함께 출력 -->
			<property name="hibernate.use_sql_comments" value="true" />
		</properties>
	</persistence-unit>
</persistence>

3) JPA 사용하기

① @Entity 적용하기

  • @Entity 어노테이션이 붙은 클래스는 데이터베이스에서 하나의 테이블과 매핑
  • 객체를 관계형 데이터베이스 테이블과 매핑하기 위해 사용
  @Entity
  @Getter @Setter
  public class Member {

      @Id
      private Long id;
      private String name;
  }

② jpa 사용하는 클래스 만들기

  • 엔티티 매니저 팩토리는 하나만 생성해서 애플리케이션 전체에서 사용
  • transaction : 데이터베이스의 상태를 변화시키기 위해 수행하는 작업 단위
public class JpaMain {

	public static void main(String[] args) {
		EntityManagerFactory emf 
			= Persistence.createEntityManagerFactory("hello");
		EntityManager em = emf.createEntityManager();
		
		// transaction 선언
		EntityTransaction tx = em.getTransaction();
        // transaction 시작 
		tx.begin();
		
		try {
			// 추가 
			Member member = new Member();
			member.setId(2L);
			member.setName("UserB");
			em.persist(member);
			
			// 회원조회
			Member findMember = em.find(Member.class, 1L);
			System.out.println("findMember.id : " + findMember.getId());
			System.out.println("findMember.name : " + findMember.getName());
			
			// 회원 수정
			findMember.setName("HelloJPA");
			
			// 회원 삭제
			em.remove(findMember);
			
            // transaction 커밋
			tx.commit();
            // 커밋과 커밋 사이를 하나의 트랜잭션 단위 = 비즈니스 단위
			// 오류 나면 트랜잭션 자체가 롤백
		}catch (Exception e) {
			tx.rollback();
		} finally {
			em.close();
			emf.close();
		}
	}
}

③ ctrl + f11로 실행 후 디비버에서 테이블 확인

jpa 세팅을 위한 기본 프레임

package com.codingbox.jpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class Jpabasic {
	public static void main(String[] args) {
		EntityManagerFactory emf 
			= Persistence.createEntityManagerFactory("hello");
		EntityManager em = emf.createEntityManager();		
		EntityTransaction tx = em.getTransaction();
		tx.begin();		
		try {
			tx.commit();
		} catch (Exception e) {
			tx.rollback();
		} finally {
			em.close();
			emf.close();
		}
	}
}
  • @Entity 있으면 기본 프레임만 실행해도 테이블 생성
profile
안녕하세요, 한보람입니다.

0개의 댓글