/ SPRING BOOT, SPRING, JPA

JPA 사용해보기

스프링 목록

스프링 부트 목록



ORM(링크)

객체 관계 매핑(Object-relational mapping; ORM)은 데이터베이스와 객체 지향 프로그래밍 언어 간의 호환되지 않는 데이터를 변환하는 프로그래밍 기법이다.

객체 지향 언어에서 사용할 수 있는 “가상” 객체 데이터베이스를 구축하는 방법이다. 객체 관계 매핑을 가능하게 하는 상용 또는 무료 소프트웨어 패키지들이 있고, 경우에 따라서는 독자적으로 개발하기도한다.





JPA(링크)

자바 퍼시스턴스 API또는 자바 지속성 API(Java Persistence API, JPA)는 자바 플랫폼 SE와 자바 플랫폼 EE를 사용하는 응용프로그램에서 관계형 데이터베이스의 관리를 표현하는 자바 API이다.

기존에 EJB에서 제공되던 엔터티 빈(Entity Bean)을 대체하는 기술이다.





Hibernate(링크)

하이버네이트 ORM(Hibernate ORM)은 자바 언어를 위한 객체 관계 매핑 프레임워크이다. 객체 지향 도메인 모델을 관계형 데이터베이스로 매핑하기 위한 프레임워크를 제공한다.

orm, jpa, Hibernate 출저 위키피디아




ORM(개념) : 기법

JPA(스펙, 명세) :orm의 자바에서 필요한 스펙

Hibernate(제품) : jpa를 실제 제품으로 만든 프레임 워크






Spring이 해주는 것들

  • CrudRepository인터페이스만 구현해주면 됨
    보안을 위해 실제 구현된 객체 대신 Proxy를 노출
    ex) interface CustomerRepository extends CrudRepository<Customer, String> 타입 제네릭 사용
  • 트랜젝션 단위로 엔터티 매니저가 여러개 만들어 진다
    -> persist context도 여러개 생김





0. Spring Data JPA 라이브러리 추가

프로젝트 우클릭 -> Spring -> Add Starter -> Spring Data JPA 추가





1.application.yml

server:
  port: 9999
  servlet:
    context-path: /jpa
spring:
  datasource:
    hikari:
      driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
      jdbc-url: jdbc:log4jdbc:oracle:thin:@localhost:1521:xe
      username: hr
      password: hr
      maximum-pool-size: 10
      minimum-idle: 2
  jpa:
    database: oracle
#DB전용 SQL 문법 사용가능 : ROWNUM , DECODE(), 데이블 생성시 SUBQUERY사용방법이 DB마다 다를수 있다.
    generate-ddl: true
    show-sql: true
    database-platform: org.hibernate.dialect.Oracle10gDialect
    
    
logging:
  level:
    org.hibernate: info





2.MyCustomer.java

@Entity@Table 달아주기
멤버변수 실제 DB에 해당하는 PK값에 @ID 꼭달아주기

항상 이런식으로 Entity를 구현해주면 됨

package com.my.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity(name = "mycustomer")
@Table(name="mycustomer")
public class MyCusomer {
	@Id
	private String id;
	private String pwd;
	private String name;
	
	public MyCusomer() {
		super();
	}	
	public MyCusomer(String id, String pwd, String name) {
		this.id = id;
		this.pwd = pwd;
		this.name= name;
	}
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	
}





3. MyCustomerRepository.java (인터페이스)

  • 기본으로 제공되는 CrudRepository 메소드들 참고
  • 타입 제네릭에 객체랑, 키값
package com.my.repository;

import org.springframework.data.repository.CrudRepository;

import com.my.entity.MyCusomer;

public interface MyCustomerRepository extends CrudRepository<MyCusomer, String> {
}

자동으로 JPA가 쿼리를 만들어줌으로 쿼리 짤 필요 없어짐

  • 심지어 findAll() 같은건 자동으로 구현되 있음





4.CustomerRepositoryTest.java

주석들 내용 읽어보기
1차 캐시, 2차캐시 개념 익히기
멤버변수가 참조형이면, hash랑 equals 꼭 재정의 해줘야 캐시 활용 가능

package com.my.repository;

import javax.transaction.Transactional;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.my.customer.entity.Customer;

@SpringBootTest
public class CustomerRepositoryTest {
	
	@Autowired
	private MyCustomerRepository repository;
	
	@Test
	@Transactional //실행은 되지만 commit 안하면 실제 DB반영은 안할 것
	public void testSave() {
		Customer c1 = new Customer("id1", "p1","n1");
		repository.save(c1);
	}

	
	@Test
	@Transactional
	void testSave2() {
		Customer c1 = new Customer("id4", "p1", "n1"); 
		repository.save(c1); //select 한번함, 그러나 insert는 하지않음 (@Commit이 없기때문에 )
		
		Customer c2 = repository.findById("id4").get(); // select 안하고 PC(persistence Context)에 있는 값활용
		

        // 값 다르게 나오는이유 : JPA 설계상 c1 객체를 PC에 가져올때 원본을 카피하기 때문에 실제 기본 해쉬값(주소)이 다름
		Assertions.assertEquals(c1, c2);

		//같게 만들고 싶으면 Customer의 HashoCode 랑 equals 오버라이드 할것
        // (실제 주소는 모르지만 , 해쉬값은 같게 만들수 있음)
	}

}

스프링 목록

스프링 부트 목록