JAVA/JPA

JPA(Java Persistence API) 기초

대현 2022. 8. 19. 16:30
JPA(Java Persistence API) 란 ?
ORM(Object-Relational Mapping) 기술 표준으로 사용되는 인터페이스 모음
 

Spring 프레임워크는 JPA를 서브 프로젝트로 구현하여 제공하고 있음


ORM(Object-Relational Mapping)이란?

자바 클래스와 관계형 데이터베이스(: Oracle )테이블의 연결(매핑)

 

   ㄴ  1:1 매칭(테이블 1= 자바 객체 1)

 

자바 객체와 관계형 데이터베이스의 테이블을 자동으로 영속화

 

   ㄴ 영속화객체와 테이블은 동일한 데이터를 가진다.”
 

JPA의 장점

1) SQL문이 아닌 함수를 통해 데이터 조회, 등록, 수정, 삭제 수행
 
    • JPA 내부 엔진이 함수를 자동으로 SQL로 변환하여 실행함
 
2) 객체 지향적 코드 작성이 가능함
 

3) 데이터 모델링 구조가 단순함

 

    • 단일 테이블로 데이터 처리하도록 모델링함
 

     ㄴ 테이블 간 관계 설정을 최소화

 

     ㄴ JOIN 사용 안함

 

 

4) 데이터베이스 변경이 쉬움
 
   • MariaDB -> PostgreSQL 등 다른 데이터베이스로 전전환이 쉬움
 
   • SQL을 작성하지 않음
 
   • JPA 내부 엔진이 작성된 자바 함수를 통해 PostgreSQL에 맞게 SQL을 생성함

JPA의 단점

 

1) 데이터 모델링 구조가 복잡한 경우, 적용이 어려움

 

   • 테이블간 관계가 복잡하면 JPA 적용 불가
 
   • 대부분의 SI, 솔루션 기업은 JPA 적용이 어려움
 
2) 단순 쿼리만 지원하기에 복잡한 수준의 쿼리는 함수로 구현 불가
 
   • Group by, Join 등 불가능하며, SQL을 사용함
 

JPA(Java Persistence API) 를 사용하기 위한 application.properties 설정


예시로 사용할 프로젝트의 구조

* DTO는 데이터 전달 및 받기 위해 활용
   • 특히 JPA로 부터 받은 결과(Entity) DTO에 저장

* Entity에 저장된 데이터를 DTO로 변환하기 위해서는 반드시 변수명이 동일해야 함
   • JPA Entity의 변수명에 _(밑줄) 사용 못하게 함
   • 따라서 DTO 변수명은 _(밑줄)을 쓰면 안됨
   • Entity -> DTO 변환은 쉽게 하기 위해 Jackson 사용할 예정
   • Jackson은 변수명이 동일해야 변환됨

* Service는 주요 로직을 구현하기위해 사용
   • JPA Repository 호출
JPA로 공지사항 리스트 조회
   • @Service 어노테이션 사용
   • 테이블의 값을 변경하는 쿼리 실행은 반드시 트랜젝션(@Transactional) 적용(데이터 등록, 수정, 삭제)
   • EntityDTO로 변환
    ㄴ Entity는 데이터베이스의 테이블과 매칭되는 구조로 사용이 완료되면, 바로 반납하는 것이 성능상 좋음
    ㄴ Entity로부터 받은 결과는 즉시 DTO로 변환하고, Entity를 반납함
Jackson을 이용하여 List<Entity> -> List<DTO> 변환

 

Entity 란?
1) Entity는 테이블과 1:1 매칭됨
2) 테이블에 정의된 주요 설정(Not Null)들을 설정

3) Entity에 객체는 데이터의 조회, 등록, 수정, 삭제 발생시 정보가 같이 저장

   • 캐시 역할
   • Entity는 절대 JPA 및 생성자, 빌더(Builder)를 통해 수정되어야 함
   • 외부의 영향으로 값이 변경되면 안됨
   • 절대 @Setter를 통해 setter 함수들을 생성하면 안됨

 

Entity 주요 어노테이션

Entity 소스 일부

1) @Getter
   • Getter 함수 생성
   • Entity에 저장된 값을 가져오기 위해 활용
2) @NoArgsConstructor
   • 파라미터가 존재하지 않는 생성자 생성
   • new NoticeEntity(); 실행할 때, 메모리에 올리는 함수
3) @AllArgsConstructor
   • Entity 안의 모든 변수를 기반으로 생성자 생성
 
4) @Table(name = "NOTICE")
 
   • 매핑될 관계형 데이터베이스(MariaDB)의 테이블명
 
5) @DynamicInsert
 
   • 데이터 저장할 때, Entity 변수의 값이 null인 변수는 제외하고, insert 쿼리 생성하여 저장하기
 
6) @DynamicUpdate
 
   • 데이터 수정할 때, Entity 변수의 값이 null인 변수는 제외하고, update 쿼리 생성하여 저장하기
 
   • 게시판 내용 중 제목만 수정할 때, 제목만 변경하는 update 쿼리가 생성됨
 
   • 반드시 Entity 생성할 때 추가하길 바람
 
7) @Builder
 
   • Entity 변수에 값을 저장하기 위한 빌더 생성
 
   • 데이터 저장, 수정할 때, 활용
 
   • 생성자 사용하는 것보다 코드가 직관적이고 편리함
 
   • EntitySetter 함수를 절대로 생성하지 않음

8) @Entity

   • 자바 클래스가 Entity임을 알려줌
9) @Id
   • 테이블의 PK 역할인 컬럼에 적용
10) @GeneratedValue(strategy = GenerationType.IDENTITY) 
   • Autoincrement와 같이 자동으로 값을 증가 시킴
   • 항상 @Id 어노테이션과 같이 사용됨

11) @Column
   • 테이블의 컬럼과 매칭

* 예제 설명
    - name = "title" : title 변수는 테이블의 title 컬럼과 매칭
    - length = 500 : 최대 저장가능한 길이는 500바이트
    - nullable = false : 컬럼에 Null 값 저장을 허용하지 않음
* 예제 설명
    - regId 변수는 테이블의 reg_id 컬럼과 매칭
    - updatable = false : Update 쿼리가 실행될 때, 값을 수정하지 않음
12) @NonNull
   • Entity 변수의 값이 Null이 되면 안됨

Repository란?
1) JPA에서 Entity의 값 조회 및 저장, 수정, 삭제 수행하는 역할
2) @Repository 어노테이션 사용
3) JpaRepository 상속함
   • 단순 CRUD 구현은 CrudRepository를 상속 가능
   • 조회시, 정렬, 페이징 기능을 사용하기에JpaRepository 상속하길 추천

4) 인터페이스로 작성(Class 아님)
   • 사용할 Entity 정의
5) Entity를 통해 처리 못하는 경우, SQL(NativeSQL) 작성
   • @Modifying(clearAutomatically = true) 필수 적용
     √ 적용 이유 : Entity 객체의 정보를 초기화하기 위함
(메모리에 있는 Entity의 정보와 NativeSQL로 값을 입력한 DB의 정보가 다르기때문에
값이 제대로 나오지않는 현상을 방지하기 위해)

 

     √ 영속화(동기화)가 되지 않음

Native SQL로 작성된 JPA 함수