실습 코드 참조
moonhy7/SpringFramework: Spring Framework 실습 코드 정리 (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();
}
}
실행 결과
테이블을 드롭했다가 다시 만드는 옵션임
댓글