WEB/Spring
[Spring] JPA
다콩잉
2023. 2. 15. 15:16
JPA란?
- 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스
- ORM에 대한 자바 API 규격이며 Hibernate, OpenJPA 등이 JPA를 구현한 구현체
JPA 장점
- 생산성이 뛰어나고 유지보수가 용이
- sql을 직접적으로 작성하지 않고, 객체를 사용하여 동작
- DB컬럼이 추가될 때마다 테이블 수정이나 SQL 수정하는 과정, 값을 할당하거나 변수 선언 등의 부수적인 코드가 줄어듦
- DBMS에 대한 종속성이 줄어든다.
- DBMS가 변경된다 하더라도 소스, 쿼리, 구현 방법, 자료형 타입 등을 변경할 필요가 없다.
JPA 단점
- JPA의 장점을 살려 잘 사용하기 어려움
- 복잡한 쿼리를 사용할 때 불리
- 잘못 사용할 경우, 실제 SQL문을 직접 작성하는 것보다 성능이 떨어짐
Entity 클래스 생성
- 테이블 구조화 클래스
- @Setter는 없음
- Entity 클래스는 테이블 그 자체이기 때문에 각 컬럼에 대한 setter를 무작정 생성할 경우, 객체의 값이 어느 시점에 변경되었는지 알 수 없음
- @Getter
- 해당 클래스에 포함된 멤버 변수의 모든 getter 메서드를 생성
- @NoArgsConstructor(access = AccessLevel.PROTECTED)
- 해당 클래스의 기본 생성자를 생성
- access 속성을 이용하여 동일한 패키지 내의 클래스에서만 객체를 생성할 수 있도록 제어
- @Entity
- 해당 클래스가 테이블과 매핑되는 JPA의 엔티티 클래스임을 의미
- 기본적으로 클래스명을 테이블명으로 매핑
- ex) user_role → UserRole
- @Table
- 클래스명과 테이블명이 다를 수밖에 없는 상황에서 사용
- @Table(name = “user_role”)
- @Id
- 해당 멤버가 PK임을 의미
- 보통 MySQL DB는 PK를 bigint 타입으로, 엔티티(Entity)에서는 Long 타입으로 선언
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- PK 생성 전략을 설정
- MySQL은 자동 증가(AUTO_INCREMENT)를 지원하는 DB이며, PK 자동 증가를 지원하는 DB는 해당 어노테이션을 선언해야 함.
- 오라클과 같이 시퀀스(Sequence)를 이용하는 DB는 GenerationType.SEQUENCE를 이용
- GenerationType.AUTO로 설정하게 되면 DB에서 제공하는 PK 생성 전략을 가져가게 됨
- @Builder
- 생성자 대신 이용하는 패턴
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // PK
private String title; // 제목
private String content; // 내용
private String writer; // 작성자
private LocalDateTime createdDate = LocalDateTime.now(); // 생성일
@Builder
public Board(String title, String content, String writer) {
this.title = title;
this.content = content;
this.writer = writer;
}
}
JPA 레파지토리(Repository) 인터페이스 생성
- JpaRepository<T, ID> 인터페이스 상속
- T: 클래스명, ID: PK 데이터 타입
- ex) JpaRepository<Board, Long>
public interface BoardRepository extends JpaRepository<Board, Long> {
}
@Service
public class BoardService {
@Autowired
BoardRepository boardRepo;
public String findBoard(long id) {
Optional<Board> board = boardRepo.findById(id);
return board;
}
public List<User> findAllBoard() {
List<Board> board = boardRepo.findAll();
return board;
}
public void delete(long id) {
boardRepo.deleteById(id);
System.out.println("삭제 성공");
}
}
728x90