영속성(Persistence): 데이터를 생성한 프로그램이 종료되더라도 사라지지 않는 데이터의 특성을 얘기 한다.
jpa(java persistence api) : 즉, JPA는 ORM을 사용하기 위한 표준 인터페이스를 모아둔 것이다. 사용자가 원하는 jpa구현체를 선택해서 사용하면 되는데 hibernate로 사용한다.
ORM은 Object Relational Model로 다음과 같은 기능을 담당한다.
하이버네이트 프레임워크(ORM FrameWork)는
사용자 어플리케이션에서 세션 팩토리에 세션을 요청하면 세션 팩토리가 설정파일(configuragtion)을 참고하여 Session Object를 인스터화하여 반환해주면. 세션오브젝트를 이용해 디비와 상호연결을 한다. 세션은 매번 디비와 물리적연결이 필요할떄 생성되어서 persistent object를 저장하고 되찾는데 사용한뒤에 없어진다.
Entity Manager(동일하게 생각)를 생성할떄 자동으로 만들어지는데, 엔티티객체들을 관맇는 컨테이너, EntityManager를 통해서만 접근이 가능하며 영속성 컨텍스트에 등록된 엔티티는 ENtityManager가 제공하는 메소드를 통해 관리됨
상태
1차캐시와 FLUSH
EntityManager 의 persist를 통해 엔티티를 영속화 시키면, 엔티티는 (key,Entity)형태로 1차캐시에 등록된다.
1차캐시에 저장된 엔티티는 바로 실제 데이터베이스에 연동되지않고 트랜잭션을 종료할때 실제 디비에 반영된다. (이떄서야 디비에 INSERT문이 실행됨)
SQL 저장소
엔티티를 영속화시키면 먼저 영속성컨텍스트에 등록된다음 해당 엔티티에 해당하는 SQL문을 생성하여 SQL 저장소에 등록한다.
항상 유의할것은 다음이다
스냅샷
엔티티를 영속화시키면 복사본을 만들어서 별도의 컬렉션에 저장하는데 이 공간을 스냅샷이라 한다.
스냅샷에 저장된 원래 엔티티와 1차 캐시에 수정된 엔티티를 비교해서 변경된 값을 UPDATE쿼리문으로 만들어 전송한다. 전송시기는 트랜잭션이 종료될때이다.
이떄, 모든필드수정전략을 사용하는데 이는 다음과 같은 이유여서다.
하지만 단순 조회만을 위해 스냅샷(instance)를 만들게 되면 더 많은 메모리를 사용하는 단점이 있다.
대량의 데이터를 조회만 할거기 때문에 읽기 전용로 메모리 사용량을 최적화할 수 있다.
@Transactional(readOnly = true)
해당 옵션을 주면 Spring Framework가 Hibernate Session의 Flush 모드를 Manual로 설정하여,
강제로 flush()를 하지 않는 한 flush()가 일어나지 않는다.
트랜잭션이 커밋되어도 플러시되지 않음
flush() 할 때 일어나는 스냅샷 비교와 같은 무거운 로직을 수행하지 않음 -> 성능 향상
트랜잭션 시작, 로직수행, 커밋은 똑같이 동작한다.
CRUD
실질적인 CRUD 기능은 EntityManageFactory 부터 생성된 EntityManager를 얻어 이 객체의 persist 메소드를 이용하여 엔티티에 설정된 값을 테이블에 저장함
하지만 이렇다고 실제 DB에 반영되는 것이 아니다.
실제 테이블에 저장되려면 해당 작업(CRUD)이 반드시 트랜잭션I최소작업단위) 안에서 수행되어야한다.
(Transaction은 EntityManager로부터 생성될수 있으며, 트랜잭션시작코드는 begin, commit(성공), 실패(rollback)으로 나눠짐
JPQL(Java Persistence Query Language) → 검색대상이 엔티티임 ,SQL과 매우 유사
기본 쿼리
Containing 키워드(Like 연산자 in sql)
게시글 내용에 특정 단어가 포함된 글 목록을 조회하기 위해서 다음과 같이 사용함
List<Board> findByContentContaining(String searchKeyword)
List<Board> findByTitleContainingOrContentContaining(String , String);
실제 처리되는 SQL문
The LIKE operator is used in a WHERE clause to search for a specified pattern in a column.
SELECT column1, column2, ...
FROM table_name
WHERE columnN LIKE pattern;
Like 연산자에 대해 더 궁금하면 일단 https://www.w3schools.com/sql/sql_like.asp 여기로
데이터 정렬
OrderBy + 변수 + Asc or Desc
List<Board> findByTitleContainingOrderBySeqDesc(String seachKeyword)
페이징과 정렬 처리하기
페이징과 정렬
Pageable paging = PageRequest.of(0,5,Sort.Direction.DESC,"seq")
(페이지번호, 검색할 데이터개수, 정렬 방향, 정렬대상이되는 변수(속성)이름)
Page타입 사용하기
Page<Board> pageInfo = boardReop.findByTitleContaing(String, paging)
pageInfo의 함수들
getSize => pagesize를 알 수 이음
getTotalPages => page개수
getTotalElements = > total count
nextPageable => 다음 page 객체 반환
List<Board> boardList = pageInfo.getContent();