스프링 부트 JPA

존스노우·2021년 9월 27일
0

JPA 사용이유

관계형데이터베이스 -> 데이터를 어떻게 저장할지 초점을 맞춤
객체지향 프로그래밍 -> 메세지 기반 기능과 속성을 한곳에다 관리하는 기술

둘은 시작점부터 틀림 그래서 패러다임 불일치 발생...

그러면? 개발방향은 데이터베이스 모델링에만 집중하는 현상 발생. (ex:mybatis)

그래서 JPA는 중간에서 패러다임을 일치시켜주기 위한 기술

개발자는 객체지향 프로그래밍을하고 SQL 종속적인 개발을 하지않아도됨.

Spring Data JPA

구현체 교체의 용이성 / 저장소 교체의 용이성

실무에서 쓰려면 객체지향프로그램과 관계형데이터 베이스 둘다 이해해야됨 ( 어려움)

사용하려면 디펜던시에 추가해주면됨 . (* h2 메모리상 디비툴)

package com.bookStudy.boo.springboot.domain.posts;

import com.bookStudy.boo.springboot.domain.BaseTimeEntity;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Getter
@NoArgsConstructor //기본 생성자 자동추가 . public Posts(){}
@Entity // 테이블과 링크될 클래스
public class Posts extends BaseTimeEntity {

@Id //PK 필드
@GeneratedValue(strategy = GenerationType.IDENTITY) // auto_increment
private Long id;


@Column(length = 500, nullable = false) //굳이 선언하지않더라도 모두 칼럼이된다 나머지 필드는. 사용할경우 옵션을 주기위해
private String title;

@Column(columnDefinition = "TEXT", nullable = false)
private String content;

private String author;

//실제 DB 테이블과 매칭될 클래스이며 보통 Entity 라고도 한다.  JPA 사용시 데이터 작업할경우 실제쿼리보다 이 클래스 수정  통해작업?
// 해당 클래스의 빌더 패턴 클래스 생성?  생성자 상단에 선언시 생성자에 포함된 필드만 빌더에 포함
@Builder
public Posts(String title, String content, String author) {
    this.title = title;
    this.content = content;
    this.author = author;
}

public void update(String title, String content) {
    this.title = title;
    this.content = content;
}

}

테이블과 직접 링크되는 클래스다. 기본키 설정 및 빌더 클래스(생성자랑 비슷한듯하다)만들어 생성시 컬럼명을 명확히 알수있음
setter 메서드가 없는대신 추가로 클래스내에 퍼블릭 메소드를 만들어 메세지를 보내 상태값을 변경하면 된다.

package com.bookStudy.boo.springboot.domain.posts;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface PostsRepository extends JpaRepository<Posts, Long> {

@Query("SELECT p FROM Posts p ORDER BY p.id DESC")
List<Posts> findAllDesc();

}

레파지토리 클래스이다 엔티티,키 타입을 입력하면 된다.

자동적으로 기본 CRUD 클래스가 생성되는 데 코드상에는 안나와있다

따로 쿼리를 만들고싶으면 @Query 해서 붙여주면 될듯.

package com.bookStudy.boo.springboot.domain.posts;

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.time.LocalDateTime;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest // H2 자동으로 실행해준당
public class PostsRepositoryTest {

@Autowired
PostsRepository postsRepository;


@After //단위 테스트 끝날때 작동 데이터 침범을 막기위해 .
public void cleanup() {
    postsRepository.deleteAll();
}

@Test
public void 게시글저장_불러오기() {

    String title = "게시글 제목";
    String content = "게시글 본문";

    postsRepository.save(Posts.builder() //save 기능은 insert/update  id가 잇으면 업데이트를 실행한다.
            .title(title)
            .content(content)
            .author("kkkj@naver.com")
            .build()
    );

    List<Posts> postsList = postsRepository.findAll();

    Posts posts = postsList.get(0);
    assertThat(posts.getTitle()).isEqualTo(title);
    assertThat(posts.getContent()).isEqualTo(content);

}

@Test
public void 베이스엔티티_등록() {

    //given
    LocalDateTime now = LocalDateTime.of(2021, 9, 25, 0, 0, 0);
    postsRepository.save(Posts.builder().title("title").content("content").author("author").build());


    //when
    List<Posts> postsList = postsRepository.findAll();


    //then

    Posts posts = postsList.get(0);

    System.out.println(">>>>>>>>>> createDate=" + posts.getCreatedDate() );
    System.out.println(">>>>>>>>>> modifyDate=" + posts.getModifiedDate() );

    assertThat(posts.getCreatedDate()).isAfter(now);
    assertThat(posts.getModifiedDate()).isAfter(now);
}

}

테스트코드.

여기까지 -> 테이블과 링크할수있는 엔티티 / 레파지토리를 만든후 코드생성후 테스트 함.

profile
어제의 나보다 한걸음 더

0개의 댓글