[Spring Boot]11.JPA 사용
※JPA란?
JPA(Java Persistence API)란 자바 객체와 데이터베이스 테이블간의 매핑을 처리하는 ORM(Object Relational Mapping)기술의 표준입니다.
ORM : 객체와 관계를 설정하는것.(객체와 관계형 데이터베이스의 매핑을 도와주는것))
이러한 ORM의 개념을 구현하기 위한 표준이 JPA이다.
JPA 프로바이더 : JPA에 대한 실제로 기능을 구현한 구현체가 필요한데 이를 구현한 제품이나 프레임 워크로 하이버네이트,이클립스 링크등의 구현체
>JPA의 장점
개발이 편리
- CRUD용 SQL을 직접 작성하지 않아도 된다.데이터베이스에 독립적인 개발이 가능하다.
- JPA는 특정 데이터베이스에 종속적이지 않기 때문에 데이터베이스와 관계없이 개발할수 있음.
- JPA가 해당 데이터베이스에 맞는 쿼리를 알아서 생성해준다.유지보수에 대한 용이성
- 마이바티스처럼 프레임워크를 사용하면 데이터베이스 중심의 개발을 하기때문에 수정시 관련 테이블을 전부 수정해야되는데 비해 JPA같은 경우 객체만 수정하면 된다.
>JPA 단점
학습곡선이 크다
- SQL을 직접적으로 사용하지 않기 때문에 튜닝등을 할때도 어려움이 있다.
- 개발자가 배워야 할 부분이 많아진다.(데이터 베이스 위주가 아니기 때문에)특정 데이터베이스의 기능을 사용할 수 없다.
- 오라클등. 강력한 함수를 제공해 주지만 데이터 베이스에 종속적인 기능을 사용할 경우 데이터 베이스에 독립적인 개발이 불가능해진다.객체 지향 설계가 필요하다.
- 객체 위주의 설계이다 보니객체 및 비즈니스 로직이 설계,개발하기 어려울수 있음
이제 JPA를 Spring Boot에 설정해 보자
1.application.properties파일에 아래와 같이 셋팅해 준다.
2.DatabaseConfiguration클래스에 JPA설정 빈을 등록한다.
3.자바8에 있는 날짜 및 시간 관련 클래스를 그대로 사용할 경우 MySQL의 버전에 따라 문제가 발생할 수 있어 Jsr310JpaConverters적용 방법을 사용
- build.gradle파일에 spring-boot-starter-data-jpa를 추가한다.
- 설정 후 아래와 같이 BoardApplication.java처럼 셋팅을 해준다.
- 아래와 같이 JPA엔티티를 설정해 준다.
- controller와 service는 기존과 같아 따로 설정할 필요가 없다.(url설정같은 부분만 변경해주면됨)
- 아래와 같이 serviceImpl을 JPA에 맞게 변경해준다.(save,findById등등)
- FileUtils.java를 JPA에 맞게 수정해 준다.(Entity를 변경해준다.)
- Repository를 작성해 준다.( Repository는 스프링 데이터 JPA가 제공하는 인터페이스입니다.)
※스프링 데이터 JPA리포지터리 인터페이스
스프링 데이터 JPA에서 제공하는 리포지터리 인터페이스는 아래와 같은 구조를 가진다.
1.최상위 Repository인터페이스는 아무런 기능이 없어 잘 사용하지 않음
2.CrudRepository는 CRUD기능을 기본으로 제공
3.PagingAndSortingRepository 인터페이스는 CrudRepository기능에 페이징 및 정렬 기능이 추가된 인터페이스입니다.
4.스프링 데이터 JPA를 이용하려면 리포지터리 인터페이스를 기준으로 동적으로 실행할 수 있는 메서드를 생성해 준다.
위와 같이 메서드의 이름에 따라 쿼리가 생성되는 부분을 쿼리 메서드라고 한다.
쿼리 메서드는 find...By,read...By,query...By,count..by,get...by와 같이 시작하면 된다.
예)findByTitle(String title); <- 제목 검색
이와 같이 메서드를 실행하면 JPQL(java Persistence Query Language)문이 실행된다.
- 만약 2개이상의 속성을 조합하려면 And키워드를 사용한다.
예)findByTitleAndCountents(String title,String countents); <-제목과 내용으로 검색
그 이외에도 아래와 같이 여러가지의 비교 연산자를 쓸수 있다.
5.위와 같이 사용을 하면되지만 쿼리로 가져올려고 하다 보면 복잡하게 얽혀 있어서 메서드명이 점점 길어질수 있다.
(예)findByLastnameAndfirstnameAndFirstnameIsAndObjectNameOrName......(끝없이....))
이와 같이 복잡해 진다면 @Query어노테이션을 사용하여 쿼리를 직접 작성할수 있다.
1.[?숫자]형식으로 파라미터를 지정. 순서대로 각각 ?1,?2에할당 된다.
2.:[변수이름]으로 파라미터를 지정. 변수이름은 @Param어노테이션에 대응된다.
위와같이 선언해서 사용할 경우에는 주의할 점이 있는데 FROM절에 데이터베이스의 테이블명이아니라 검색하려는
엔티티 이름을 사용한다는 부분을 주의해서 작업해야 한다.
※해당 JPA프로젝트를 실행하면 spring.jpa.generate-ddl옵션을 이용하여 해당하는 데이터베이스의 테이블이 자동생성 또는 변경이 된다.
- 엔티티에 변화가 없으면 테이블 생성,변경을 하는 쿼리는 수행되지 않고 바로 애플리케이션이 실행된다.
>생성한 로그
2022-09-18 15:42:36,211 INFO [jdbc.sqlonly] create table t_jpa_board (board_idx integer not null auto_increment, contents varchar(255) not null, created_datetime datetime not null, creator_id varchar(255) not null, hit_cnt integer not null, title varchar(255) not null, updated_datetime datetime, updater_id varchar(255), primary key (board_idx)) engine=InnoDB
2022-09-18 15:42:36,254 INFO [jdbc.sqlonly] create table t_jpa_file (idx integer not null auto_increment, created_datetime datetime not null, creator_id varchar(255) not null, file_size bigint not null, original_file_name varchar(255) not null, stored_file_path varchar(255) not null, updated_datetime datetime, updater_id varchar(255), board_idx integer, primary key (idx)) engine=InnoDB
2022-09-18 15:42:36,262 INFO [jdbc.sqlonly] alter table t_jpa_file add constraint FK2nbe74xrl4gfj0wnqo1d6dk3l foreign key (board_idx) references t_jpa_board (board_idx)
2022-09-18 15:42:37,990 INFO [board.BoardApplication] Started BoardApplication in 5.89 seconds (JVM running for 8.414)
댓글을 작성해보세요.