일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 스프링 구글차트로 기간별 현황 조회하기
- 제이쿼리
- 스프링 Ioc
- 스프링 부트가 해결하려고 했던 문제
- 썸머노트
- 스프링
- 오라클
- CSS
- 스프링 Ioc Container
- Spring Boot가 해결하려고 했던 문제
- HTML
- 스프링 제어역전
- 자바왕기초
- 자바 기초
- jsp
- 스프링 구글차트
- 스프링과 스프링부트 차이점
- 자바
- 오라클일별데이터
- 자바 왕기초
- maven
- 오라클클라우드에 젠킨스 설치하기
- 오라클통계
- 세션
- 자바기초
- 오라클주별데이터
- 자바왕초보
- 스프링 에러
- java
- 오라클월별데이터
- Today
- Total
Just Do it
JPA(Java Persistence API)란 무엇인가 + 예제 실습 1 본문
출처: 코드로 배우는 스프링부트 웹 프로젝트. 구멍가게 코딩단, 남가람북스
2.3 Spring Data JPA의 소개
JPA: Java Persistence API
Java 언어를 통해서 데이터베이스와 같은 영속 계층을 처리하고자 하는 스펙이다. JPA를 이해하기 위해서는 우선 ORM(Object-Relational Mapping)이라는 기술에 대해서 먼저 설명해야만 한다.
2.3.1 ORM과 JPA
- ORM(Object Relational Mapping)은 단어에서 보듯이 객체지향과 관련이 있다.
- ORM은 간단하게 말하자면 '객체지향 패러다임'을 '관계형 데이터베이스에 보존하는 기술'이라고 할 수 있다.
- 패러다임 입장에서 생각하자면 '객체지향 패러다임을 관계형 패러다임으로 매핑(mapping)해 주는 개념'이라고 볼 수 있다.
- ORM의 시작은 아주 단순해서 '객체지향'의 구조가 '관계형 데이터베이스'와 유사하다는 점에서 시작한다.
- 객체지향 언어 중에서 '클래스(Class)'를 사용하는 언어는 특히 그러한 경우인데 예를 들어 '클래스' 장치를 사용하는 객체지향 프로그래밍 언어들은 어떠한 데이터의 구조를 잡기 위해서 우선적으로 클래스를 설계한다.
====> 스프링 프로젝트 당시 DB를 사용하기 위해 VO, DTO, DAO 작성했던 것을 떠올리면 됨!
- 관계형 데이터 베이스를 다루는 입장에서는 클래스는 아니지만 '테이블(Table)'을 설계한다. 새로운 테이블에는 칼럼을 정의하고 칼럼에 맞는 데이터 타입을 지정해서 데이터를 보관하는 틀을 만든다는 의미에서 클래스와 상당히 유사하다.
- 이와 같이 객체지향과 관계형 데이터베이스는 유사한 특징을 가지고 있다. 이런 특징에 기초해서 '객체지향을 자동으로 관계형 데이터베이스에 맞게' 처리해 주는 기법에 대해 아이디어를 내기 시작했고, 그것이 ORM의 시작이었다.
- ORM은 완전히 새로운 패러다임을 주장하는 것이 아니라 '객체지향'과 '관계형'사이의 변환 기법을 의미한다. 따라서 특정 언어에 국한되는 개념이 아니고, 관계형 패러다임을 가지고 있다면 데이터베이스의 종류를 구분하지 않는다. 현실적으로 이미 여러 객체지향을 지원하는 언어에서 ORM을 위한 여러 프레임워크들이 존재하고 있다.
- JPA는 'Java Persistence API'의 약어로 ORM을 Java 언어에 맞게 사용하는 '스펙'이다.
- 따라서 ORM이 좀 더 상위 개념이 되고, JPA는 Java라는 언어에 국한된 개념으로 볼 수 있다.
- JPA는 단순한 스펙이기 때문에 해당 스펙을 구현하는 구현체마다 회사의 이름이나 프레임워크의 이름이 다르게 된다. 여러 프레임워크가 있지만 그중에서 가장 유명한 것은 'Hibernate'이다.
2.3.2 Spring Data JPA와 JPA
- 스프링 부트는 JPA 구현체 중에서 'Hibernate'라는 구현체를 이용한다. Hibernate는 '오픈소스'로 ORM을 지원하는 프레임워크이다.
- 다른 프레임워크와 마찬가지로 Hibernate는 단독으로 프로젝트에 적용이 가능한 독립된 프레임워크이다. 그래서 스프링 부트가 아닌 스프링만을 이용한다고 해도 Hibernate와 연동해서 JPA를 사용할 수 있다.
- 프로젝트 생성 시에 추가한 'Spring Data JPA'는 Hibernate를 스프링 부트에서 쉽게 사용할 수 있는 추가적인 API들을 제공한다.
- 스프링 프레임워크 자체가 대부분의 다른 프레임워크와의 호환성을 위한 라이브러리를 제공하는 경우가 많은데 'Spring Data JPA' 역시 이러한 예이다.
- 이를 정리해서 표현하면 'Spring Data JPA'를 이용했을 때는 다음과 같은 구성을 이용하게 된다.
"Spring Data JPA" <-> "Hibernate" <-> "JDBC" <-> "DB"
2.4 엔티티 클래스와 JpaRepository
- 실습을 통해 실제 Spring Data JPA를 어떤 방식으로 사용하게 되는지 알아볼 필요가 있다.
- Spring Data JPA가 개발에 필요한 것은 단지 두 종류의 코드만으로 가능하다.
* JPA를 통해서 관리하게 되는 객체(이하 엔티티객체(Entity Object))를 위한 엔티티 클래스
* 엔티티 객체들을 처리하는 기능을 가진 Repository
- 이 중에서 Repository는 Spring Data JPA에서 제공하는 인터페이스로 설계하는데 스프링 내부에서 자동으로 객체를 생성하고 실행하는 구조라 개발자 입장에서는 단순히 인터페이스를 하나 정의하는 작업으로도 충분하다. (Spring Data JPA는 자동으로 생성되는 코드를 이용하므로 단순 CRUD나 페이지 처리 등의 개발에 코드를 개발하지 않아도 된다.)
- 실습을 위해 간단한 메모 기능을 하나 정의해서 이를 구현하고 테스트를 실행해보자.
- 먼저 Java에서 객체를 생성하기 위한 엔티티 클래스를 정의한다.
2.4.1 엔티티 클래스 작성
- 예제 프로젝트에 'entity' 패키지를 추가하고, Memo라는 클래스를 정의한다.
어노테이션 | 설명 |
@Entity | 엔티티 클래스는 Spring Data JPA에서는 반드시 @Entity라는 어노테이션을 추가해야만 한다. @Entity는 해당 클래스가 엔티티를 위한 클래스이며, 해당 클래스의 인스턴스들이 JPA로 관리되는 엔티티 객체라는 것을 의미한다. 또한 @Entity가 붙은 클래스는 옵션에 따라서 자동으로 테이블을 생성할 수도 있다. 이 경우 @Entity가 있는 클래스의 멤버 변수에 따라서 자동으로 칼럼들도 생성된다. |
@Table | @Entity 어노테이션과 같이 사용할 수 있는 어노테이션으로 말 그대로 데이터베이스상에서 엔티티 클래스를 어떠한 테이블로 생성할 것인지에 대한 정보를 담기 위한 어노테이션이다. 예를 들어 @Table(name="t_memo")와 같이 지정하는 경우에는 생성되는 테이블의 이름이 't_memo' 테이블로 생성된다. 단순히 테이블의 이름뿐만 아니라 인덱스 등을 생성하는 설정도 가능하다. |
@Id와 @GeneratedValue | @Entity가 붙은 클래스는 PK에 해당하는 특정 필드를 @Id로 지정해야만 한다. @Id가 사용자가 입력하는 값을 사용하는 경우가 아니라면 자동으로 생성되는 번호를 사용하기 위해서 @GeneratedValue라는 어노테이션을 활용한다. @GeneratedValue(strategy = GenerationType.IDENTITY) 부분은 PK를 자동으로 생성하고자 할 때 사용한다. (키 생성 전략이라고 한다.) 만일 연결되는 데이터베이스가 오라클이면 별도의 번호를 위한 별도의 테이블을 생성하고, MySQL이나 MariaDB면 'auto increment'를 기본으로 사용해서 새로운 레코드가 기록될 때 마다 다른 번호를 가질 수 있도록 처리된다. 키 생성 전략은 크게 다음과 같다. * AUTO(default) - JPA 구현체(스프링 부트에서는 Hibernate)가 생성 방식을 결정 * IDENTITY - 사용하는 데이터베이스가 키 생성을 결정. MySQL이나 MariaDB의 경우 auto increment 방식을 이용 * SEQUENCE - 데이터베이스의 sequence를 이용해서 키를 생성. @SequenceGenerator와같이 사용 * TABLE - 키 생성 전용 테이블을 생성해서 키 생성. @TableGenerator와 함께 사용 |
@Column | 만일 추가적인 필드(칼럼)가 필요한 경우에도 마찬가지로 어노테이션을 활용한다. 이때는 @Column을 이용해서 다양한 속성을 지정할 수 있다. 주로 nullable, name, length 등을 이용해서 데이터베이스의 칼럼에 필요한 정보를 제공한다. 속성 중에 columnDefinition을 이용하면 기본값을 지정할 수도 있다. (시간에 대한 기본값은 조금 뒤에서 다룬다.) 기존의 Memo 클래스를 아래와 같이 수정한다. |
변경된 Memo 클래스는 Lombok의 @Getter를 이용해서 Getter 메서드를 생성하고 @Builder를 이용해서 객체를 생성할 수 있게 처리한다. @Builder를 이용하기 위해서는 @AllArgsConstructor와 @NoArgsConstructor를 항상 같이 처리해야 컴파일 에러가 발생하지 않는다.
**@Column과 반대로 데이터베이스 테이블에는 칼럼으로 생성되지 않는 필드의 경우에는 @Transient 어노테이션을 적용한다. 또한, @Column으로 기본 값을 지정하기 위해서 columnDefinition을 이용하기도 한다.
예) @Column(columnDefinition = "varchar(255) default 'Yes'")
2.4.2 Srping Data JPA를 위한 스프링 부트 설정
- 현재까지 데이터베이스의 설정과 엔티티 클래스를 추가한 것 만으로 프로젝트의 실행은 문제가 없긴 하지만, 자동으로 필요한 테이블을 생성하거나 JPA를 이용할 때 발생하는 SQL 등을 확인하기 위해서는 약간의 추가 설정이 필요하다.
- 프로젝트 내에 만들어진 application.properties 파일에 아래와 같은 내용을 추가한다.
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
- 추가된 항목은 크게 3가지로 다음과 같다.
spring.jpa.hibernate.ddl-auto | 프로젝트 실행 시에 자동으로 DDL(create, alter, drop)등을 생성할 것인지를 결정하는 설정이다. 설정값은 create, update, create-drop, validate가 있다. 예를 들어 create의 경우에는 매번 테이블 생성을 새로 시도한다. 예제에서는 update를 이용해서 변경이 필요한 경우에는 alter로 변경되고, 테이블이 없는 경우에는 create가 되도록 설정하였다. |
spring.jpa.properties.hibernate.format_sql | 실제 JPA의 구현체인 'Hibernate'가 동작하면서 발생하는 SQL을 포맷팅해서 출력한다. 실행되는 SQL의 가독성을 높여준다. |
spring.jpa.show-sql | JPA 처리시 발생하는 SQL을 보여줄 것인지 결정한다. |
- 위의 3가지 항목을 추가한 후 프로젝트를 실행하면 데이터베이스에 어떤 테이블이 생성되는지 로그를 통해서 확인할 수 있다.
- 정상적으로 실행된 경우에는 다음과 같이 테이블 생성에 필요한 SQL이 기록되는 것을 확인할 수 있다.
- 그리고 데이터베이스를 이용해 생성된 테이블을 확인할 수 있다.
2.4.3 JpaRepository 인터페이스
- 앞에서 언급했듯이 Spring Data JPA는 JPA의 구현체인 Hibernate를 이용하기 위한 여러가지 API를 제공한다. 그중에서 개발자가 가장 많이 사용할 것이 바로 JpaRepository이다.
- Spring Data JPA에는 여러 종류의 인터페이스의 기능을 통해서 JPA 관련 작업을 별도의 코드 없이 처리할 수 있게 지원한다. 예를 들어 CRUD 작업이나 페이징, 정렬 등의 처리도 인터페이스의 메서드를 호출하는 형태로 처리하는데 기능에 따라서 상속 구조로 추가적인 기능을 제공한다.
- JpaRepository 상속 구조: JpaRepository -> PagingAndSortRepository -> CrudRepository -> Repository
- 일반적인 기능만을 사용할 때는 CrudRepository를 사용하는 것이 좋고, 모든 JPA 기능을 사용하고 싶을 때는 JpaRepository를 이용하지만 특별한 경우가 아니라면 JpaRepository를 이용하는 것이 가장 무난한 선택이다.
1) JpaRepository 사용하기
- JpaRepository는 인터페이스이고, Spring Data JPA는 이를 상속하는 인터페이스를 선언하는 것만으로도 모든 처리가 끝나는 마법 같은 일이 벌어진다. 실제 동작 시에는 스프링이 내부적으로 해당 인터페이스에 맞는 코드를 생성하는 방식을 이용한다.
- 프로젝트 내에 repository 패키지를 생성하고 MemoRepository 인터페이스를 추가한다.
- 작성된 MemoRepository는 특이하게도 인터페이스 자체이고 JpaRepository 인터페이스를 상속하는 것만으로 모든 작업이 끝난다.
- JpaRepository를 사용할 때는 엔티티의 타입 정보(Memo 클래스 타입)와 @Id의 타입을 지정하게 된다.
- 이처럼 Spring Data JPA는 인터페이스 선언만으로도 자동으로 스프링의 빈(bean)으로 등록된다.
'신입 개발자가 되기 위해 공부했던 독학 자료들 > JPA' 카테고리의 다른 글
JPA(Java Persistence API)란 무엇인가 + 예제 실습 2 (0) | 2022.04.05 |
---|