본문 바로가기
Back-End/Spring Boot

Spring Boot - JPA

by 코젼 2022. 7. 21.
728x90
반응형

2022-07-21(24일차)


💡 JPA

💁‍♀️ JPA에 대해서 알아봅시다.

▪️ JPA ( Java Persistence API )
▪️ 자바 ORM ( Object Relational Mapping ) 기술에 대한 API 표준
 --> ORM : 객체와 관계형 데이터베이스를 매핑해주는 것

📌 문제점
▪️ 자바 객체를 SQL을 통해 데이터베이스를 관리하게 하고 데이터베이스에 저장된 데이터를 자바 애플리케이션에서 사용하려면 SQL을 통해 다시 자바 객체로 변환하는 반복적인 작업을 해야 한다.
 --> 개발자가 SQL을 매핑하는 역할을 반복해야 한다.
▪️ 객체를 데이터베이스에 넣기 위해서는 SQL문을 통해 변환해서 저장해야 하고, 데이터베이스에서 객체를 다시 꺼내오기 위해서는 복잡한 SQL문을 다시 작성해야 한다.
 --> 결국 객체를 단순히 데이터 전달 목적으로 사용할 뿐 객체지향적으로 프로그래밍 할 수 없다.
 --> 객체지향과 관계형 데이터베이스 간의 패러다임의 불일치

📌 해결
▪️ 객체지향과 관계형 데이터베이스 간의 패러다임의 불일치를 해결하기 위해 나온 기술이다.

📌 JPA 장점
▪️ 특정 데이터베이스에 종속되지 않음
▪️ 객체지향적 프로그래밍 ( java 기반 )
▪️ 생산성 향상

📌 JPA 단점
▪️ 복잡한 쿼리 처리
▪️ 성능 저하 위험
▪️ 학습 시간

📌JPA 동작 방식
🔸엔티티
▪️ 데이터베이스의 테이블에 대응하는 클래스

🔸엔티티 매니저 팩토리
▪️ 엔티티 매니저 인스턴스를 관리하는 주체

🔸엔티티 매니저
▪️ 영속성 컨텍스트에 접근하여 엔티티에 대한 데이터베이스 작업을 제공
▪️ find() 메소드 : 영속성 컨텍스트에서 엔티티를 검색하고 영속성 컨텍스트에 없을 경우 데이터베이스에서 데이터를 찾아 영속성 컨텍스트에 저장한다.
▪️ persist() 메소드 : 엔티티를 영속성 컨텍스트에 저장한다.
▪️ remove() 메소드 : 엔티티 클래스를 영속성 컨텍스트에서 삭제한다.
▪️ flush() 메소드 : 영속성 컨텍스트에 저장된 내용을 데이터베이스에 반영한다.

🔸영속성 컨텍스트
▪️
엔티티를 영구 저장하는 환경으로 엔티티 매니저를 통해 영속성 컨텍스트에 접근한다.

▪️ 객체만 만든 경우는 생성만 된 상태이고 아직 엔티티 매니저에게 넘기지 않은 상태이다.
▪️ JPA가 엔티티 매니저 팩토리를 생성한다.
▪️ 엔티티 매니저 팩토리는 엔티티 매니저를 생성한다.

엔티티 생명주기

🔸스트림(stream)
▪️ open
▪️ action
▪️ close
-- 서버 프로그램을 닫지 않으면 메모리에 계속 살아있어서 서버가 죽는다.

💁‍♀️서버를 시작한다면...

▪️ jsp, jasper를 추가해야한다.
▪️ maven파일이면 pom.xml에 추가한다. 
▪️ gradle파일이면 build.gradle에 추가한다.

⭐가장 좋은 방법은 spring web을 선택해서 참조하여 필요한 것들을 추가하고 파일을 받아서 jsp를 실행한다.

▪️ jpa의 Thymeleaf 사용
▪️ jsp의 mybatis 사용

📌서버 부팅
▪️ spring boot로 서버를 띄우고 spring web으로 mybatis, jpa, mysql, thymeleaf 선택해서 서버를 띄운다.
▪️ application에서 내 환경으로 바꾼다.
▪️ 서버쪽에 페이지를 띄운다.

🔸 MySQL 연결 설정하기
▪️
spring.datasource.hikari.jdbc-url=jdbc:mysql://{url}:{port}/{db}

▪️ Contorller가 메뉴 페이지에 맞춰서 늘어날 것이고, 가져다 붙이면서 사용한다.

💁‍♀️Search를 통해 updateItem과 관련된 정보를 찾아봅시다.

▪️ Search는 단축어 'Ctrl + H'로 열 수 있다.

▪️ Containning text에 'updateItem'을 적는다.
▪️ File name patterns에 '*.java'를 적는다.
▪️ Scope는 Workspace를 선택하고 검색한다.


▪️ 하단에 Search 부분에 'updateItem'과 관련된 정보들이 검색되는 것을 확인할 수 있다.


▪️ ItemeService.java를 보면, item에 있는 updateItem 메서드를 사용하는 것을 확인할 수 있다.

updatItem 메서드를 추적한다.

▪️ ItemController를 보면, itemService에 있는 updateItem 메서드를 사용하는 것을 확인할 수 있다.


