domain 패키지
- 도메인 담을 패키지 (게시글, 댓글, 회원, 정산, 결제 등 소프트웨어에 대한 요구사항 / 문제 영역)
Entity 클래스
실제 DB의 테이블과 매칭될 클래스
package com.springAWS.domain.posts;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter
@NoArgsConstructor
@Entity
public class Posts {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 500, nullable = false)
private String title;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
private String author;
@Builder
public Posts(String title, String content, String author) {
this.title = title;
this.content = content;
this.author = author;
}
}
- @Entity
- JPA 애노테이션
- 테이블과 링크될 클래스임을 나타냄
- 기본값으로 클래스 카멜케이스 이름을 _네이밍으로 테이블 이름 매칭함
SalesManager.java -> slaes_manager table - 이 클래스의 필드는 모두 칼럼이 됨
- @Id
- 해당 테이블의 PK 필드 나타냄
- @GeneratedValue
- PK의 생성 규칙 나타냄
- GenerationType.IDENTITY 옵션을 추가해야 auto_increment 됨 (대부분 이거로 함)
- @Column
- 기본값 외에 추가 변경 필요한 옵션 있으면 사용함
- ex) VARCHAR(255)가 기본값인데 문자열의 사이즈를 500으로 늘리고 싶을 때
타입을 TEXT로 변경하고 싶을 때
- @NoArgsConstructor
- 기본 생성자 자동 추가 (public Posts(){}와 같은 효과임)
- @Builder
- 해당 클래스의 빌더 패턴 클래스를 생성함
- 생성자 상단에 선언하면 생성자에 포함된 필드만 빌드에 포함시킴
- Setter 메소드 없음
- Setter 메소드 만들게 되면 해당 클래스의 인스턴스 값들이 언제 어디서 변하는지 코드상 명확히 구분 불가능
-> 기능 변경시 복잡해짐 - Entity 클래스에서는 Setter 메소드 만들지 않음
- 해당 필드의 값 변경이 필요할 경우 그 목적과 의도 나타낼 수 있는 메소드 추가해야 함
- Setter 없이 값을 DB에 삽입하는 방법
- 생성자(@Builder) 통해 최종값 채운 후 DB에 삽입하는 것
- 값 변경이 필요하면 해당 이벤트에 맞는 메소드 호출해 변경함
- Setter 메소드 만들게 되면 해당 클래스의 인스턴스 값들이 언제 어디서 변하는지 코드상 명확히 구분 불가능
JpaRepository
- Posts 클래스로 Database를 접근하게 해줌
- 인터페이스로 생성함
- JpaRepository<Entity 클래스, PK 타입>을 상속하면 기본적인 CRUD 메소드 자동 생성됨
- Entity 클래스와 기본 Entity Repository는 함께 위치해야함
package com.springAWS.domain.posts;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PostsRepository extends JpaRepository<Posts, Long> {
}
JpaRepositoryTest
save, findAll 기능 테스트
package com.springAWS.domain.posts;
import junit.framework.TestCase;
import org.assertj.core.api.Assertions;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
public class PostsRepositoryTest extends TestCase {
@Autowired
PostsRepository postsRepository;
@After
public void cleanup(){
postsRepository.deleteAll();
}
@Test
public void savePost(){
//given
String title = "테스트 게시글";
String content = "테스트 본문";
postsRepository.save(Posts.builder()
.title(title)
.content(content)
.author("gayoung@gmail.com")
.build());
//when
List<Posts> postsList = postsRepository.findAll();
//then
Posts posts = postsList.get(0);
assertThat(posts.getTitle()).isEqualTo(title);
assertThat(posts.getContent()).isEqualTo(content);
}
}
- postsRepository.save
- posts 테이블에 insert/update 쿼리 실행함
- id 값 있으면 update, 없으면 insert 쿼리 실행됨
- postsRepository.findAll
- posts 테이블에 있는 모든 데이터 조회함
- 다른 설정 없이 @SpringBootTest 실행하면 H2데이터베이스 자동 실행해줌 (gradle에 넣어둠)
실행된 쿼리 로그 보는 설정
application.properties 파일(resources 하위에 있음, 없으면 만들기)에 옵션 추가하기
#H2쿼리 문법으로 보여짐
spring.jpa.show_sql=true
#MySQL 버전으로 쿼리 출력하려면 추가 (H2 사용해도 가능)
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect