Spring

Spring Boot STEP 6 - JPA

IT의 큰손 2023. 7. 1. 11:35
728x90

★ 새 프로젝트 생성

Name : boot-jpa
Group : com.test
Artifact : boot-jpa
Package : com.test.jpa

의존성
- Spring Web
- Lombok
- MyBatis Framework
- Oracle Driver
- Spring boot Devtools
- Thymeleaf
- Spring JPA

 

■ JPA, Java Persistent API

  • Java ORM 기술에 대한 API 표준 명세
  • JPA 구현 기술 > Hibernate, EclipseLin, DataNucleus 등
  • 대부분 Hibernate를 사용

■ ORM, Object Relational Mapping

  • Entity 객체와 Database 테이블을 서로 매핑해서, SQL 쿼리가 아닌 Java 메소드를 사용해서 데이터를 조작한다.
  • DB의 데이터 구조를 자바의 객체 구조로 취급

 

★ 기초 셋팅

  • script.sql
create table Item (
    name varchar2(30) primary key,
    price number not null,
    color varchar2(30) not null,
    owner varchar2(30) null,
    orderdate date default sysdate not null
);

insert into Item (name, price, color, owner, orderdate) values ('키보드', 100000, 'black', '홍길동', sysdate - 1);
insert into Item (name, price, color, owner, orderdate) values ('무접점 고급 키보드', 120000, 'white', null, sysdate - 1.5);
insert into Item (name, price, color, owner, orderdate) values ('기계식 키보드', 150000, 'black', '홍길동', sysdate - 2);
insert into Item (name, price, color, owner, orderdate) values ('멤브레인 키보드', 80000, 'white', '홍길동', sysdate - 2.5);
insert into Item (name, price, color, owner, orderdate) values ('마우스', 50000, 'silver', '홍길동', sysdate - 3);
insert into Item (name, price, color, owner, orderdate) values ('버티컬 마우스', 90000, 'silver', '아무개', sysdate - 3.5);
insert into Item (name, price, color, owner, orderdate) values ('게이밍 마우스', 120000, 'black', '아무개', sysdate - 4);
insert into Item (name, price, color, owner, orderdate) values ('고급 볼 마우스', 95000, 'yellow', '아무개', sysdate - 3);
insert into Item (name, price, color, owner, orderdate) values ('노트북', 1100000, 'white', '아무개', sysdate - 4.5);
insert into Item (name, price, color, owner, orderdate) values ('노트북 가방', 120000, 'blue', null, sysdate - 5);
insert into Item (name, price, color, owner, orderdate) values ('노트북 받침대', 95000, 'yellow', '하하하', sysdate - 5.5);
insert into Item (name, price, color, owner, orderdate) values ('노트북 파우치', 95000, 'yellow', '하하하', sysdate - 5);


select * from Item;

commit;
  • 파일 생성
src/main/java > "com.test.controller" > ItemController.java
src/main/java > "com.test.repository" > ItemRepository.java(I)
src/main/java > "com.test.domain > Item.java
src/main/resource > template > item > result.html
  • 설정 -> application.properties
# Server port
server.port=8092

# Oracle settings
#spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
#spring.datasource.url=jdbc:oracle:thin:@localhost:1521/xe
#spring.datasource.username=hr
#spring.datasource.password=java1234

# Hikari CP settings
spring.datasource.hikari.connection-timeout=60000
spring.datasource.hikari.maximum-pool-size=5
spring.datasource.hikari.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.hikari.jdbc-url=jdbc:oracle:thin:@localhost:1521:xe
spring.datasource.hikari.username=test
spring.datasource.hikari.password=java1234

# logging
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
logging.level.org.hibernate.SQL=debug

logging.level.org.hibernate.type.descriptor.sql=trace
logging.level.=error

# Thymeleaf
spring.thymeleaf.cache=false

#JPA
spring.jpa.database=oracle

spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true

 

★ JPA > Entity

  • 데이터베이스의 테이블 <- (연결) -> JPA의 엔티티
  • 매핑 되는 테이블명과 엔티티의 이름을 동일하게 만든다.

 

■ Item.java

package com.test.domain;

import javax.persistence.Entity;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

//JPA > Entity
//- 데이터베이스의 테이블 <- (연결) -> JPA의 엔티티

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Item {

	//엔티티가 참조하는 테이블의 컬럼 > 멤버 정의
	@Id
	private String name;
	
	private int price;
	private String color;
	private String owner;
	private String orderdate;
	
}
  • 스캔 추가 -> BootJpaApplication.java
