오늘의 취준/오늘의 공부

[Spring Boot] JPA 사용하기 / Spring Data JPA

gogoem 2023. 9. 16. 03:25
728x90

2023.09.15

 

JPA(Java Persistent API)란?

: JPA는 자바 진영의 ORM(Object-Relational Mapping. 객체와 관계형 DB를 매핑) 기술 표준을 의미합니다.

즉, 데이터를 영구적으로 저장할 수 있도록 Java 진영에서 정해진 규칙이며, SQL문을 직접 작성하지 않고 코드 내에서 CRUD작업을 할 수 있도록 해 줍니다. Hibernate가 JPA를 구현해줍니다.

(주의/ JPA를 사용하려면 해당 클래스의 기본 생성자를 꼭 만들어줘야 합니다.)

 

Spring Data JPA란?

: 복잡한 JPA코드를 스프링으로 쉽게 사용할 수 있도록 도와주는 라이브러리입니다.

JPA를 사용합니다.

 

도식화

 

 

 

왜 필요한가?

- SQL문을 사람이 직접 작성하면 문법 실수가 나올 수 있고, 해당 실수는 컴파일 시점이 아니라 런타임 시점에 발견되므로 발견까지 시간이 오래 걸립니다.

- DB마다 문법이 다르므로 추후 DB변경이 필요할 때 일일이 수정하는 데에 비용과 시간이 많이 들기 때문에 특정 DB에 종속될 가능성이 큽니다.

- 테이블이 생성될 때 마다 새로운 CRUD 연산이 필요하므로 반복 작업이 많아집니다.

 

 

 

JPA는 단순 규칙이며, 해당 규칙을 구현해주는 구현체인 Hibernate를 통해 구현할 수 있습니다.

Hibernate는 내부적으로 JDBC를 사용합니다.

 

 

application.yml 설정

: JPA를 사용하려면 application.yml 파일에 다음과 같은 설정을 해 주어야 한다.

spring:
  datasource:
    url: "jdbc:mysql://localhost/library"
    username: "root"
    password: ""
    driver-class-name: com.mysql.cj.jdbc.Driver
    
  jpa:
    hibernate:
      ddl-auto: none  
           //스프링 시작 시 DB의 테이블 처리에 대한 옵션
           //create : 기존 테이블 삭제 후 재생성
           //create-drop : 스프링 종료 시 테이블 모두 제거
           //update : 객체와 테이블이 동일한지 확인
           //none : 별다른 조치 하지 않음
    properties:
      hibernate:
      show_sql: true
           //JSA로 SQL을 날릴 때 SQL문을 보여주는지 여부
      format_sql: true
           //SQL문을 보여줄 때 포맷팅 할 것인지 여부
      dialect: org.hibernate.dialect.MySQL8Dialect
           //DB 종류를 설정하면 자동으로 문법에 맞게 SQL문을 수정해줌.
           //위는 MySQL8.0버전으로 설정한 것.

 

JPA 관련 어노테이션들

@Entity 스프링이 객체와 테이블을 같은 것으로 바라보게 함.
@Id 해당 필드를 Primary Key로 간주함.
@GeneratedValue Primary Key를 자동 생성되는 값으로 설정.
@GeneratedValue(strategy = GenerationType.IDENTITY) : Mysql의 auto_increment와 동일
@Column 객체의 필드와 테이블의 필드를 매핑. 생략 가능함.
null 가능 여부, 길이 제한, DB의 컬럼명 설정 등. (객체와 DB 컬럼명이 동일하면 생략 가능함.)

 

 

 

Fruit 객체와 Fruit 테이블을 조작하는 예시

테이블 구조

CREATE TABLE fruit{
    id int auto_increment,
    name varchar(20),
    primary key(id)
   )

fruit 객체

@Entity     //--> 객체와 테이블을 매핑하도록 하는 어노테이션
public class Fruit {

    @Id   //-->id를 객체에 추가해줌.
    @GenerateValue(strategy = GenerationRype.IDENTITY)  //->primary key 표시
    private Integer id = null;
    
    @Column(nullable = false, length = 20, name = "name")
            //Column에 붙이는 어노테이션.
            //주로 null 여부, 길이제한, DB에서의 column이름을 설정.(이름이 다를 경우)
	private String name;
    
    protected Fruit() {}
        //JPA에 의해 테이블과 매핑된 객체는 파라미터가 없는 기본 생성자가 꼭 필요함.
    
    public Fruit(String name) {
        this.name = name;
    }
    
	public String getName() {
        return name;
    }
}

 

 

사용자 입력 받는 request 객체

public class FruitsaveRequest {
    private String name;

    public String getName() {
        return name;
    }
}

 

 

 

JPA 사용하지 않는 경우

//FruitService.java
public class FruitService {
    private final FruitRepository fruitRepository;
       //service에서 repository 선언
    
    public FruitService(JdbcTemplate jdbcTemplate) {
        this.fruitRepository = new fruitRepository(jdbcTemplate);
    }
    
    public void saveFruit(FruitSaveRequest request){
        fruitRepository.saveFruit(request.getName());
    }
--------------------------------------------------------------------
//FruitRepository.java
public class FruitRepository {
    private final JdbcTemplate jdbcTemplate;

    public FruitRepository(JdbcTemplate jdbcTemplate){
        this.jdbcTemplate = jdbcTemplate;
    }

    public void saveFruit(String name){
        String sql = "INSERT INTO fruit (name) VALUES (?)";
               //코드 내에서 SQL문을 직접 작성해야 함.
        jdbcTemplate.update(sql, name);
    }
}

 

 

JPA 사용하는 경우

//FruitService.java

@Service
public class FruitService2 {
    private final FruitRepository fruitRepository;
    
    public FruitService2(FruitRepository fruitRepository){
        this.fruitRepository = fruitRepository;
    }
    
    public void saveFruit(FruitSaveRequest request) {
        fruitRepository.save(new Fruit(request.getName()));
             //save 메소드를 호출하면 INSERT문이 자동으로 날아감.
    }
}

------------------------------------------------------------------

//FruitRepository.java

public interface FruitRepository extends JpaRepository<Fruit, Integer> {
    //JpaRepository<객체, 객체의 id 자료형> 으로 설정
    // Spring Data JPA가 자동으로 해당 메서드를 구현.
}

 

'오늘의 취준 > 오늘의 공부' 카테고리의 다른 글

MVC 패턴  (0) 2023.09.16
비대칭키 암호화, 대칭키 암호화  (0) 2023.09.16
[Java] comparable 인터페이스  (0) 2023.08.12
[Java/Queue] 큐 사용하기  (0) 2023.08.09
[JAVA/VScode] 자바 개발환경 세팅하기  (0) 2023.08.08