Programming/Spring

[Spring] Spring Data JPA

JIHYEON LEE 2021. 12. 28. 20:19

ORM(Object-Relational Mapping)

ORM 프레임워크가 중간에서 객체와 DB 데이터(테이블)를 자동으로 매핑

sql 자동 생성

프로그램 복잡도를 줄일 수 있다

복잡한 query가 필요한 경우 직접 query를 입력해야 한다

 

 

 

JPA (Java Persistence API)

ORM 기술 표준

JAVA에서 제공하는 API

 

 

 

Spring Data JPA

Spring에서 JPA를 쉽게 사용할 수 있게 만들어놓은 프레임워크CRUD 처리를 위한 공통 인터페이스 제공

 

 

 

JpaRepository

Spring Data JPA에서 CRUD 처리를 위한 공통 인터페이스

find(), findAll(), save(), delete(), ...

 

 

 

@Service

Repository와 Dto를 통해 DB에 접근하여 프로세스를 처리하는 비지니스 로직

@RequiredArgsConstructor
@Service
public class BookmarkService {
    @Autowired
    private BookmarkRepository bookmarkRepository;

    // My List(북마크) 추가
    public BookmarkPrimaryKey addBookmark(BookmarkDto bookmarkDto) {
        return bookmarkRepository.save(BookmarkEntity.builder()
                        .bookmarkPrimaryKey(new BookmarkPrimaryKey(bookmarkDto.getMember_id(), bookmarkDto.getMovie_id()))
                        .createDt(new Date())
                .build()
        ).getBookmarkPrimaryKey();
    }

    // My List(북마크) 삭제
    public void deleteBookmark(BookmarkDto bookmarkDto) {
        bookmarkRepository.deleteById(new BookmarkPrimaryKey(bookmarkDto.getMember_id(), bookmarkDto.getMovie_id()));
    }

    // My List(북마크) 추가 여부
    public boolean getBookmark(String movie_id, String member_id) {
        BookmarkPrimaryKey bookmarkPrimaryKey = new BookmarkPrimaryKey(member_id, movie_id);
        Optional<BookmarkEntity> bookmarkEntity = bookmarkRepository.findById(bookmarkPrimaryKey);
        if(bookmarkEntity.isEmpty()) return false;
        else return true;
    }

    // My List(북마크) 추가 목록 가져오기
    public List<BookmarkEntity> getBookmarks(String member_id) {
        return bookmarkRepository.findAllByMember_id(member_id);
    }
}

 

 

 

@Repository

DB에 직접 접근함

JpaRepository 안에 @Service에서 호출한 save(), delete(), find() 등이 다 있음

가장 많이 사용하는 것은 방금 언급한 save(), delete(), find()로 뒤에 All이나 ById 등을 붙여 응용해서 사용하기도 함

아래의 예시처럼 @Query를 통해 native query를 직접 작성해서 사용할 수도 있음 (query가 복잡한 경우)

@Repository
public interface BookmarkRepository extends JpaRepository<BookmarkEntity, BookmarkPrimaryKey> {
    @Query(value="select * from bookmark where member_id = :member_id", nativeQuery = true)
    List<BookmarkEntity> findAllByMember_id(@Param("member_id") String member_id);
}

 

 

 

@Entity

DB 테이블과 실질적으로 매핑하는 클래스

@EmbeddedId는 primary key가 여러 개일 때 사용하는 어노테이션으로 primary key 클래스를 따로 만들어서 사용함 

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity(name = "bookmark")
public class BookmarkEntity {
    @EmbeddedId
    private BookmarkPrimaryKey bookmarkPrimaryKey;

    @Column(name = "createDt")
    private Date createDt;
}
@Embeddable
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class BookmarkPrimaryKey implements Serializable
{
    private static final long serialVersionUID = 1L;

    private String member_id;
    private String movie_id;
}

 

 

 

@Dto

Entity를 직접 사용할 경우 데이터를 변경할 때 너무 많은 것에 영향이 갈 수 있기 때문에 따로 Dto를 만들어서 사용함

@Data
public class BookmarkDto {
    private String member_id;
    private String movie_id;
    private String createDt;
}

 

 

 

 

 

reference

     -  JPA는 도대체 뭘까? (orm, 영속성, hibernate, spring-data-jpa)

        https://velog.io/@adam2/JPA는-도데체-뭘까-orm-영속성-hibernate-spring-data-jpa

     -  JPA, Hibernate, 그리고 Spring Data JPA의 차이점

        https://suhwan.dev/2019/02/24/jpa-vs-hibernate-vs-spring-data-jpa/

     -  [jpa] Spring Data JPA

        https://joont92.github.io/jpa/Spring-Data-JPA/