[Spring Boot] MySQL & JPA 연동 및 테스트 (Gradle 프로젝트)
by coco3oSpringBoot에서 MySQL 그리고 Spring Data JPA를 연동하는 방법에 대해 알아보도록 하겠습니다.
1. 프로젝트에 의존성 추가하기
build.gradle에 의존성을 아래와 같이 추가해줍니다.
dependencies {
implementation 'mysql:mysql-connector-j'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}
2. application.properties 에 DB 정보 추가하기
# MySQL 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# DB Source URL
spring.datasource.url=jdbc:mysql://<IP>:<Port>/<DB>?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul
# DB username
spring.datasource.username=<username>
# DB password
spring.datasource.password=<password>
# true 설정시 JPA 쿼리문 확인 가능
spring.jpa.show-sql=true
# DDL(create, alter, drop) 정의시 DB의 고유 기능을 사용할 수 있다.
spring.jpa.hibernate.ddl-auto=update
# JPA의 구현체인 Hibernate가 동작하면서 발생한 SQL의 가독성을 높여준다.
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=[ ]
- create : 기존 테이블을 삭제하고 새로 생성 [ DROP + CREATE ]
- create-drop : CREATE 속성에 추가로 어플리케이션을 종료할 때 생성한 DDL을 제거 [ DROP + CREATE + DROP ]
- update : DB 테이블과 엔티티 매핑 정보를 비교해서 변경 사항만 수정 [ 테이블이 없을 경우 CREATE ]
- validate : DB 테이블과 엔티티 매핑정보를 비교해서 차이가 있으면 경고를 남기고 어플리케이션을 실행하지 않음
- none : 자동 생성 기능을 사용하지 않음
[ 정보 추가 예시 ]
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/bootex?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul
spring.datasource.username=test_user
spring.datasource.password=1234
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
아래와 같이 정상적으로 실행되는 것을 볼 수 있습니다.
3. JPA Hibernate 엔티티(Entity) 생성하기
자세한 Entity 매핑 설명은 참고
@ToString
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tbl_memo")
@Entity
public class Memo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) //MySQL의 AUTO_INCREMENT를 사용
private Long id;
@Column(length = 200, nullable = false)
private String memoText;
}
사용 어노테이션 정리
- @Entity : DB의 테이블을 뜻함 [ Spring Data JPA 에서는 반드시 @Entity 어노테이션을 추가해야 함 ]
- @Table : DB 테이블의 이름을 명시 [ 테이블 명과 클래스 명이 동일한 경우 생략 가능 ]
- @Getter : Lombok의 Getter를 이용해 Getter 메소드를 생성하고 @Builder 를 이용해서 객체를 생성할 수 있게 처리한다.
- @Builder를 이용하기 위해 @AllArgsConstructor 와 @NoArgsConstructor 를 같이 처리해야 컴파일 에러가 발생하지 않음
- @Id : Primary Key를 뜻함
- @GeneratedValue : Primary Key의 키 생성 전략(Strategy)을 설정하고자 할 때 사용
- GenerationType.IDENTITY : MySQL의 AUTO_INCREMENT 방식을 이용
- GenerationType.AUTO(default) : JPA 구현체(Hibernate)가 생성 방식을 결정
- GenerationType.SEQUENCE : DB의 SEQUENCE를 이용해서 키를 생성. @SequenceGenerator와 같이 사용
- GenerationType.TABLE : 키 생성 전용 테이블을 생성해서 키 생성. @TableGenerator와 함께 사용
- @Column : DB Column을 명시
- @Column과 반대로 테이블에 컬럼으로 생성되지 않는 필드의 경우엔 @Transient 어노테이션을 적용한다.
Memo 클래스 실행
위와 같이 테이블 생성에 필요한 SQL이 기록되는 것을 확인할 수 있습니다.
DB에 생성된 테이블의 모습입니다.
4. JPA Repository 생성
Spring Data JPA는 JPA의 구현체인 Hibernate를 이용하기 위한 여러 API를 제공합니다.
그 중에서 가장 많이 사용되는 것이 바로 JPA Repository라는 인터페이스 입니다.
public interface MemoRepository extends JpaRepository<Memo, Long> {
}
작성된 MemoRepository는 JpaRepository를 상속하는 것만으로 모든 작업이 끝납니다.
- MemoRepository를 이용해서 작성된 테이블에 SQL문 없이 CRUD 작업을 할 수 있게 됩니다.
- JpaRepository의 제네릭 타입으로는 <Entity, PK의 타입>을 지정해주면 Spring Data JPA는 자동으로 스프링의 빈(bean)으로 등록됩니다.
- [ 스프링이 내부적으로 인터페이스 타입에 맞는 객체를 생성해서 빈으로 등록 ]
5. 테스트를 통한 CRUD 기능 확인
5.1 Create 테스트
Insert를 할 때 Repository 객체의 save() 메소드를 사용합니다.
@SpringBootTest
public class MemoRepositoryTest {
@Autowired
MemoRepository memoRepository;
@Test
public void InsertDummies() {
IntStream.rangeClosed(1, 10).forEach(i -> {
Memo memo = Memo.builder()
.memoText("Sample..." + i)
.build();
//Create!
memoRepository.save(memo);
});
}
10개의 새로운 Memo 객체를 생성하고 MemoRepository를 이용해서 insert하는 것입니다.
5.2 Read 테스트
Select를 할 때 Repository 객체의 findById() 메소드를 사용합니다.
findById()를 통해 기본키를 넣어주면, 해당하는 객체를 Optional 타입으로 반환해줍니다.
@SpringBootTest
public class MemoRepositoryTest {
@Autowired
MemoRepository memoRepository;
@Test
public void SelectDummies() {
Long id = 10L;
Optional<Memo> result = memoRepository.findById(id);
System.out.println("=============================");
if(result.isPresent()) {
Memo memo = result.get();
System.out.println(memo);
}
}
}
findbyId()의 경우 Optional 타입으로 반환되기 때문에 한번 더 결과가 존재하는지를 체크하는 형태로 작성하게 됩니다.
5.3 Update 테스트
수정 작업과 등록작업은 동일하게 save()를 이용해서 처리합니다.
내부적으로 해당 엔티티의 @Id값이 일치하는지를 확인해서 insert 혹은 update 작업을 처리합니다.
@SpringBootTest
public class MemoRepositoryTest {
@Autowired
MemoRepository memoRepository;
@Test
public void UpdateDummies() {
Memo memo = Memo.builder()
.id(10L)
.memoText("Update Text")
.build();
memoRepository.save(memo);
}
JPA는 엔티티 객체들을 메모리상에 보관하려고 하기 때문에 특정한 엔티티 객체가 존재하는지 확인하는 select가 먼저 실행되고
해당 @Id를 가진 엔티티 객체가 있다면 update, 그렇지 않다면 insert를 실행하게 됩니다.
5.4 Delete 테스트
삭제 작업도 수정 작업과 동일한 개념으로 삭제하려는 엔티티 객체가 있는지 먼저 확인하고, 삭제합니다.
@SpringBootTest
public class MemoRepositoryTest {
@Autowired
MemoRepository memoRepository;
@Test
public void DeleteDummies() {
Long id = 10L;
memoRepository.deleteById(id);
}
'🌈Programming > Spring Boot' 카테고리의 다른 글
[Spring Boot] @Scheduled을 이용해 일정 시간 마다 코드 실행하기 (1) | 2022.06.26 |
---|---|
[Spring Boot] Validation 적용, @Valid로 유효성 검사하기 (1) | 2021.12.17 |
[Spring Boot] Gradle jar 빌드 및 배포하기 (2) | 2021.06.28 |
[Spring Boot] 프로젝트 구조 살펴보기 (0) | 2021.06.28 |
[Spring Boot] intelliJ로 Spring Boot 프로젝트 생성 및 실행하기 (0) | 2021.06.28 |
블로그의 정보
슬기로운 개발생활
coco3o