DAY64(2) - JPA

은나현·2023년 4월 26일
0

📌 1. JPA

📍 1-1. JPA

  • JPA : Java Persistence API
    • java 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용하는 인터페이스 모음
    • 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스

📍 1-2. ORM

  • ORM : Object-Relational Mapping
    • 우리가 일반적으로 알고 있는 애플리케이션 ClassRDB(Relational DataBase)의 테이블을 매핑(연결)한다는 뜻이며, 기술적으로는 어플리케이션의 객체를 RDB테이블에 자동으로 영속화해 주는 것이라고 보면 된다.
  • 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해주는 것을 말한다.
    • 객체지향 프로그래밍은 클래스를 사용하고, 관계형 데이터베이스는 테이블을 사용한다.
    • 객체 모델과 관계형 모델 간에 불일치가 존재한다.
    • ORM을 통해 객체 간의 관계를 바탕으로 SQL을 자동으로 생성하여 불일치를 해결한다.
  • 데이터베이스 데이터 <---------mapping ---------> object 필드
    • 객체를 통해 간접적으로 데이터베이스 데이터를 다룬다.

📍 1-3. 장점과 단점

  • 장점

    • SQL문이 아닌 method를 통해 DB를 조작할 수 있으므로 개발자는 객체 모델을 이용하여 비지니스 로직을 구성하는 데만 집중할 수 있다.
      (내부적으로는 쿼리를 생성하여 DB를 조작하지만 개발자는 이를 신경쓰지 않아도 됨)
    • Query와 같이 필요한 선언문, 할당 등의 부수적인 코드가 줄어들어 각종 객체에 대한 코드를 별도로 작성하여 코드의 가독성을 높일 수 있다.
    • 객체지향적인 코드 작성이 가능하다. (생산성 증가)
    • 매핑하는 정보가 Class로 명시되었기 때문에 ERD를 보는 의존도를 낮출 수 있고 유지보수 및 리팩토링에 유리하다.
      • 기존 방식에서 사용하던 데이터베이스를 다른 데이터베이스로 변환한다고 가정할 때 ORM을 사용하면 쿼리를 수정할 필요가 없다.
  • 단점

    • 프로젝트의 규모가 크고 복잡하여 설계가 잘못된 경우, 속도 저하 및 일관성을 무너뜨리는 문제점이 생길 수 있다.
    • 복잡하고 무거운 Query는 속도를 위해 별도의 튜닝이 필요하기 때문에 결국엔 SQL문을 써야 할 수도 있다.
    • 학습비용이 비싸다.

➕ 데이터베이스 방언

  • JPA는 특정 데이터베이스에 종속되지 않는다.
    • 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다르다. 데이터베이스 방언은 그 중 특정 데이터베이스 방언으로 쿼리를 작성하라는 뜻이다.
      <property name="hibernate.dialect"
                  value="org.hibernate.dialect.Oracle10gDialect" />

📍 1-4. JPA 설정파일 예시

  • src/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="oracle.jdbc.driver.OracleDriver" />
             <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" />
             <property name="hibernate.dialect"
                value="org.hibernate.dialect.Oracle10gDialect" />
             <!-- <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL10Dialect" 
                /> -->
             <property name="hibernate.hbm2ddl.auto" 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>

📍 1-5. JPA 사용 예시

  • 엔티티 매니저 팩토리는 하나만 생성해서 애플리케이션 전체에서 공유한다.
  • JPA의 모든 데이터 변경은 트랜잭션 안에서 실행된다.
    	public static void main(String[] args) {
    		// 설정 파일의 persistence-unit name에 맞춰 생성
    		EntityManagerFactory emf = 
    				Persistence.createEntityManagerFactory("hello");
    		EntityManager em = emf.createEntityManager();
    		// transaction 획득
            // 데이터베이스의 상태를 변화시키기 위해 수행하는 작업 단위
    		EntityTransaction tx = em.getTransaction();
            // 트랜잭션 시작
    		tx.begin();
    		try {
    			// 추가 (insert)
    			Member member = new Member();
    			member.setId(1L);
    			member.setName("UserA");
    			em.persist(member);
    			// 회원조회 (select)
    			Member findMember = em.find(Member.class, 1L);
    			System.out.println("findMember.id : " + findMember.getId());
    			System.out.println("findMember.name : " + findMember.getName());
    			// 회원 수정 (update)
    			findMember.setName("HelloJPA");
    			// 회원 삭제 (delete)
    			em.remove(findMember);
                // 트랜잭션 커밋
    			tx.commit();
    		}catch(Exception e) {
            	// 예외 발생시 트랜잭션 롤백
    			tx.rollback();
    		}finally {
            	// 결과와 상관없이 EntityManager, EntityManagerFactory close
    			em.close();
    			emf.close();
    		}

0개의 댓글