이번에는 JPA를 실제 Spring Boot에서 사용하는 방법에 대해서 적어보려고 한다.
프로그램을 간단하게 요약하자면, 회원을 등록, 삭제, 검색, 추가할 수 있는 일련의 기능을 구현 중에 있다고 가정하고
현재, Service로 부터 Repository에 DTO가 넘어왔음을 가정한다.
다음과 같이 초기 Memeber를 관리하는 DAO가 있다고 가정하자.
@Repository("Member")
public class MemberJpaStore implements MemberStore{
// Member DB에 Create
@Override
public String create(Member member) {
}
// Member DB에서 아이디로 검색
@Override
public Member retrieve(String memberId) {
}
// Member DB에서 이름으로 검색
@Override
public List<Member> retrieveByName(String name) {
}
// Member DB에서 전체 멤버 검색
@Override
public List<Member> retrieveAll() {
}
// Member DB에서 해당 멤버 수정
@Override
public void update(Member member) {
}
// Member DB에서 아이디로 해당 멤버 삭제
@Override
public void delete(String memberId) {
}
}
여기서 이제 해야할 것은 메서드의 인자로 들어온 다양한 객체 또는 프로퍼티를 활용해, 실제 DB에 검색하고 삭제하고 수정하고 등록해야한다는 것이다.
생각을 해보면 과정은 다음의 두가지 경우 중 하나이다.
JPA
1. DTO->Entity로 변경
2. Entity를 SQL문과 매핑
3. DB에 전송후 결과 받아옴
4. 결과 Enitty를 다시 DTO로 변경
5. 결과 사용
MyBatis
1. DTO에서 필요한 내용 정돈(ID로 검색시 ID를 따로 만드는 과정 등)
2 SQL문 작성
3. DTO와 SQL 매핑 후 결과 받아옴
4. 결과 사용
각각의 장단점이 있고 이는 앞선 블로그에서 다뤘으니 생략한다.
이번에는 JPA에서 다뤄보려고 한다. ORM-JPA-Hibernate-Spring Data JPA를 보통 묶어서 표현을 하곤 하는데,
ORM-JPA-Hibernate는 묶어서 생각하고 이 묶음의 기능들 중 자주 사용하는 것을 Spring Data JPA가 제공해준다고 생각하면 된다.
1. Dependancy 설정.
JPA를 사용하기에 앞서, 관련된 라이브러리들을 설치해야 한다.
Spring Data JPA 관련 라이브러리와 관련 DB들을 설치해야하는데, 나는 Oracle을 적용했다. 또한 DB서버는 Cloud 환경이 아닌 local로 진행했다.
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- oracle -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<scope>runtime</scope>
</dependency>
2. Config 설정
이제 DB사용 관련, JPA 사용 관련해서 설정들을 해줘야 한다.
주석으로 설명했으니 참고하면 좋을 것 같다.
# Server 설정, 포트번호 : 8090
server.port=8090
server.servlet.session.timeout=360000
# Oracle Config, 해당 프로그램과 Oracle DB를 연결해준다.
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
# JPA Config
# 쿼리가 만들어지면 쿼리내용을 콘솔로 확인
spring.jpa.show-sql=true
# 쿼리 정돈해서 확인 가능
spring.jpa.properties.hibernate.format_sql=true
# Entity를 Oracle 쿼리형태로 바꿔주는 역할
spring.jpa.database=oracle
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
# 데이터베이스 스키마(테이블) 생성
# create, create-drop, update, validate, none 등 가능
spring.jpa.hibernate.ddl-auto=create
spring.jpa.generate-ddl=false
# 콘솔에 출력가능한 hiberate 최소 레벨
logging.level.org.hibernate=info
위의 내용을 좀 더 자세히 보면 다음과 같다.
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
- DAO클래스에서 Entity 생성 시 이를 Oracle 쿼리에 맞춰 변경해주는 역할
spring.jpa.hibernate.ddl-auto=create
- create: 기존테이블 삭제 후 다시 생성
- create-drop: create와 같지만 종료시점에 테이블 삭제
- update: 변경만 반영
- validate: 엔티티와 테이블이 정상 매핑되었는지만 확인
- none: 사용하지 않음
spring.jpa.generate-ddl=false
- 서버 시작 시점에 DDL문을 생성할지 말지 결정
이를 통해, 알 수 있는 것은 JPA는 테이블을 생성해주고 Entity를 DB의 쿼리에 매핑을 해주는 것을 알 수 있다.
이것을 통해 우리는 DTO를 Entity로 만드는 작서을 하고 어떤 SQL처리를 할지 명시를 해주면 되는 것이다.
그럼, JPA에서 테이블 생성, 해당 처리, 사용하는 DB에 맞는 쿼리문을 매핑해 줄 것이다.
3. Entity 생성
DTO를 Entity로 바꿔주고, 또 다시 Entity를 DTO로 바꿔주는 작업이 필요하다.
@Entity // Entity 클래스임을 명시
@Getter
@Setter
@NoArgsConstructor
@Table(name="Member") // 테이블 생성시 테이블 이름 설정
public class MemebrJpo {
@Id // 식별자, key 정의
private String id;
private Int pwd;
private String name;
private long foundationTime;
// DTO를 Entity로 변환
public MemberJpo(Member member) {
// DTO의 프로퍼티들을 Entity의 프로퍼티들로 매핑
BeanUtils.copyProperties(member, this);
}
// Entity를 다시 DTO로 변환
public Member toDomain() {
Member member = new Member(this.id, this.pwd);
member.setName(this.name);
member.setFoundationTime(this.foundationTime);
return member;
}
}
@Entity : 현재 클래스가 Entity 클래스 임을 명시
@Table : 현재 클래스가 테이블이며, 테이블 이름도 지정 가능.
@Id : Entity의 식별자를 명시.
4. Spring JPA 인터페이스 생성
이제 스프링 JPA 인터페이스를 생성해 해당 인터페이스에서 제공해주는 메서드(SQL 매핑)를 사용하려고 한다.
Hibernate에서 기본적으로 제공을 해주지만 Spring JPA는 Hibernate관련된 문법이나 메서드명을 몰라도 기본적으로 자주 쓰이는 기능들을 모아 Spring JPA Interface를 통해 제공해준다고 생각하면 된다.
// JpaRepository 상속 -> Spring JPA에서 제공해주는 기본 CRUD 기능 등을 사용 가능
public interface MemberRepository extends JpaRepository<MemberJpo, String>{
}
다음과 같이 인터페이스를 만들어 JpaRepository를 상속받는다. 이때, <Entity클래스 명, Entity 식별자의 타입명>로 작성해주면 된다.
5. DAO 클래스에 적용
이제 실질적으로 적용해보려고 한다. 과정은 다음과 같다.
- 1. Repository 클래스(JpaRepository를 상속받은)를 DAO에 주입
- 2. DAO에 전달받은 DTO를 Entity로 변경
- 3. Repository의 메서드를 통해서 생성한 Entity를 SQL문에 매핑
간단하게 memberRepository 즉, JpaRepository의 메서드를 조금 보면 다음과 같다. 기본적인 것이고 아주 많다.
- save(Entity) -> Table에 해당 Entity 검색 후, 없으면 생성, 있으면 수정한다.
- findById(Id) -> Id로 검색
- findAll() -> Table에 전체 내용 검색
- deleteById(Id) -> Id로 삭제
@Repository("Member")
public class MemberJpaStore implements MemberStore{
private MemberRepository memberRepository;
public MemberJpaStore(MemberRepository memberRepository){
this.memberRepository = memberRepository;
}
// Member DB에 Create
@Override
public String create(Member member) {
memberRepository.save(new MemberJpo(member);
return club.getId();
}
// Member DB에서 아이디로 검색
@Override
public Member retrieve(String memberId) {
}
// Member DB에서 이름으로 검색
@Override
public List<Member> retrieveByName(String name) {
}
// Member DB에서 전체 멤버 검색
@Override
public List<Member> retrieveAll() {
}
// Member DB에서 해당 멤버 수정
@Override
public void update(Member member) {
}
// Member DB에서 아이디로 해당 멤버 삭제
@Override
public void delete(String memberId) {
}
}
'Server Development > Data API' 카테고리의 다른 글
JPA - @Query with Spring JPA (0) | 2023.04.05 |
---|---|
JPA - Query Method with Spring JPA (0) | 2023.04.05 |
JPA - Auditing (0) | 2023.04.04 |
JPA - EntityManager, EntityMapping, Context (0) | 2023.04.04 |
Data API - Basic Concept (0) | 2023.03.28 |