본문 바로가기
👨‍💻 2. 웹개발_Back end/2-6 Spring

[Spring] 4장 JPA 개념 - JPA 특징과 프로젝트 생성 및 라이브러리 내려받기

by 달님🌙 2021. 11. 2.
반응형

 

실습 코드 참조

 

moonhy7/SpringFramework: Spring Framework 실습 코드 정리 (github.com)

 

GitHub - moonhy7/SpringFramework: Spring Framework 실습 코드 정리

Spring Framework 실습 코드 정리. Contribute to moonhy7/SpringFramework development by creating an account on GitHub.

github.com

 

 

4.1절 JPA 특징

 

1. JPA 개념

 

1) VO (Value Object) 클래스와 테이블 관계

- 사용자가 입력한 데이터나 비즈니스 로직 수행 결과로 얻은 데이터를 재사용할 수 있도록 데이터베이스에 저장한다.

- 자바 객체와 데이터베이스의 테이블 사이를 매핑하기 위해 많은 SQL 구문과 자바 코드가 필요할 수 밖에 없다.

 

2) Object (VO 객체) Relation (Table) Mapping

- ORM은 정확히 일치하지 않는 자바 객체와 테이블 사이를 매핑해준다.

- 다시 말해, ORM은 자바 객체에 저장된 데이터를 테이블의 ROW 정보로 저장하고, 반대로 테이블에 저장된 Row 정보를 자바 객체로 매핑해준다.

- 이 과정에서 사용되는 SQL 구문과 자바 코드는 ORM 프레임워크가 자동으로 만들어준다.

- DB 연동 기술을 사용할 때 항상 SQL 명령어를 XML 파일에 작성해야했지만 ORM을 사용하면 필요한 SQL을 자동으로 생성해준다.

- 또한 DBMS가 변경될 때는 ORM 환경설정 파일만 조금 수정해주면 된다.

 

3) JPA (Java Persistence API)

- EJB의 EntityBean (가장 처음 등장한 것) : 완성도가 높지 않아서 성능이나 복잡한 구현 등의 문제가 있음

- Hebernate 프레임워크 (그 다음으로 등장한 것) : 완벽한 ORM 프레임워크로서 자바 객체와 테이블의 ROW를 매핑하는 역할을 수행한다. 오랜 시간을 거치며 기능도 추가되고 성능도 향상되어 ORM의 대표적인 프레임워크가 됨 

- TopLink나 Cocobase :  Hebernate 이후 하나씩 등장하기 시작한 프레임워크들

- 이러한 ORM 프레임워크들에 대한 표준화 작업 끝에 그 결과로 JPA가 나오게 되었다.

- 우리가 사용할 프레임워크는 Hebernate 이다.

 

4) JDBC와 JPA 공통점

 

- JPA (Java Persistence API)는 모든 ORM 구현체들의 공통 인터페이스를 제공한다.

- JPA를 JDBC와 비교하면 이해하기가 편하다.

- JDBC는 DB 연동 로직을 구현할 때, JDBC API의 인터페이스들을 이용하면 실질적인 DB 연동 처리는 해당 DBMS의 드라이버 클래스들이 담당하는 구조이다.

- 따라서 DBMS가 변경될 때도 드라이버만 변경하면 JDBC API를 이용하는 애플리케이션은 수정하지 않는다.

 

- JPA도 마찬가지로 애플리케이션을 구현할 때 JPA API를 이용하면 개발 당시 Hibernate를 ORM 프레임워크로 사용하다가 실제 서비스가 시작될 때는 TopLink로 변경이 가능하다.

 

5) JPA 특징

- 단점 : JPA는 복잡한 업무 시스템에서는 쿼리가 많아지고 JOIN이 복잡해져서 사용하기에 불편하다.

- 쓰이는 예 : 보통 스타트업에서 프로토타입, 솔루션 예시를 보여줄 때 많이 사용함

- VO 클래스가 아직 완벽히 매핑되지않았으므로 완벽히 1:1 매핑해줄 예정이다.

 

 

4.2절 JPA 프로젝트 생성

 

1. JPA 설치

 

1) Help > Install New Software... 

 

2) 2020-06으로 변경 후 JPA 검색하여 옵션 빼고 다 체크, 맨 아래 Contact all update~ 체크 해제 > 모두 Next

 

2. Maven 기반 프로젝트 생성

 

1) 설치 완료 후 재부팅한 다음 Maven 기반 프로젝트 생성

 

2) 일반 자바 프로젝트를 생성할 것이므로 기본인 'maven-archetype-quickstart'가 선택된 상태에서 Next 클릭

 