@ComponentScan(basePackages = "com.test.controller")
@EntityScan(basePackages = "com.test.domain")
@EnableJpaRepositories(basePackages = "com.test.repository")

 

★ 코드 작성 

  • m1 -> insert
------------------------------ItemController.java----------------------------------
@GetMapping("/item/m1")
public String m1(Model model) {

    //[C]RUD
    //- 레코드 추가하기
    Item item = new Item();

    item.setName("잉크젯 프린터");
    item.setPrice(250000);
    item.setColor("yellow");
    item.setOwner("홍길동");

    //save > (JPA) > insert
    Item result = itemRepo.save(item);

    model.addAttribute("result", result);

    System.out.println("m1");

    return "item/result";
}
------------------------------ result.hmtl ----------------------------------
<div class="message" title="결과">
    <th:block th:if="${result != null}">
        <div th:text="${result.name}"></div>
        <div th:text="${#numbers.formatInteger(result.price, 0, 'COMMA')}"></div>
        <div th:text="${result.color}"></div>
        <div th:text="${result.owner}"></div>
        <div th:text="${result.orderdate}"></div>
    </th:block>
</div>
  • m2 -> builder를 이용한 방식 insert
//빌더 패턴(Builder Pattern)
//- OOP에서 객체를 생성하는 패턴 중 하나
//- 유연함

@GetMapping("/item/m2")
public String m2(Model model) {

    Item item = Item.builder().name("레이저 프린터")
                              .price(300000)
                              .color("black")
                              .owner("아무개")
                              .build();

    //save > (JPA) > insert
    Item result = itemRepo.save(item);

    model.addAttribute("result", result);

    System.out.println("m2");

    return "item/result";
}
  • m3 -> 단일 레코드 읽기
@GetMapping("/item/m3")
public String m3(Model model) {

    //C[R]UD
    //- 단일 레코드 읽기
    //Item item = itemRepo.getById("마우스");
    //model.addAttribute("result", item);

    Optional<Item> item = itemRepo.findById("노트북");
    model.addAttribute("result", item.get());

    return "item/result";
}
  • m4 -> 수정하기
@GetMapping("/item/m4")
public String m4(Model model) {

    //CR[U]D
    //- 레코드 수정하기
    /*
    Item item = Item.builder()
                    .name("프린터")//조건절
                    .price(230000) //수정O
                    .color("white") //수정X
                    .owner("홍길동")//수정X
                    .build();
                    */

    //Item result = itemRepo.save(item);
    //model.addAttribute("result", result);

    Optional<Item> item = itemRepo.findById("프린터");

    if (item.isPresent()) {

        item.get().setPrice(240000);

        Item result = itemRepo.save(item.get());

        model.addAttribute("result", result);
    }



    return "item/result";
}
  • m5 -> 삭제하기
@GetMapping("/item/m5")
public String m5(Model model) {

    //CRU[D]
    Optional<Item> item = itemRepo.findById("노트북");

    itemRepo.delete(item.get());

    return "item/result";
}
  • m6 -> 다중값 select
------------------------------ItemController.java----------------------------------
@GetMapping("/item/m6")
public String m6(Model model) {

    //Query Methods

    //다중 레코드 조회
    List<Item> list = itemRepo.findAll();

    model.addAttribute("list", list);

    return "item/result";
}
------------------------------ result.hmtl ----------------------------------
<table class="vertical">
    <tr>
        <th>이름</th>
        <th>가격</th>
        <th>색상</th>
        <th>소유자</th>
        <th>주문날짜</th>
    </tr>
    <tr th:each="item : ${list}">
        <td th:text="${item.name}"></td>
        <td th:text="${#numbers.formatInteger(item.price, 0, 'COMMA')}"></td>
        <td th:text="${item.color}"></td>
        <td th:text="${item.owner}"></td>
        <td th:text="${item.orderdate}"></td>
    </tr>
</table>
  • m7 -> 존재 유무 확인
------------------------------ItemController.java----------------------------------
@GetMapping("/item/m7")
public String m7(Model model) {

    //Query Methods

    //존재 유무 확인 
    boolean bool = itemRepo.existsById("마우스");

    model.addAttribute("bool", bool);

    return "item/result";
}
------------------------------ result.hmtl ----------------------------------
<div th:text="${bool}"></div>
  • m8 -> count
------------------------------ItemController.java----------------------------------
@GetMapping("/item/m8")
public String m8(Model model) {

    //Query Methods

    //존재 유무 확인 
    long count = itemRepo.count();

    model.addAttribute("count", count);

    return "item/result";
}
------------------------------ result.hmtl ----------------------------------
<div th:text="${count}"></div>

 

728x90