본문 바로가기

🚀 부트캠프 - PLAYDATA/📒 수업 내용 정리

[SpringBoot] Entity 와 Repository 설계 / Repository 메서드 설계 규칙

JPA 프로젝트 구조 

프로젝트 구조


 

Entity 와 Repository 설계

 

Spring Data JPA 사용 

: 테이블 생성을 위해 직접 쿼리를 작성하지 않아도 됨.

이 기능을 가능하게 하는 것이 Entity임. 

 

Entity : 데이터베이스의 테이블에 대응하는 클래스. 데이터베이스에 쓰일 테이블과 칼럼을 정의. Entity에 어노테이션을 사용하면 테이블 간의 연관관계를 정의할 수 있음. 

 

data/entity/Product.java

Entity 클래스 
  • @Entity 어노테이션
  • getter/setter 
  • application.properties 파일에
spring.jpa.hibernate.ddl-auto=update		// 추가

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)  // 자동 증가 (자동생성 방식 결정)
    private Long number;  

    @Column(nullable = false)           // Null값 허용 안함.
    private String name;

    @Column(nullable = false)           // Null값 허용 안함.
    private Integer price;

    @Column(nullable = false)           // Null값 허용 안함.
    private Integer stock;

    private LocalDateTime createdAt;       // Null값 허용 따라서 @Column 없음.

    private LocalDateTime updatedAt;
 Entity 어노테이션 
  • @Entity : 해당 클래스가 Entity임을 명시, 클래스 자체는 테이블과 일대일로 매칭. 클래스 내의 객체들은 테이블에서 하나의 레코드를 의미 
  • @Table : 엔티티 클래스는 테이블과 매핑됨. @Table 어노테이션을 사용할 때는 클래스의 이름과 테이블의 이름을 다르게 지정해야하는 경우! 어노테이션이 없을 경우엔 클래스 이름과 테이블 이름이 동일하다는 의미. 서로 다른 이름을 사용할 경우 @Table(name=값) 형태로 작성 (database와 자바의 명명법이 다르기때문에 자주 사용)
  • @Id : 엔티티는 클래스의 필드는 테이블의 칼럼과 매핑. @Id 가 붙은 필드는 테이블의 기본값 역할. primary 키로 이해하면 될 것 같다. 
  • @GeneratedValue : 자동생성방식 결정 (Auto increment) 
GeneratedValue를 사용하지 않는 방식 (직접할당) : strategy를 지정하지 않을 경우를 의미

1. 애플리케이션에서 자체적으로 고유한 기본값을 생성할 경우 사용하는 방식 
2. 내부에서 정해진 규칙에 의해 기본값을 생성하고 식별자로 사용

* AUTO 
- @GeneratedValue의 기본 설정값 
- 기본값을 사용하는 데이터베이스에 맞게 자동 생성

* INDENTITY 
- 기본 생성을 데이터베이스에 위임하는 방식
- 데이터베이스의 AUTO_INCREMENT를 사용해 기본값 생성

* SEQUENCE
- @SequenceGenerator 어노테이션으로 식별자 생성기를 설정하고 이를 통해 값을 자동 주입 받음.
- @SequenceGenerator를 정의할 때는 name, sequenceName, allocationsize(최대 증가)를 활용

* Table 
- 어떤 DBMS를 사용해도 동일하게 동작하기를 원할경우
- 식별자로 사용할 숫자의 보관 테이블을 별도로 생성해서 Entity를 생성할 때마다 값을 갱신하며 사용
- @TableGenerator 어노테이션으로 테이블 정보를 설정
  • @Column : 엔티티 클래스의 필드는 자동으로 테이블 칼럼으로 매핑됨. 별다른 설정 없으면 명시 안해도됨. 
// Sequence 사용방법이 감이 안와서 첨부! 

