본문 바로가기
Spring/Spring

day79) JPA로 DAO4변경하기

by code_learner 2022. 4. 22.

[JPA]

1) 장점: DB연동을 위한 SQL을 자동으로 생성해준다.
2) jpql을 사용한다 -> 모든 DBMS(MySql,Oracle)의 표준어

   - 해당 DBMS에 맞게 바꿔주는 설정: dialect설정

 


[작업순서]

1) project facets 2.1
   -> unit
2) 필수속성 +옵션
 a. Connection 확보 -> Spring연동시 dataSource
 b. dialect
 +c. 로그

 +d. ddl
3) Entity 클래스
   기존의 VO -> @Entity추가후 unit에 <class>로 추가
   @Id
      객체직렬화 코드 + 기본생성자
+) @GeneratedValue
   DBMS에 맞는 pk생성정책을 자동생성 및 호출


[설정하기]

1)프로젝트 -> properties -> project Facets

*Apply가 안되는 경우

 -하단의 further configuration어쩌구를 클릭-> JPA implementation을 Disable Library Configuration로 변경

*JPA 버전 바꾸기

1. 체크해제 JPA를 제거한다.

2. META-INF의 persistence.xml 파일을 삭제한다.

   (남아있으면 새로 JPA를 추가해도 새 파일이 생성되지 않는다.)

3. Project Facets에서 JPA의 버전부터 2.1로 맞춘 후 체크하여 생성한다.

 

2)Pom.xml설정

-JPA보다 Spring을 먼저 불러내야하는 이슈가 있어서 Spring -> JPA -> MyBatis 순으로 구현체 순서를 바꾸었다.

더보기
 <!-- Spring -->
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>${org.springframework-version}</version>
         <exclusions>
            <!-- Exclude Commons Logging in favor of SLF4j -->
            <exclusion>
               <groupId>commons-logging</groupId>
               <artifactId>commons-logging</artifactId>
             </exclusion>
         </exclusions>
      </dependency>
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-webmvc</artifactId>
         <version>${org.springframework-version}</version>
      </dependency>
   <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-core</artifactId>
       <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
       <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
       <version>2.3.0</version>
    </dependency>
      <!-- JPA 실제 구현체 -->
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-entitymanager</artifactId>
            <version>5.1.0.Final</version>
      </dependency>
      <dependency>
         <groupId>org.springframework.data</groupId>
         <artifactId>spring-data-jpa</artifactId>
         <version>1.8.1.RELEASE</version>
      </dependency>
      <!-- Mybatis -->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
            <version>3.3.1</version>
      </dependency>
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis-spring</artifactId>
            <version>1.2.4</version>
      </dependency>

 

3) 필수속성 + 옵션속성 확보

JPA Content혹은 META-INF폴더 아래 persistence.xml(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="day80">
	<class>com.test.app.board.BoardVO</class>
		<properties>
		<!-- A 핵심설정 DBMS 연동할것이기 때문에 Connection확보해야한다 -->
		<!--Spring이랑 연동시 AC - DataSource를 사용하기 때문에 직접 만들지 않는다 -->
			<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
			<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
			<property name="javax.persistence.jdbc.password" value="1234"/>
			<property name="javax.persistence.jdbc.user" value="kim"/>
			<!-- 실 구현체가 hibernate를 사용하기 때문에 해당 설정을 한다. -->
			
			
			<!-- B DBMS가 달라질 시 value를 바꿔야한다. -->
			<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>	
			
			<!-- 선택설정(hibernate관련) -->
			<!-- C 1. 자동 생성된 SQL문을 로그로 출력해주는 설정 -->
			<property name="hibernate.show_sql" value="true"/>
			<!-- D 2. 테이블관리 설정 -->
			<property name="hibernate.hbm2ddl.auto" value="create"/>
		</properties>
	</persistence-unit>
</persistence>

 

 

A: 핵심속성 - Connection확보, Spring연동시 dataSource로 대체됨

B: 핵심속성 - Dialect 

* DBMS별 hibernate Dialect 설정 방법

DBMS별 hibernate Dialect를 설정해 주어야 설정에 맞게 번역이 가능하다.

  • Oracle 10g : org.hibernate.dialect.Oralce10gDialect
  • MySQL : org.hibernate.dialect.MySQL5InnoDBDialect
  • H2 : org.hibernate.dialect.H2Dialect
  • MariaDB : org.hibernate.dialect.MariaDBDialect

출처: https://logical-code.tistory.com/126

 

[JPA] Dialect(방언)

세상엔 많은 데이터베이스 제품이 존재하고, 각각의 제품은 표준 SQL(ANSI SQL)을 제외한 독자적인 기능을 위한 SQL도 존재한다. SQL Server : ANSI SQL + T-SQL Oracle : ANSI SQL + PL/SQL 기타 등등... 그리고..

logical-code.tistory.com

C: 옵션속성 - 로그

D: 옵션속성 - 테이블 관리 속성

 

3)Entity 클래스

엔티티 클래스 == 영속 클래스
: DB의 테이블을 매핑할 클래스 -> VO

