이 포스팅에서는 스프링부트와 JPA를 연동하는 실습 과정을 담았습니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--테스트용 인메모리 DB-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
h2
는 인메모리
기반으로 경량 DB로 테스트용
, 캐시용
으로 자주 사용됩니다.
h2
는 데이터베이스에 접근할 수 있는 웹 인터페이스를 제공합니다.
h2
를 사용하기 위해서는 spring-boot-devtools
의존성 추가가 필요합니다.
어플리케이션을 실행하고 http://localhost:8080/h2-console 에 접속하면 콘솔을 확인할 수 있습니다.
참고로 스프링부트 최신버전을 사용하고 있다면, JDBC URL을 jdbc:h2:mem:testdb
로 바꾸시고 연결하시길 바랍니다.
콘솔 주소는 application.properties
파일에서 변경할 수 있습니다:
spring.h2.console.path=/db-console
DB 내용은 어플리케이션이 시작할때마다 초기화됩니다.
자세한 내용은 여기서 확인 하시면 되겠습니다.
참고로 Lombok을 사용했습니다.
매번 DB에 insert
, update
할 때마다, 날짜 데이터를 등록 수정하기 힘듭니다. 그래서 저희는 JPA Auditing을 사용합니다.
사용 방법은
1. Entity 클래스들의 상위 클래스 작성(우리 프로젝트에선 BaseTimeEntity)
2. Entity 클래스에서 상속
3. @EnableJpaAuditing 활성화
이 순으로 됩니다.
그럼 먼저, 상위 클래스인 BaseTimeEntity를 작성해봅시다.
package com.corini.springbootjpa;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {
@CreatedDate
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime modifiedDate;
}
그 다음엔 Entity 클래스에서 상속을 받습니다.
package com.corini.springbootjpa.account;
import com.corini.springbootjpa.BaseTimeEntity;
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Getter
@Setter
@ToString
public class Account extends BaseTimeEntity{
@Id @GeneratedValue
private Long id;
private String username;
private String password;
@Builder
public Account(String username, String password) {
this.username = username;
this.password = password;
}
}
마지막으로 SpringBootApplication 클래스에서 Auditing을 활성화 합니다.
package com.corini.springbootjpa;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@EnableJpaAuditing
@SpringBootApplication
public class SpringbootJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootJpaApplication.class, args);
}
}
Entity 클래스 관련 어노테이션 정리
package com.corini.springbootjpa.account;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AccountRepository extends JpaRepository<Account, Long> {
}
JpaRepository<Entity클래스, PK타입>
를 상속하면 기본적인 CRUD 메소드가 자동생성 됩니다.
@Repository
어노테이션을 추가할 필요가 없습니다.
mac
+ intellij
사용 중이시면 AccountRepository 인터페이스 명에 커서를 갖다놓고 command
+ shift
+ T
단축키를 누르면 테스트 코드를 위한 클래스를 자동으로 생성할 수 있습니다.
package com.corini.springbootjpa.account;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@AllArgsConstructor
public class AccountController {
private AccountRepository accountRepository;
@GetMapping(value = "/")
public String hello() {
return "hello world";
}
@GetMapping(value = "/create")
public Object create() {
Account account = new Account();
account.setUsername("admin");
account.setPassword("test");
accountRepository.save(Account.builder()
.username("admin")
.password("test")
.build());
return accountRepository.findAll();
}
@GetMapping(value = "/read")
public Object read() {
return accountRepository.findAll();
}
@GetMapping(value = "/delete")
public Object delete() {
accountRepository.deleteAll();
return "delete";
}
}
@AllArgsConstructor
어노테이션을 사용하여, 생성자를 생성합니다. 코드로 보시면 이해 되실 겁니다.
@RestController
public class AccountController {
private AccountRepository accountRepository;
public AccountController(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
...
}
이렇게 하는 이유는 스프링프레임워크에서 Bean 주입 방식 중 권장하는 방법입니다. 다른 방법으로는...
http://localhost:8080/create
url을 호출하면 Account 테이블의 username
컬럼에는 admin
데이터가 password
컬럼에는 test
데이터가 들어갑니다.
위에 정의한대로 /read
url은 전체 데이터 조회를 /delete
url은 전체 데이터 삭제를 합니다.
테스트 코드를 짜시고 본 프로젝트에 적용하는 걸 추천합니다... 저는 간단한 코드라 그냥 짰지만... ㅠㅠ
jojoldu님 블로그 와 @junwoo4690님 벨로그 포스팅 참조하시면 테스트 코드 작성 방법 자세히 나와 있습니다!
간단하게나마 인메모리 기반 데이터베이스를 h2
를 이용하여, JPA를 사용해봤습니다!
맛보기로 해봤지만, 넘나 편리한거 같습니다...
퇴사했던 회사에서는 springMVC
+ JDBC
+ Mybatis
+ MSSQL
사용했었는데... 비즈니스 로직 짜는거 보다 설정이나 이외의 것들 코딩하느라 시간이 엄청 오래 걸렸었는데... spring boot
+ JPA
조합은 정말 신세계네요..
저의 소스는 Github에서 확인 하실 수 있습니다!!!