JPA란?
JPA(Java Persistence API)는 자바를 이용하여 ORM을 구현한 것
따라서 JPA를 구현한 회사마다 방식이 다 다르며 따라서 각 구현체마다 특정 회사의 이름으로 불린다.
ex) Hibernate, TopLink, Eclipselink
ORM?
ORM(Object Relational Mapping)은 객체와 DB의 테이블이 매핑을 이루는 것
즉, 객체가 관계형 데이터 베이스의 테이블이 되도록 매핑 시켜주는 것
ORM을 이용하면 SQL Query가 아닌 직관적인 코드(메서드)로서 DB의 데이터를 조작 가능
자바 객체만 만들면 SQL을 작성하지 않아도 알아서 DB에 CRUD해준다.
Spring Data JPA
스프링 부트는 JPA 중에서 Hibernate라는 구현체를 사용
Spring Data JPA는 이런 Hibernate를 좀 더 쉽게 사용할 수 있는 추가적인 API들을 제공한다.
Spring Data JPA가 DB에 데이터를 다루는 과정
- Spring Data JPA <-> Hibernate <-> JDBC <-> DB
JPA 구성 요소 (Entity, Repository)
Entity
DB 테이블과 직접적으로 매핑되는 클래스
Entity 클래스 => 테이블
Entity 객체 => 하나의 데이터
@Entity
- 클래스에 @Entity를 지정하여 해당 클래스가 엔티티 클래스라는 걸 명시해준다.
@Table
- 엔티티 클래스를 DB의 어떤 테이블과 매핑시킬지 지정한다.
- name 속성을 이용해서 특정 테이블의 이름을 지정한다.
- => application.yml 파일에서 설정에 따라 테이블을 생성할 수 있다.
@Id
- 기본키에 해당하는 변수에 지정해준다.
- 엔티티 클래스에서 @Id로 지정한 변수가 없으면 에러가 발생한다.
@GeneratedValue
- 사용자가 입력하는 값이 아닌 자동으로 생성되는 값을 사용할 때 해당 변수에 지정해준다.
타입
- AUTO: 기본값, JPA 구현체가 알아서 생성
- IDENTITY: 사용하는 DBMS가 키 생성을 결정한다.
- MySQL이나 MariaDB의 경우 auto_increment를 사용
- Oracle은 새로운 테이블을 생성해서 사용
- SEQUENCE: DB의 sequence를 이용해서 키를 생성한다. @SequenceGenerator와 같이 사용
- TABLE: 키 생성 전용 테이블을 생성해서 키를 생성한다. @TableGenerator와 같이 사용
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idx;
private String title;
private String content;
}
Repository
JpaRepository를 상속받은 인터페이스다.
JpaRepository란?
- Spring Data JPA에서 제공하는 인터페이스 중 하나로, JPA를 사용하여 데이터베이스를 조작하기 위한 메서드들을 제공한다.
상속을 받기 때문에 선언하는 것만으로도 내장 메서드들을 통해 DB에 CRUD가 가능하다.
public interface 인터페이스이름 extends JpaRepository<엔티티클래스, @Id변수의 타입> {
}
JPA로 DB 다루기
dependency 추가
build.gradle에 mariadb와 data-jpa 라이브러리 추가
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
application.yml 설정 (DB 설정)
src > main > resources 에 있는 application.properties을 yml로 바꾸고,
파일에 DB 정보를 입력해준다.
properties와 yml 둘 다 써도 되지만, 구조를 더 파악하기 쉬운 yml을 사용할 것이다.
spring:
# 알아서 DB 연결 객체를 생성
# HicariCP를 이용해서 커넥션 풀에 기본 연결 객체를 여러 개 저장
datasource:
url: jdbc:mariadb://[db서버 ip 주소]:3306/[db 이름]
driver-class-name: org.mariadb.jdbc.Driver
username: [사용자 계정]
password: [비밀번호]
이렇게 작성하면 내부적으로 알아서 DB 연결 객체를 생성해준다.
HicariCP를 이용해서 커넥션 풀에 기본 연결 객체를 여러 개 저장해준다.
Entity
DB와 매핑될 엔티티를 생성해준다.
@Entity 는 DB의 테이블을 자동으로 생성해준다.
-> 클래스의 변수들이 DB 테이블의 속성으로 만들어진다.
- class Test01 => CREATE TABLE Test01
- int idx => INT idx
- String name => VARCHAR(255) name
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idx;
private String title;
private String content;
// getter, setter 생략
}
프로젝트를 실행하면 DB에 자동으로 테이블이 생성된다.
Repository
JpaRepository를 상속받아 엔티티 클래스와 기본키 속성을 입력해준다.
Repository를 통해 데이터베이스를 조작할 수 있다.
// JpaRepository<엔티티 클래스, 기본키 속성>
public interface BoardRepository extends JpaRepository<Board, Long> {
}
Service
서비스의 비즈니스 로직 작성 (CRUD)
클래스 위에 @Service 어노테이션을 붙여줘야 한다.
Repository에서 데이터를 받아 어떤 처리를 할지 비즈니스 로직을 작성한다.
삽입 (INSERT)
- save(엔티티객체)
조회 (SELECT)
- findAll()
- findById()
@Service
public class BoardService {
private final BoardRepository boardRepository;
public BoardService(BoardRepository boardRepository) {
this.boardRepository = boardRepository;
}
public void register(BoardRegisterReq dto) {
Board entity = new Board();
entity.setTitle(dto.getTitle());
entity.setContent(dto.getContent());
// save(엔티티객체) : 알아서 INSERT문으로 바꿔서 실행
boardRepository.save(entity);
}
public List<Board> list() {
// findAll(); 알아서 SELECT문으로 바꿔서 실행
List<Board> boardList = boardRepository.findAll();
return boardList;
}
public Board read(Long idx) {
// SELECT * FROM board WHERE idx=1;
Optional<Board> result = boardRepository.findById(idx);
if(result.isPresent()) {
Board board = result.get();
return board;
}
return null;
}
}
Controller
사용자의 요청을 받아 Service에 처리를 넘겨주고, 이에 대한 처리 결과를 반환해준다.
클래스 위에 @RestController 또는 @Controller를 붙여준다.
@RequestMapping과 @GetMapping, @PostMapping 어노테이션을 통해 HTTP 요청을 처리해준다.
@RestController
@RequestMapping("/board")
public class BoardController {
private final BoardService boardService;
public BoardController(BoardService boardService) {
this.boardService = boardService;
}
@PostMapping("/register")
public ResponseEntity<String> register(@RequestBody BoardRegisterReq dto) {
boardService.register(dto);
return ResponseEntity.ok("success");
}
@GetMapping("/list")
public ResponseEntity<List<Board>> list() {
List<Board> boardResList = boardService.list();
return ResponseEntity.ok(boardResList);
}
@GetMapping("/read/{idx}")
public ResponseEntity<Board> read(@PathVariable Long idx) {
Board response = boardService.read(idx);
return ResponseEntity.ok(response);
}
}
board 테이블에 데이터가 이렇게 있을 때
게시글 생성 - register
전체 게시글 조회 - list
게시글 Idx로 조회 - read
'BE > Spring Boot' 카테고리의 다른 글
[Spring Boot] DTO 생성 방법 (단일 파일, 이너 클래스) / 생성 시 주의사항 (0) | 2025.02.10 |
---|---|
[Spring Boot] Repository 메서드 생성 규칙 (findAll, findBy) (0) | 2025.02.07 |
[Spring Boot] 서버 -> 클라이언트로 데이터 전달 (ResponseEntity) (0) | 2025.02.05 |
[Spring Boot] 클라이언트 -> 서버로 데이터 전달 (RequestMapping) (0) | 2025.02.05 |
[Spring Boot] IntelliJ에서 스프링 부트 프로젝트 생성 / 초기 설정 (0) | 2025.02.05 |