Programming-[Backend]/JPA

[JPA활용-1] 1. 프로젝트 생성 및 기초: .yml, @PersistenceContext, @Transactional, jar 빌드 등

컴퓨터 탐험가 찰리 2021. 11. 1. 20:26
728x90
반응형

 

 

 

활용편은 대부분 아는 내용이라, 차례대로 모두 정리하지 않고 새롭게 알게된 내용들만 일부 참조하여 작성한다.

 

 

devtools 라이브러리

 

gradle 라이브러리에 devtools 라이브러리를 import 한다.

 

build.gradle 파일

1
2
3
4
5
6
7
8
9
10
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-devtools'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'com.h2database:h2'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
cs

 

이렇게하면 템플릿엔진에서 참조하는 html 페이지 내용을 바꿨을 때, 서버를 재시작하지 않고 Build -> recompile [파일명] 으로 템플릿의 내용을 바로 변경 적용할 수 있다.

 

이외에도 캐시를 지우는 등 여러가지 기능들을 지원해준다고 한다.

 

 

 

 


 

설정하기

 

application.yml 과 application.properties의 차이점

원래 설정 파일은 application.properties를 사용하는데, 설정 내용이 많아지면 application.yml 파일이 더 편하다고 한다. 다음은 참조 2)의 yml의 장점이다.

눈에 띄는 점으로는 Pyhthon, Ruby등 다른 언어들도 YAML 설정 파일을 사용한다는 것과, 계층적인 구조를 사용한다는 것이다. 아무래도 가독성이 좋은 것 같다.

 

 

application.yml 예제, 설정 spec 확인

 

 

MVCC

dataSource의 MVCC=TRUE 옵션은 있으면 좋다고 한다. 참조 3)의 내용에 따르면,

MVCC는 Multi-Version Concurrency Control의 약어로, 동시에 실행되는 트랜잭션을 최대로 활용할 수 있도록 함과 동시에 데이터의 무결성이 유지되도록 도와준다고 한다.

-> 다만, h2의 1.4.198 버전부터는 MVCC 옵션을 넣으면 에러가 난다!

 

띄어쓰기, 오타

yaml 파일은 띄어쓰기 2칸을 기준으로 계층을 구분한다. IDE에서 자동으로 잡아주긴 하지만, 그래도 혹시 이 들여쓰기가 잘못되지 않도록 주의해야한다.

오타가 나도 안된다. 반드시 IDE가 잡아주는 자동완성 기능을 통해서 작성하자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
spring:
 datasource:
    url: jdbc:h2:tcp://localhost/~/jpashop;MVCC=TRUE
    username: sa
    password:
   driver-class-name: org.h2.Driver
 
  jpa:
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
#        show_sql: true
        format_sql: true
 
logging:
  level:
    org.hibernate.SQL: debug
cs

 

show_sql과 logging.level.org.hibernate.SQL: debug의 차이

SQL문을 콘솔창에 출력해주지만, show_sql의 경우 System.out을 기반으로 하고, logging.level.org.hibernate.SQL의 경우 spring 강의에서 들은 것처럼 logger를 이용하여 출력해준다. 따라서 logging.level.org.hibernate.SQL을 사용하는 것이 좋다.

 

 

설정 spec 확인

설정 spec이 뭔가 싶은데, 이 설정이 무엇인지 내용을 알고 싶다면 spring.io 사이트에서 springboot 공식 문서를 보고 배워야한다고 한다. 일단 뒤로 미뤄두자. 해당 페이지에서 예를 들어 spring.dataSource.url 등으로 검색하여 찾아들어가면 된다.

 

추가 설정 org.hibernate.type : trace

해당 어노테이션을 logging.level 아래에 추가하면, 쿼리파라미터의 정보도 표시해준다. 다만 이 정보는 실제로 DB와 통신할 때의 SQL에서만 보이므로, 아래에서 언급하는 내용과 같이 테스트 코드에서 @Rollback(false)를 해주어야 확인할 수 있다.


 

@PersistenceContext

 

@PersistenceContext 어노테이션은 스프링부트가 제공하는 기능으로, 이 어노테이션을 사용하면 앞서 배운 EntityManagerFactory, xml 설정 등을 따로 하지 않아도 된다. EntityManagerFactory(EMF)를 스프링부트가 하나 생성해서 관리해주고, 여기서 EntityManager(EM)를 꺼내서 전달해준다.

 

