[Spring] Spring Data JPA
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