-
JPA 프로그래밍 - 2 (스프링 데이터 JPA - 3)Programming/Spring Data JPA 2021. 1. 1. 15:46728x90
1. Entity 상태
- Transient : JPA가 모르는 상태
- Persistent : JPA가 관리중인 상태 (1차 캐시, Dirty Checking, Write Behind, ...) - save
- Detached : JPA가 더이상 관리하지 않는 상태 - return 한 경우
- Removed : JPA가 관리하긴 하지만 삭제하기로 한 상태
save()를 호출한다고 바로 DB에 반영되는 것이 아님, JPA가 판단하여 DB에 반영
2. Cascade
엔티티의 상태 변화를 전파 시키는 옵션
Parent - Child 구조를 만들고 양방향 관계를 만듬
- Post.java
cascade를 통해 상태 변화시 저장된 Comment에게 전파하겠다는 설정을 함
@Entity public class Post { @Id @GeneratedValue private Long id; private String title; @OneToMany(mappedBy = "post", cascade = CascadeType.ALL) private Set<Comment> comments = new HashSet<>(); public void addComment(Comment comment) { this.getComments().add(comment); comment.setPost(this); } }
- Comment.java
@Entity public class Comment { @Id @GeneratedValue private Long id; private String comment; @ManyToOne private Post post; }
- JpaRunner.java
Post가 save를 통해 Persistent 상태로 바뀌면, Comment 들도 상태가 바뀜 -> save를 하지 않은 comment들도 DB에 반영됨
@Component @Transactional public class JpaRunner implements ApplicationRunner { @PersistenceContext EntityManager entityManager; @Override public void run(ApplicationArguments args) throws Exception { Post post = new Post(); post.setTitle("This is Title"); Comment comment = new Comment(); comment.setComment("comment"); post.addComment(comment); Comment comment1 = new Comment(); comment1.setComment("comment1"); post.addComment(comment1); Session session = entityManager.unwrap(Session.class); session.save(post); } }
2. Fetch
연관 관계의 엔티티를 어떻게 가져올 것이냐.. 지금(Eager)? 나중에(Lazy)?
- @OneToMany의 기본값은 Lazy
- @ManyToOne의 기본값은 Eager (쿼리가 한 번 일어남)
*PK를 통한 쿼리에만 Fetch 모드가 결정됨
이를 잘 설정해야 성능을 최적화할 수 있음
필요 없는 값을 메모리에 너무 많이 올려놓으면 성능 문제 발생
3. Query
*항상 하이버네이트가 내가 의도한 쿼리를 하는지 살펴보기 - 의도하지 않는 쿼리는 성능 문제 발생 가능*
JPQL (HQL)
- SQL과 비슷하지만, 엔테티 기준으로 작성해야 함
- JPA 또는 하이버네이트가 해당 쿼리를 SQL로 변환해서 실행함
TypedQuery<Post> query = entityManager.createQuery("SELECT p From Post As p", Post.class); List<Post> posts = query.getResultList(); posts.forEach(System.out::);
Criteria
- JPQL 은 타입 세이프 하지 않음! (문자열이 들어가기 때문에)
- 이는 타입 세이프 쿼리
Native Query
- SQL 쿼리 실행하기
List<Post> posts = entityManager.createNativeQuery("SELECT * FROM POST", Post.class).getResultList(); posts.forEach(System.out::println);
4. 성능 문제를 예방하기 위해 SQL문 확인하기
내가 예측한 대로 원하는 만큼 쿼리가 발생하는지?
원하는 데이터를 적절한 타이밍에 가져오고 있는지?
실행된 SQL문의 ? 값 확인하기
logging.level.org.hibernate.type.descriptor.sql=trace
인프런 백기선님 '스프링 데이터 JPA’ 강의를 듣고 정리한 내용입니다.
728x90'Programming > Spring Data JPA' 카테고리의 다른 글
스프링 데이터 Common - Web (스프링 데이터 JPA - 6) (0) 2021.01.01 스프링 데이터 Common - 2 (스프링 데이터 JPA - 5) (0) 2021.01.01 스프링 데이터 Common - 1 (스프링 데이터 JPA - 4) (0) 2021.01.01 JPA 프로그래밍 - 1 (스프링 데이터 JPA - 2) (0) 2020.04.30 관계형 데이터베이스와 ORM (스프링 데이터 JPA - 1) (0) 2020.04.30