환경설정 파일에서 dependencies : 'org.springframework.boot:spring-boot-starter-data-jpa' 설정에 의해 사용이 가능하다. 실제 사용은 아래와 같이 사용한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Repository
public class MemberRepository {
 
  @PersistenceContext
  private EntityManager em;
 
  public Long save(Member member) {
    em.persist(member);
    return member.getId();
  }
 
  public Member find(Long id) {
    return em.find(Member.class, id);
  }
  
}
cs

 

커맨드와 쿼리를 분리

save 메서드에서 반환값을 저장된 Member 객체로 지정하는 것이 아니라, id 값만 반환했다. save 메서드는 DB에 값을 저장하는 기능을 하는 커맨드이다. 만약 객체를 반환한다면 저장된 Member 객체를 다시 불러와서 사용할 위험성이 있으므로 조회하는 곳에서 사용할 수 있도록 id값만 반환한다.

 

 


 

@Transactional :

EntityManager(PersistenceContext)를 이용한다면 반드시 Transaction를 거쳐야 한다

 

 

- @Transactional 어노테이션은 사용 코드의 메서드에 직접 달아도 되고, Test 코드의 메서드 위에 달아도 된다.

- @Transactional 어노테이션은 자바 표준 javax에서 지원하는 것이 있고, springframework에서 지원하는 것도 있는데, springframework에서 지원하는 것이 기능이 많다.

- @Transactional 어노테이션이 테스트 코드에 있으면, 테스트가 끝난 후 바로 롤백이 실행되어 DB에는 정보가 저장되지 않는다. 만약 롤백을 원하지 않는다면 @Rollback(false)를 넣어주면 된다.

 

 


 

Jar 파일 빌드하기 : CLI 방식-CMD

 

[window키 + R]을 눌러서 cmd를 실행시키고, 프로젝트가 있는 파일로 이동한다.

참고로 CMD의 명령어는 dir은 현재 위치의 디렉토리 목록, cd [디렉터리명] 은 해당 위치로 이동을 의미한다.

 

다음 명령어는 운영체제나 window마다 약간 다른 것 같은데, 내 경우에는 gradlew clean build 라는 명령어는 잘 작동했다. 이렇게 하면 gradle에 남아있는 build 정보를 clean 하고 새롭게 build한다.

 

빌드 시 포함되어있는 테스트를 진행하고 jar 파일을 생성한다.

 

완성된 jar 파일은 build/libs 위치에 생성되어있다.

 

jar 파일을 로컬로 실행하는 방법은 java -jar [파일이름] 명령어를 입력하는 것이다. 실행 후 localhost:8080 위치에 들어가보면 서버가 성공적으로 실행되는 것을 확인할 수 있다.

 

서버를 종료할 땐 [Ctrl + C]를 눌러주면 된다.

 


 

쿼리파라미터 편하게 보기 : spring-boot-datasource-decorator

 

쿼리 파라미터는 SQL문 상에서 ?로 표시되는데, 위에서 org.hibernate.type 정보를 설정해주는 방법을 배웠지만, 라이브러리를 이용할 수도 있다. 아래 사이트에 들어가보면, 라이브러리를 import하는 코드를 제공해준다.

 

https://github.com/gavlyukovskiy/spring-boot-data-source-decorator

 

 

아래 코드를 build.gradle에 추가한다. 이 글을 작성하는 시점의 version은 1.7.1 이므로 이 값을 ${version} 부분에 넣어준다.

implementation("com.github.gavlyukovskiy:p6spy-spring-boot-starter:${version}")

 

참고로, 해당 라이브러리는 버전값을 직접 넣지만, jpa, lombok, h2등의 버전을 명기하지 않는 것은 스프링부트가 잘 사용하는 기본 라이브러리들은 자신의 버전에 맞는 라이브러리의 버전들을 자동으로 지정해주기 때문이라고 한다.

 

gradle을 refresh하고 테스트 코드를 실행해보면, 쿼리파라미터가 잘 출력되는 것을 확인할 수 있다. 다만 실제 DB에 정보가 들어가는 SQL문이 생성되어야 확인이 가능하므로, @Rollback(false)를 넣어줘야 한다.

 


 

참조

 

1. 인프런_실전! 스프링 부트와 JPA 활용1_김영한 님 강의

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/dashboard

 

2. GeekForGeeks 사이트

https://www.geeksforgeeks.org/difference-between-yaml-yml-and-properties-file-in-java-springboot/

 

3. 개발자입니까? 블로그

https://devvkkid.tistory.com/213

728x90
반응형