티스토리 뷰
지난 포스팅에서 JPA 인터페이스의 기초적인 개념과 사용 방법에 대하여 다뤘다. 이번 포스팅은 JPA를 Spring 환경에서 좀 더 쉽게 사용할 수 있도록 해주는 모듈인 Spring Data JPA에 대하여 다루려고 한다.
Spring Data JPA는 Spring에서 제공하는 모듈 중 하나로, 개발자가 JPA를 더 쉽고 편하게 사용할 수 있도록 도와준다.
이는 JPA를 한 단계 추상화시킨 Repository라는 인터페이스를 제공함으로써 이루어진다.
즉, Spring-Boot 는 JPA 구현체 중 Hibernate를 이용하는데, Spring Data JPA 가 이 Hibernate를 쉽게 사용할 수 있도록 추가적인 API를 제공하는 것이다.
Spring Data JPA 를 이용하여 개발 시, 필요한 코드는 단 두 종류이다.
1. 엔티티 클래스 : JPA를 통하여 관리되는 객체(엔티티객체)를 위한 클래스
2. Repository : 엔티티 객체들을 처리하는 기능을 보유한 인터페이스
Spring Data JPA에서 제공하는 인터페이스로 설계
스프링 내부에서 자동으로 객체를 생성하고, 실행하는 구조이기 때문에, 개발자는 단순히 인터페이스를 하나 정의 하기만 하면 된다.
Spring Data JPA 를 이용할 경우 모든 코드가 자동으로 생성되기 때문에 CRUD 작업, 페이징 작업을 개발하지 않아도 된다.
일반적인 Spring Data JPA 를 사용하는 프로젝트의 작업 순서는 다음과 같다.
1. 엔티티 클래스 선언
◎ExEntity.java
package com.choonham.maria_ex.entity;
import lombok.*;
import javax.persistence.*;
@Entity
@Table(name="tbl_memo")
@ToString
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Memo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long mno;
@Column(length=200, nullable = false)
private String memoText;
@Transient
private int t;
}
엔티티 클래스는 이전에 포스팅한 내용과 동일하게 생성할 수 있다.
JPA 기초: https://til-choonham.tistory.com/221
2. application.properties 설정 파일 작성
◎application.properties
server.port=9090
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3308/choonham
spring.datasource.username=ROOT
spring.datasource.password=6725
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true;
spring.jpa.show-sql=true
application.properties 파일에 Spring Data JPA 관련 설정을 작성해야 한다.
1) spring.jpa.hibernate.ddl-auto=프로젝트 실행시 자동으로 DDL 을 생성 할 것인지 결정
- create : 매번 테이블을 새롭게 생성
- update : 변경이 필요한 경우에만 alter 되고, 테이블이 없을 경우에는 create
- create-drop : 매번 테이블을 생성하고, 작업 종료 직전 생성된 테이블을 삭제
- validate : 테이블에 대한 유효성 검사
2) spring.jpa.show-sql=true 또는 false
실제 JPA 구현체인 Hibernate가 처리 시에 발생하는 SQL을 보여줄 것인지 여부
3) spring.jpa.properties.hibernate.format-sql=true 또는 false
실제 JPA 구현체인 Hibernate가 동작하면서 발생하는 SQL을 포맷팅(들여쓰기등..)하여 출력
실행되는 SQL에 대한 가독성을 높일 경우에 설정
3. Repository 인터페이스 생성
Spring Data JPA에는 여러 종류의 인터페이스 기능을 이용하여
JPA 관련 작업을 별도의 코드 개발 없이 처리할 수 있도록 지원한다!!!
CRUD 작업, 페이징 처리, 정렬, 검색 등의 처리도 인터페이스의 메서드를 호출하는 형태로 처리가 되는데,
기능에 따라 상속 구조로 추가적인 기능을 제공..
CrudRepository : 일반적인 CRUD 작업만 할 경우 사용
PagingAndSortRepository : 일반적인 CRUD 작업 + 페이징, 정렬 작업을 사용할 경우...
JpaRepository : JPA 관련 모든 기능을 사용할 경우... (개발자가 가장 많이 사용하는 인터페이스)
=>
Spring Data JPA는 이를 상속하는 인터페이스 선언만으로 모든 작업에 대한 개발이 끝난다.
실제 동작 시에는 스프링이 내부적으로 해당 인터페이스에 맞는 코드를 자동 생성한다.
JpaRepository 를 사용할 경우에는 엔티티 타입 정보와 @id 타입 정보를 Map형태로 지정한다..
Spring Data JPA는 인터페이스 선언만으로도 자동으로 스프링 빈(Bean)으로 등록한다.(매우 굿)
즉, 스프링이 내부적으로 인터페이스 타입에 맞는 객체를 생성하여 빈(Bean)으로 등록한다는 것
◎MemoRepository.java(interface)
package com.choonham.maria_ex.repository;
import com.choonham.maria_ex.entity.Memo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MemoRepository extends JpaRepository<Memo, Long> {
}
이제 실제로 데이터의 조작이 가능한지 Test 모듈 내에서 실행해보자.
◎Ex_text.java
package com.choonham.maria_ex.repository;
import com.choonham.maria_ex.entity.Memo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
import java.util.stream.IntStream;
@SpringBootTest
public class MemoRepositoryTests {
@Autowired
MemoRepository memoRepository;
@Test
public void testClass(){
System.out.println(memoRepository.getClass().getName());
}
//등록 테스트 : 100 개의 새로운 Memo 객체를 생성
// MemoRepository 인터페이스를 이용하여 insert
@Test
public void testInsertDummies(){
IntStream.range(1, 100).forEach(i -> {
Memo memo = Memo.builder().memoText("Sample" + i).build();
memoRepository.save(memo);
});
}
//조회 작업 테스트
//findById() 는 반환 타입이 Optical 타입으로 반환
@Test
public void testSelect() {
Long mno = 100L;
Optional<Memo> result = memoRepository.findById(mno);
System.out.println("============");
if(result.isPresent()){
Memo memo = result.get();
System.out.println(memo);
}
System.out.println("============");
}
//조회 작업 테스트2 : getOne() 을 이용
// getOne() 은 엔티티 객체로 반환
@Transactional
@Test
public void testSelect2() {
Long mno = 99L;
Memo memo = memoRepository.getOne(mno);
System.out.println("============");
System.out.println(memo);
System.out.println("============");
}
//수정 테스트
@Test
public void testUpdate(){
IntStream.range(1, 100).forEach(i -> {
Memo memo = Memo.builder().mno(99L).memoText("Update Text").build();
memoRepository.save(memo);
});
}
//삭제 테스트 메서드 : deleteById()
@Test
public void testDelete() {
Long mno = 99L;
memoRepository.deleteById(mno);
}
// 페이지 처리 메서드 : findAll()
// findAll() : Spring Data JPA 에서 페이징 처리와 정렬 작업에서 사용되는 메서드
// PagingAndSortRepository 에서 정의된 메서드
// 이 메서드에 전달할 수 있는 데이터는 Pageable 객체
// 따라서 이 메서드를 사용하려면 먼저 Pageable 객체를 생성하고
// 이 객체는 PageResult.of(시작, 갯수) 같이 지정하여 얻어낼 수 있다.
@Test
public void testPageDefault() {
//만약 한 페이지에 10개씩 출력하고 싶을 때
Pageable pageable = PageRequest.of(0, 10);
Page<Memo> result = memoRepository.findAll(pageable);
System.out.println(result);
System.out.println(result.getTotalPages());
System.out.println(result.getTotalElements());
System.out.println(result.getNumber());
System.out.println(result.getSize());
System.out.println(result.hasNext());
System.out.println(result.isFirst());
}
// 정렬 조건 추가 및 조회된 데이터 출력 : findAll()
@Test
public void testSort(){
Sort sort = Sort.by("mno").descending();
Pageable pageable = PageRequest.of(0, 10, sort);
Page<Memo> result = memoRepository.findAll(pageable);
result.get().forEach(memo -> {
System.out.println(memo);
});
}
}
전체적인 프로젝트의 구조:
'[JAVA] > Spring-Boot' 카테고리의 다른 글
[Spring-Boot] Spring Data JPA 3: @Query (0) | 2021.07.08 |
---|---|
[Spring-Boot] Spring Data JPA 2: 쿼리 메서드 (0) | 2021.07.08 |
[Spring-Boot] Spring Data JPA 1차 정리(비공개) (0) | 2021.07.07 |
[Spring-Boot] Spring-Boot 프로젝트 Maria DB 사용 (0) | 2021.07.06 |
[Spring-Boot] Spring-Boot 시작하기 (0) | 2021.07.06 |
- 맛집
- Promise
- AsyncStorage
- react
- redux-thunk
- 파니노구스토
- redux
- 정보보안기사 #실기 #정리
- react-native
- 인천 구월동 이탈리안 맛집
- 인천 구월동 맛집
- await
- 이탈리안 레스토랑
- javascript
- Async
- Total
- Today
- Yesterday