일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- type assertion
- 좋은 PR
- Compound Component
- Custom Hook
- 회고
- Redux Toolkit
- Microtask Queue
- useLayoutEffect
- Render Queue
- 프로세스
- task queue
- react
- 명시적 타입 변환
- TypeScript
- docker
- linux 배포판
- AJIT
- JavaScript
- 주니어개발자
- 암묵적 타입 변환
- Recoil
- helm-chart
- Headless 컴포넌트
- CS
- Sparkplug
- zustand
- jotai
- prettier-plugin-tailwindcss
- 타입 단언
- 클라이언트 상태 관리 라이브러리
- Today
- Total
구리
TIL_210705_JPA 개념 본문
목차
DB에 연동되는 기술 : 전통적인 JDBC, 스프링 DAO, MyBatis, Hibernate 등 다양
ORM(Obejct-Relation-Mapping, 객체 관계 매핑) : 자바 객체와 테이블 사이를 매핑, DB연동에 필요한 SQL까지도 프레임워크에서 제공
=> 객체는 객체대로 설계하고, 관계형 데이터베이스는 관계형 데이터베이스대로 설계
=> ORM 프레임워크가 중간에서 매핑
(Hibernate, TopLink 등)
JPA(Java Persistance API) : ORM들을 보다 쉽게 사용할 수 있도록 표준화시킨 것(공통 인터페이스 제공)
<참고>
- MyBatis, iBatis는 ORM이 아니라 SQL Mapper인비다.
- ORM은 객체를 매핑하는 것이고, SQL Mapper는 쿼리를 매핑하는 것입니다.
[JPA 개념]
Mybatis : SQL을 개발자가 직접 XML 파일에 등록하여 사용
Hibernate(와 같은 ORM) : 프레임워크에서 SQL을 생성하기에 개발자가 신경 쓸 필요가 없음
- SQL을 직접 다루는 기술
JDBC를 이용하여 DB 연동 처리시 => 드라이버 클래스 로딩 => 커넥션 연결 => statement 생성 => SQL 전송 및 결과 처리 => 커넥션 연결 해제 등 반복적으로 필요합니다.
이런 반복적인 코드 작성들을 생략할 수 있게 도와주는 것이 프레임워크인데 유지보수시 SQL이 변경되는 것은 반영해야 합니다. 이렇게 수정된 SQL을 사용하는 자바 코드들도 반영되어야 합니다.
- SQL을 직접 다루지 않는 기술
Hibernate와 같은 ORM은 VO가 가지고 있는 정보를 데이터베이스가 아닌 java.util.Map과 같은 컬렉션에 저장하는 것과 동일한 개념
객체를 Map에 저장하므로 관련된 SQL이 사용되지 않고 추가적인 필드가 생겨도 변수만 추가하면 됩니다.
JPA란?
JPA는 마치 JDBC 프로그램에서 JDBC API와 같은 개념JPA가 제공하는 인터페이스를 이용해 DB를 처리하면 실제론 JPA를 구현한 구현체가 동작하는 것으로 해당 구현체는 Hibernate, EclipseLink 등이 존재합니다.
(Hibernate를 ORM 프레임워크로 개발 당시 사용하다가 실제 서비스 시작될 때 TopLink로 변경 가능)
JPA 동작 원리
JPA는 자바 애플리케이션과 JDBC 사이에 존재하며 JDBC의 복잡한 절차를 대신 처리해줍니다. JPA가 DB 연동에 사용되는 코드뿐 아니라 SQL도 제공합니다. 따라서 유지보수의 편의성이 극대화됩니다.
1. JPA 프로젝트 생성 (JPAProject)
- JPA Project는 추가로 설정해야 하는 것들이 있기에 일단 Maven 기반의 프로젝트 생성
- 프로젝트 설정 변경 properties > project facets > JPA 체크
그런데 여기서 JPA 항목이 보이지 않았다. 원래는 STS/이클립스에서 Persistence 관련 모듈이 기본적으로 제공되는데 결함이 있어 제외되고 배포된다.
그래서 추가적은 툴 설치 필요
Help > Install New Software > worh with > http://download.eclipse.org/releases/oxygen 입력 후 엔터
아래 Name 항목 중 Web, XML, Java EE and OSGi Enterprise Development > JPA 관련 모든 항목 체크 후 설치 > 이클립스 재구동
(간단히 찾으려면 "type filter text" 항목에 JPA라고 입력)
혹은 help > market place > jpa > jpa diagram editor 1.1.1 install
- 이클립스 재구동 후 properties > Java Build Path > Java 버전 변경 (1.8) 및 ojdbc8.jar 파일 추가/ properties > project facets > JPA 체크 변경
- properties > project facets > Runtimes > jdb (or jre) check 후 apply
- "Further configuration required" 링크 클릭 > Type : "Disable Library Configuration" 선택 후 OK
- src/main/java > META-INF > persistence.xml 파일 생성됨
2. JPA 라이브러리 받기
pom.xml에서 dependency 수정
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.1.0.Final</version>
</dependency>
3. JPA 시작
(1) 엔티티 클래스 매핑
데이터베이스의 테이블과 매핑될 영속 클래스 작성 (가능한 이클립스에서 제공하는 JPA Entity 생성 기능 이용)
이클립스에서 JPA Perspective가 제공하는 엔티티 생성 기능 사용 시 엔티티 생성과 함께 영속성 설정 파일(persistence.xml)에 자동으로 엔티티 등록
(src/main/java > 패키지 선택 후 New > Other > JPA Entity 클릭 후 Board 이름으로 생성)
Q) Entity란?
JAP에서 하나의 테이블 객체를 표현한 것이라고 생각하면 됩니다. @Entity가 테이블 정보이며 변수는 필드가 되는 셈입니다.
생성시 수정된 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="JPAPrac">
<class>com.bjy.biz.board.Board</class>
</persistence-unit>
</persistence>
엔티티 클래스에 JPA 매핑 관련 어노테이션 설정
package com.springbook.biz.board;
import java.util.Date;
import javax.persistence.*;
@Entity
@Table(name="BOARD")
public class Board{
@Id
@GeneratedValue
private int seq;
private String title;
private String writer;
private String content;
@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 "BoardVO [seq=" + seq + ", title=" + title + ", writer=" + writer + ",content= " + content + ", regDate = " + regDate + ", cnt = " + cnt +"]";
}
}
엔티티 매핑에 사용되는 어노테이션
(매핑 정보가 없는 나머지 필드들은 자동으로 테이블의 동일한 칼럼과 매핑)
@Entity : 엔티티 클래스, 기본적으로 클래스 이름과 동일한 테이블에 매핑
@Table : 엔티티 이름과 매핑될 테이블 이름이 다른 경우, name 속성을 사용하여 매핑, 엔티티 이름 = 테이블 이름일땐 생략 가능
@Id : 테이블의 기본키와 매핑, 예제에서는 seq 변수가 테이블의 SEQ 칼럼과 매핑되도록 설정. 엔티티의 필수 어노테이션으로서 @Id가 없는 엔티티는 사용하지 못함
@GeneratedValue : @Id가 선언된 필드에 기본 키 값을 자동으로 생성하여 할당. 다양한 옵션이 있지만 @GeneratedValue 만 사용시 설정된 DB에 따라서 JPA가 자동으로 결정해줌. (H2는 시퀀스를 이용하여 처리)
@Temporal : 날짜 타입의 변수에 선언하여 날짜 타입 매핑할 시 사용. TemporalType의 DATE, TIME, TIMESTAMP 중 택 1
엔티티와 테이블을 보다 정교하게 매핑하기 위해선 더 많은 어노테이션 필요
(2) persistence.xml 파일 작성
JPA는 무조건 persistence.xml 파일을 로딩하여 설정됩니다.
JPA 메인 환경설정 파일로 영속성 유닛을 설정(persistence-unit), 영속성 유닛에는 JPA가 연동할 DB의 정보가 있습니다.
이 설정 파일이 META-INF 폴더 아래에 존재하다면 별도의 설정 없이 JPA가 인식합니다.
<?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="JPAProject">
<class>com.springbook.biz.board.Board</class>
<properties>
<!-- 필수 속성 -->
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="javax.persistence.jdbc.user" value="bjy"/>
<property name="javax.persistence.jdbc.password" value="qorwjddus96"/>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@127.0.0.1:1521:XE"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
<!-- 옵션 -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="false"/>
<property name="hibernate.id.new_generator_mappings" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
(3) 클라이언트 프로그램 작성
영속성 유닛을 이용해 EntityManagerFactory 객체 생성 > EntityManager 객체 생성 > JPA 이용해 CRUD 기능 구현
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("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("임시 내용");
// 글등록
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();
}
}
Hibernate를 JPA 구현체로 사용했으며 hiberante_sequence라는 시퀀스를 통해 입력할 게시글 일련 번호를 얻어낸후, 글 등록을 처리하는 과정입니다.
이때 INSERT 구문이 자동생성 되었으며, SELECT 구문 또한 자동생성된 것을 볼 수 있습니다.
참고 서적 : 스프링 퀵 스타트
'SPRING FRAMEWORK' 카테고리의 다른 글
TIL_210705_Spring & JPA 연동 (0) | 2021.06.29 |
---|---|
TIL_210705_JPA 환경 설정 (0) | 2021.06.29 |
TIL_210629_Spring Mapper XML 파일 설정 (0) | 2021.06.29 |
TIL_210629_Spring Mybatis 프레임워크 시작 (0) | 2021.06.29 |
TIL_210624_Spring 데이터 변환 (0) | 2021.06.23 |