- 기존의 VO에 @Entity 추가 후 persistence.xml에 <class>com.test.app.board.BoardVO</class>형식으로 추가

- @Id : pk 설정
- (객체직렬화 코드 + 기본생성자)
+) @GeneratedValue
   DBMS에 맞는 pk생성정책을 자동생성 및 호출 ex) MySql의 AutoIncrement

 

BoardVO

더보기
package com.test.app.board;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.springframework.web.multipart.MultipartFile;

@Entity//엔티티 클래스가 반드시 가져야하는 @ 
@Table(name="BOARD")
//BOARD라는 테이블과 매핑할게~
//테이블과 클래스명이 같으면 자동 매핑되어서 @Table이 필요없다
public class BoardVO {
	
	private static final long serialVersionUID = 1L;

	public BoardVO() {//엔티티 클래스는 기본생성자가 필수
		super();
	}
	
	@Id //엔티티 클래스가 반드시 가져야하는 @ //pk를 알려줌
    //@GeneratedValue//pk생성시 db생성 방식을 따르겠다
	private int bid; // pk
    	//@Column(name="TITLE", length=50)
    	//어떤애랑 엮을 거다에 대한 설정(칼럼이랑 멤버변수명이 다를 때 사용), 속성은 다양한다
	private String title;
	private String writer;
	private String content;
	@Transient//검색등을 사용하여 테이블에 없는 멤버변수 일때 가려주는 역할
	private String searchCondition;
	@Transient
	private String searchKeyword;
	@Transient
	private MultipartFile uploadFile;
	private String filename;
	public String getFilename() {
		return filename;
	}
	public void setFilename(String filename) {
		this.filename = filename;
	}
	public MultipartFile getUploadFile() {
		return uploadFile;
	}
	public void setUploadFile(MultipartFile uploadFile) {
		this.uploadFile = uploadFile;
	}
	public String getSearchCondition() {
		return searchCondition;
	}
	public void setSearchCondition(String searchCondition) {
		this.searchCondition = searchCondition;
	}
	public String getSearchKeyword() {
		return searchKeyword;
	}
	public void setSearchKeyword(String searchKeyword) {
		this.searchKeyword = searchKeyword;
	}
	public int getBid() {
		return bid;
	}
	public void setBid(int bid) {
		this.bid = bid;
	}
	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;
	}
	@Override
	public String toString() {
		System.out.println("BoardVO 로그: "+filename);
		return "BoardVO [bid=" + bid + ", title=" + title + ", writer=" + writer + ", content=" + content + "]";
	}
}

*그 외의 @

-@Temporal(TemporalType.DATE)

  Priavate Date regDate;

:yyyy-mm-dd형태를 매핑해 주는 @

 

4)DAO 구현

BoardDAO4

더보기
package com.test.app.board.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;

import com.test.app.board.BoardVO;

@Repository("boardDAO")
public class BoardDAO4 {
	
	@PersistenceContext//@Autowired와 같은 어노테이션
	private EntityManager em;
	
	public void insertBoard(BoardVO vo) {
		System.out.println("JPA: insertBoard() 호출됨");
		em.persist(vo); // pk값을 해당 DBMS에 맞게 자동생성 -> @GV ★
	}
	public BoardVO getBoard(BoardVO vo) {
		System.out.println("JPA: getBoard() 호출됨");
		return (BoardVO)em.find(BoardVO.class, vo.getBid());
	}
	public List<BoardVO> getBoardList(BoardVO vo) {
		System.out.println("JPA: getBoardList() 호출됨");
		return em.createQuery("from BoardVO b order by b.bid desc").getResultList();
	}
	public void updateBoard(BoardVO vo) {
		System.out.println("JPA: updateBoard() 호출됨");
		em.merge(vo);
	}
	public void deleteBoard(BoardVO vo) {
		System.out.println("JPA: deleteBoard() 호출됨");
		em.remove(em.find(BoardVO.class, vo.getBid()));
	}

}

 

5)팩토리 패턴을 이용한 주입

BoardDAO4에서 EntityManager em주입이 필요하다.

그전에  EntityManagerFactory emf가 먼저 생성되어야한다

-> 팩토리 패턴 (MyBatis때도 사용함)

 

ApplicationContext.xml

더보기
	<!-- DataSource 설정 -->
	<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName"
			value="oracle.jdbc.driver.OracleDriver" />
		<property name="url"
			value="jdbc:oracle:thin:@localhost:1521:xe" />
		<property name="username" value="ksj" />
		<property name="password" value="1234" />
	</bean>

	<!-- JPA 연동 설정 -->
	<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
	</bean>

 

'Spring > Spring' 카테고리의 다른 글

Spring) 알림기능 개선(1) - HTTP, SSE, WebSocket  (0) 2022.12.05
day76) MyBatis로 DAO변경하기  (0) 2022.04.19
day73) 다국어 처리(국제화)  (0) 2022.04.13
day72) 파일 업로드  (0) 2022.04.12
day72) 에러페이지 처리  (0) 2022.04.12

댓글