https://start.spring.io/
스프링 프로젝트를 처음 생성하면 기본적으로, application.properties라는 SpringBoot의 설정 파일을 제공한다. 이 설정 파일은 다양한 형식을 제공하는데 그 중에서 가독성이 높고 권장하는 형식인 yml로 살정해보려한다.
기본으로 생성된 application.properties를 지우고 그 위치에 application.yml 파일을 생성하면 된다.
- 위와 같은 형태로 환경 설정을 하게 되는데, 이는 들여쓰기 형식으로 작성되기 때문에 가독성이 높다.
- 또한, 반복되는 suffix에 대한 작성을 막아준다.
위의 yml형식의 파일을 properties로 작성하게되면
spring.datasource.url=jdbc:h2:tcp://localhost/~/jpashop
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
- 가독성이 떨어질 뿐만 아니라, spring.datasource라는 suffix가 중복되어 작성되야한다는 단점이 존재한다.
또한 만약 여러개의 설정 파일이 필요하다면 properties를 사용할 때에는 여러개의 파일을 만들어야하지만 yml형식을 사용하게 되면 하나의 파일 내부에서 여러 파일을 사용하는 것 처럼 작성할 수 있다.
구분자 ---을 사용하여
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/jpashop
username: sa
password:
driver-class-name: org.h2.Driver
---
spring:
datasource:
url: jdbc:mysql:tcp://localhost/~/jpashop
username: hi
password:
driver-class-name: org.mysql.Driver
참고로 우선순위가 궁금하여 spring 공식 문서를 찾아보았는데,
It is recommended to stick with one format for your entire application. If you have configuration files with both .properties and .yml format in the same location, .properties takes precedence.
동일한 경로에 .properties와 .yml 형식의 파일이 존재하면 .properties형식이 상위의 우선순위를 가진다고한다.
설정에 대한 정보는 spring 공식 문서를 참조하자.(항상 공식 docs를 보는 습관을 들이자!)
JPA와 DB의 동작확인을 위해 간단한 회원, 회원 저장소 엔티티를 만들고 테스트해보자.
@Entity
테이블과 매핑되는 클래스임을 나타내는 애노테이션.
@Id, @GeneratedValue
@Id가 붙으면 테이블의 PK임을 지칭한다.
@GeneratedValue는 PK생성 규칙을 뜻하는 것으로, auto incresement를 뜻한다.
즉, 해당 Member 클래스와 매핑되는 member 테이블은 PK칼럼인 id와, username 칼럼을 가지는 테이블이다.
em.find(); // 엔티티 조회
em.persist(); // 엔티티 저장
em.remove(); // 엔티티 삭제
em.flush(); // 영속성 컨텍스트 내용을 데이터베이스에 반영
em.detach(); // 엔티티를 준영속 상태로 전환
em.merge(); // 준영속 상태의 엔티티를 영속상태로 변경
em.clear(); // 영속성 컨텍스트 초기화
em.close(); // 영속성 컨텍스트 종료
- JPA를 사용하게 되면 애플리케이션과 데이터베이스 사이에 영속성 컨텍스트(Persistence Context)를 두고 데이터를 관리한다.
- 이를 관리하는 것이 바로 Entity Manager이다.
- @PersistenceContext 애노테이션을 사용해 Entity Manager를 주입받아 사용하면 된다.
Entity Manager에 대한 공식 문서를 참조하자.
https://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html_single/#d0e46
JPA관련 애노테이션은 아래에서 확인할 수 있다.
http://www.techferry.com/articles/hibernate-jpa-annotations.html
@SpringBootTest
실제 스프링 프레임워크를 띄워서 테스트하는 것으로, 이를 통해 @Autowired로 스프링 빈을 주입받을 수 있다.
@Transactional
스프링에서는 트랜잭션 처리를 지원하는데 그중 어노테이션 방식으로 @Transactional을 선언하여 사용하는 방법이 일반적이며, 선언적 트랜잭션이라 부른다.
클래스, 메서드위에 @Transactional 이 추가되면, 이 클래스에 트랜잭션 기능이 적용된 프록시 객체가 생성된다.
이 프록시 객체는 @Transactional이 포함된 메소드가 호출 될 경우, PlatformTransactionManager를 사용하여 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback 한다. 오류가 발생했을 시 자동으로 Rollback을 실행한다.
만약 테스트코드에서 해당 애노테이션이 사용되면 테스트 수행후 Rollback을 실행시켜준다.
당연한 소리지만, 테스트 코드가 실제 DB에 반영되어선 안되기 때문이다.(반복적인 테스트도 불가능)
이는 @Rollback(false)를 통해 자동 Rollback을 해제하고 테스트가 실제 DB에 반영된 결과를 확인할 수도 있다.
로그를 살펴보자.
application.yml 파일에서 설정한 ddl-auto: create 속성을 통해 실행될 때 기존에 있던 엔티티를 drop하고 새로 테이블을 생성한다. 그 후 테스트 코드대로 새로운 Member객체를 만들어 테이블에 넣고
이를 id로 조회하여 테스트를 진행한다. 조회된 두 객체를 isEqualTo로 비교해보면 같다는 것을 확인할 수 있는데, 이는 영속성 때문에 JPA 엔티티가 항상 같은 결과를 반환하기 때문이다.
- 동일성(==)보장: 조회시 항상 같은 엔티티 인스턴스를 리턴(주소값이 같음)
실제로 localhost:8082로 접속하여 h2 데이터베이스를 직접 확인해보면
테이블이 만들어져 있는 것을 볼 수 있다.
반응형
'Spring > SpringBoot_JPA' 카테고리의 다른 글
API 개발 기본 (0) | 2021.05.26 |
---|---|
변경 감지와 병합(merge) (0) | 2021.05.24 |
테스트 예외처리 (0) | 2021.05.20 |
엔티티 설계 주의점 (0) | 2021.05.18 |
도메인 모델, 테이블 설계 (0) | 2021.05.17 |