JPA 프로젝트 구조
Entity 와 Repository 설계
Spring Data JPA 사용
: 테이블 생성을 위해 직접 쿼리를 작성하지 않아도 됨.
이 기능을 가능하게 하는 것이 Entity임.
Entity : 데이터베이스의 테이블에 대응하는 클래스. 데이터베이스에 쓰일 테이블과 칼럼을 정의. Entity에 어노테이션을 사용하면 테이블 간의 연관관계를 정의할 수 있음.
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가 생성한 데이터베이스에 접근하는데 사용.
리포지토리 생성
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에 조건으로 붙일 수 있는 몇가지 기능들...
- FineBy : SQL문의 where절 역할을 수행하는 구문. findBy뒤에 엔티티의 필드값을 입력하여 사용 ex) findByName (String name)
- AND, OR : 조건을 여러개 설정하기 위해 사용 ex) findByNameAndEmail(String name, String email)
- Like / NotLike : SQL문의 like와 동일한 기능을 수행, 특정 문자를 포함하는지 여부를 조건으로 추가. (Containing, Contains, isContaining)
- StartsWith/StartingWith : 특정 키워드로 시작하는 문자열 조건을 정함.
- EndsWith/EndingWith : 특정 키워드로 끝나는 문자열 조건을 정함.
- IsNull / IsNotNull : 레코드의 값이 Null이거나 Null이 아닌 값을 검색
- True/False : Boolean타입의 레코드를 검색할 때 사용
- Before/After : 시간을 기준으로 값을 검색
- LessThan / GreaterThan : 특정 값(숫자)을 기준으로 대소 비교를 할 때 사용
- Beetween: 두 값 사이의 데이터를 조회
- OrderBy : SQL 문에서 order by와 동일한 기능을 수행 ex) List<Product> findByNameOrderByPriceAsc(String name);
- countBy : SQL문의 count와 동일한 기능을 수행, 결과값의 개수를 추출
'🚀 부트캠프 - PLAYDATA > 📒 수업 내용 정리' 카테고리의 다른 글
[Springboot] RestTemplate / 서버간 통신 (0) | 2023.09.12 |
---|---|
[Springboot]9/6 연관 관계 매핑 (0) | 2023.09.06 |
[Springboot] IntelliJ 프로젝트 생성 / pom.xml 문서 구성 (0) | 2023.08.31 |
[Spring] REST API (0) | 2023.08.28 |
[Spring] RedirectAttributes / 로그인 기능 구현 (0) | 2023.08.28 |