@Entity
@SequenceGenerator(
        name = "USER_SEQ_ID",
        sequenceName = "USER_SEQ",
        allocationSize = 1
)
@Table(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_SEQ_ID")  // 자동 증가 (자동생성 방식 결정)
    private Long number;        // 식별값 --> Long의 개수만큼 Entity 들이 만들어 질 수 있음. 따라서Repository 식별 타입 <Long>
    // Big int == Long

 

- name : 데이터베이스의 칼럼명을 설정하는 속성, 명시하지 않으면 필드명으로 지정
- nullable : 레코드를 생성할 때 칼럼에 null처리가 가능한지 명시
- length : 데이터베이스에 저장하는 데이터의 최대 길이 지정
- unique : 해당 칼럼을 유니크로 설정
  • @Transient : 엔티티 클래스에는 선언돼 있는 필드지만 데이터베이스에는 필요 없을 경우 

 


 

리포지토리 인터페이스 설계

 

Spring Data JPA는 JpaRepository를 기반으로 더욱 쉽게 데이터베이스를 생성할 수 있는 아키텍쳐를 제공. 

 

리포지토리 인터페이스 생성 (Spring Data JPA제공 인터페이스)

 

- Entity : 데이터베이스의 테이블과 구조를 생성하는 데 사용

- Repository : Entity가 생성한 데이터베이스에 접근하는데 사용.

 

 

data > repository 패키지 구조


리포지토리 생성 

1. interface 생성

public interface ProductRepository extends JpaRepository<Product, Long> {

  /*
	인터페이스에 있는 기본 메서드들의 의미
    
    List<T> findAll(); ==> select * from

    List<T> findAll(Sort sort); ==> select * from order by

    List<T> findAllById(Iterable<ID> ids); ==> select * from where

    <S extends T> saveAll(Iterable<S> entities);  ==> insert, update, delete 에서 사용됨.

    */
    
}

- JpaRepository 상속(extends) 받기 (별도의 메서드 구현 없이도 많은 기능을 사용할 수 있음)

- 대상 엔티티와 기본값 타입을 지정. ex) <Product, Long>

 

1-1. interface 생성 시 참고할 부분

@Entity
@Table(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)  // 자동 증가 (자동생성 방식 결정)
    private Long number;        // 식별값 --> Long의 개수만큼 Entity 들이 만들어 질 수 있음.
    							// 따라서Repository 식별 타입 <Long>
}

 

 

@Id 어노테이션 붙은 변수

: 식별값 --> Long의 개수만큼 Entity 들이 만들어 질 수 있음.

따라서Repository 식별 타입 <Long> 으로 작성 

 

 null 허용하려면 @Column 어노테이션을 제거 해도 됨. 변수명으로 자동 매핑 됨.

 


 

Entity 코드 예시 
package com.springboot.jpa.data.entity;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)  // 자동 증가 (자동생성 방식 결정)
    private Long number;        // 식별값 --> Long의 개수만큼 Entity 들이 만들어 질 수 있음. 따라서Repository 식별 타입 <Long>
    // Big int == Long
    @Column(nullable = false)           // Null값 허용 안함. null 허용하겠다. 하면 @Column 제거 해도 됨. 변수명으로 자동 매핑 됨.
    private String name;
    // oracle 일 경우 varchar2
    @Column(nullable = false)           // Null값 허용 안함.
    private Integer price;

    @Column(nullable = false)           // Null값 허용 안함.
    private Integer stock;

    private LocalDateTime createdAt;       // Null값 허용 따라서 @없음.

    private LocalDateTime updatedAt;

    public LocalDateTime getUpdatedAt() {
        return updatedAt;
    }
  	/*getter, setter 생략*/
}

 


리포지토리 메서드의 생성 규칙

리포지토리에서 기본적으로 제공하는 조회메서드는 기본값으로 단일 조회하거나 전체 엔티티를 조회하는 것만 지원하고 있기 때문에 필요에 따라 다른 조회메서드를 생성하여 사용해야한다. 

 

메서드 이름 : 첫 단어를 제외한 이후 단어들의 첫 글자를 대문자로 설정

 

find에 조건으로 붙일 수 있는 몇가지 기능들... 
  1. FineBy : SQL문의 where절 역할을 수행하는 구문. findBy뒤에 엔티티의 필드값을 입력하여 사용                                ex) findByName (String name) 
  2. AND, OR : 조건을 여러개 설정하기 위해 사용                                                                                                                  ex) findByNameAndEmail(String name, String email)
  3. Like / NotLike : SQL문의 like와 동일한 기능을 수행, 특정 문자를 포함하는지 여부를 조건으로 추가.                       (Containing, Contains, isContaining)
  4. StartsWith/StartingWith :  특정 키워드로 시작하는 문자열 조건을 정함. 
  5. EndsWith/EndingWith : 특정 키워드로 끝나는 문자열 조건을 정함. 
  6. IsNull / IsNotNull : 레코드의 값이  Null이거나 Null이 아닌 값을 검색 
  7. True/False : Boolean타입의 레코드를 검색할 때 사용
  8. Before/After : 시간을 기준으로 값을 검색 
  9. LessThan / GreaterThan : 특정 값(숫자)을 기준으로 대소 비교를 할 때 사용 
  10. Beetween: 두 값 사이의 데이터를 조회 
  11. OrderBy : SQL 문에서 order by와 동일한 기능을 수행                                                                                                  ex) List<Product> findByNameOrderByPriceAsc(String name); 
  12. countBy : SQL문의 count와 동일한 기능을 수행, 결과값의 개수를 추출