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) 적용(데이터 등록, 수정, 삭제)
• Entity를 DTO로 변환ㄴ 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 주요 어노테이션

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 변수에 값을 저장하기 위한 빌더 생성
• 데이터 저장, 수정할 때, 활용
• 생성자 사용하는 것보다 코드가 직관적이고 편리함
• Entity는 Setter 함수를 절대로 생성하지 않음
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의 정보가 다르기때문에
값이 제대로 나오지않는 현상을 방지하기 위해)
√ 영속화(동기화)가 되지 않음