📃Item.java

▪️ @Entity가 붙은 클래스는 JPA에서 관리하며 엔티티라고 한다.
▪️ @Table(name="item" : Item이라는 테이블을 만든다.
▪️ lombok 라이브러리 사용. ( @Getter, @Setter, @ToString -> @Data )

▪️ public class Item extends BaseEntity : BaseEntitiy 상속받음. 필요한 것이 있다면 오버라이딩한다.

f3키를 누르면 추적하여 확인할 수 있다.
f4는 모든 상속 계층을 보여준다. 

▪️ Spring한테 @Override 어노테이션을 사용함으로써 오버라이딩 한다는 것을 알려준다. (상속, impliments)

▪️ @Id : long의 id값
▪️ @Column(name="item_id") : name이 item_id인 컬럼을 만든다.
▪️ @GeneratedValue(strategy = GenerationType.AUTO) GenerationType 4가지 타입이 있음을 확인할 수 있다.
생성된 값을 쓸 것이고, 전략은 GenerationType을 AUTO로 지정한다.

▪️ @Column(nullable = false, length = 50) : null이 가능하지 않다(필수), 길이는 50이다.

▪️ @Lob : 큰 파일이 들어갈 수도 있기 때문에 @Lob 어노테이션을 사용한다.

▪️ @Enumerated(EnumType.STRING) private ItemSellStatus itemSellStatus;
ItemSellStatus는 enum타입이기 때문에 @Enumerated 어노테이션을 사용하고, 문자열로 구성되있다고 정의한다. 

▪️ public void updateItem(ItemFormDto itemFormDto)
updateItem에서는 itemFormDto(아이템 정보) - 사용자에게서 컨트롤러를 거쳐서 온 정보를 세팅하는 메서드이다. 
package com.shop.entity;

import com.shop.constant.ItemSellStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.*;
import com.shop.dto.ItemFormDto;
import com.shop.exception.OutOfStockException;

@Entity // JPA에게 테이블을 만들라고 요청한다. 
@Table(name="item") // Item이라는 테이블을 만든다.
// lombok 라이브러리 사용. ( @Getter, @Setter, @ToString -> @Data )
@Getter
@Setter
@ToString
public class Item extends BaseEntity { // BaseEntitiy 상속받음. 필요한 것이 있다면 오버라이딩한다. f3키를 누르면 추적하여 확인할 수 있다. f4는 모든 상속 계층을 보여준다. 
	//Spring한테 @Override 어노테이션을 사용함으로써 오버라이딩 한다는 것을 알려준다. (상속, impliments)

    @Id // long의 id값, 상품 코드
    @Column(name="item_id") // 컬럼을 만든다.
    // GenerationType 4가지 타입이 있음을 확인할 수 있다.
    @GeneratedValue(strategy = GenerationType.AUTO) // 생성된 값을 쓸 것이고, 전략은 GenerationType을 AUTO로 지정한다.
    private Long id;       //상품 코드

    // null이 가능하지 않다(필수), 길이는 50
    @Column(nullable = false, length = 50)
    private String itemNm; //상품명

    // price컬럼은 null이 들어가지 않는다.
    @Column(name="price", nullable = false)
    private int price; //가격

    @Column(nullable = false)
    private int stockNumber; //재고수량

    @Lob // 큰 파일이 들어갈 수도 있기 때문에 @Lob 어노테이션을 사용한다.
    @Column(nullable = false)
    private String itemDetail; //상품 상세 설명

    // ItemSellStatus는 enum타입이기 때문에 @Enumerated 어노테이션을 사용하고, 문자열로 구성되있다고 정의한다.
    @Enumerated(EnumType.STRING)
    private ItemSellStatus itemSellStatus; //상품 판매 상태

    // updateItem에서는 itemFormDto(아이템 정보)-사용자에게서 컨트롤러를 거쳐서 온 정보를 세팅하는 메서드이다.
    public void updateItem(ItemFormDto itemFormDto){
        this.itemNm = itemFormDto.getItemNm(); // 추후 db에 넘길 예정이다.
        this.price = itemFormDto.getPrice();
        this.stockNumber = itemFormDto.getStockNumber();
        this.itemDetail = itemFormDto.getItemDetail();
        this.itemSellStatus = itemFormDto.getItemSellStatus();
    }

    public void removeStock(int stockNumber){
        int restStock = this.stockNumber - stockNumber;
        if(restStock<0){
            throw new OutOfStockException("상품의 재고가 부족 합니다. (현재 재고 수량: " + this.stockNumber + ")");
        }
        this.stockNumber = restStock;
    }

    public void addStock(int stockNumber){
        this.stockNumber += stockNumber;
    }

}

 

728x90
반응형

'Back-End > Spring Boot' 카테고리의 다른 글

Spring Boot - 엔티티 매핑 관련 어노테이션  (0) 2022.07.22
Spring Boot - Thymeleaf  (0) 2022.07.21
Spring Boot - 어노테이션 종류  (0) 2022.07.20
Spring Boot - jsp 파일 생성, web 확인  (0) 2022.07.20
Spring Boot - jsp  (0) 2022.07.20

댓글