3) Group Id와 Artifact Id, Package 설정 후 Finish

 

3. 프로젝트  설정

 

1) 기본 버전이 1.7로 되어있으므로 버전 변경

 

2) properties > Project Facts > Convert to facted form... 

 

3) JPA 2.1 버전으로 체크

 

4) Apply 버튼이 활성화되어있지 않다면 Type을 Disable Library Configuration 으로 설정

 

 

5) 이제 Apply 버튼이 활성화되었으므로 Apply 해주기

 

6) META-INF 폴더와 그 아래 JPA 환경설정 파일인 persistence.xml 파일이 생성된 것을 알 수 있다.

 

 

4.3절 JPA 라이브러리 내려받기

 

1. jar 파일 추가하기

 

 

 

2. pom.xml 설치 

 

1) pom.xml 파일 수정

<dependencies>
  <!-- JPA, 하이버네트 -->
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>5.1.0.Final</version>
  </dependency>

  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
</dependencies>

 

2) 추가된 라이브러리 확인

 

4.4절 JPA 시작하기

 

1. 엔티티 클래스 매핑

 

 

 

 

 

Board.java

package com.springbook.biz.board;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * Entity implementation class for Entity: Board
 *
 */
//@Entity : 객체를 Entity 클래스로 선언. 테이블과 1:1 매핑됨
@Entity
//@Table : Entity 클래스가 어떤 테이블과 매핑될지 설정
@Table(name="BOARD")
public class Board {
	//@Id : 테이블의 기본 키 값 설정
	@Id
	//@GeneratedValue : 기본 키값 자동 생성하여 할당, 데이터베이스마다 방식이 다름.
	@GeneratedValue
	private int seq;
	private String title;
	private String writer;
	private String content;
	//@Temporal : 날짜 타입을 매핑할 때 사용하는 어노테이션
	@Temporal(TemporalType.DATE)
	private Date regDate = new Date();
	private int cnt;
	
	public int getSeq() {
		return seq;
	}
	public void setSeq(int seq) {
		this.seq = seq;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public Date getRegDate() {
		return regDate;
	}
	public void setRegDate(Date regDate) {
		this.regDate = regDate;
	}
	public int getCnt() {
		return cnt;
	}
	public void setCnt(int cnt) {
		this.cnt = cnt;
	}
	@Override
	public String toString() {
		return "Board [seq=" + seq + ", title=" + title + ", writer=" + writer + ", content=" + content + ", regDate="
				+ regDate + ", cnt=" + cnt + "]";
	}

}

 

2. persistence.xml 파일 작성

 

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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_1.xsd">
	<persistence-unit name="_078_JPAProject">
		<class>com.springbook.biz.board.Board</class>
		
		<properties>
			<!-- 필수 속성 -->
			<!-- DataSource -->
			<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
			<property name="javax.persistence.jdbc.user" value="study"/>
			<property name="javax.persistence.jdbc.password" value="study"/>
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/studydb?serverTimeZone=UTC"/>
			
            
			<!-- 옵션 -->
			<property name="hibernate.show_sql" value="true"/>
			<property name="hibernate.format_sql" value="true"/>
			<property name="hibernate.use_sql" value="false"/>
			<property name="hibernate.id.new_generator_mappings" value="true"/>
			<property name="hibernate.hbm2ddl.auto" value="create"/>		
		</properties>
	</persistence-unit>
</persistence>

 

 

3. 클라이언트 프로그램 작성

 

package com.springbook.biz.board;

import java.util.List;

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

public class BoardServiceClient {

	public static void main(String[] args) {
		//EntityManager 생성
		EntityManagerFactory emf = Persistence.createEntityManagerFactory("_078_JPAProject");
		EntityManager em = emf.createEntityManager();
		
		//Transaction 생성
		EntityTransaction tx = em.getTransaction();
		
		try {
			//Transaction 시작
			tx.begin();
			
			Board board = new Board();
			board.setTitle("JPA 제목");
			board.setWriter("관리자");
			board.setContent("JPA 글 등록 잘 되네요.");
			
			//글 등록
			em.persist(board);
			
			//글 목록 조회
			String jpql = "select b from Board b order by b.seq desc";
			List<Board> boardList = em.createQuery(jpql, Board.class).getResultList();
			for(Board brd : boardList) {
				System.out.println("--->" + brd.toString());
			}
			
			//Transaction commit
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
			//transaction Rollback
			tx.rollback();
		} finally {
			em.close();
		}
		emf.close();
	}

}

 

 

실행 결과

 

 

테이블을 드롭했다가 다시 만드는 옵션임

 

 

 

 

반응형

댓글