스프링데이터 + JPA/웹 애플리케이션 개발

4. DB(H2) 설치 및 설정

sdafdq 2023. 11. 4. 17:56

이거 버전 맞춰서 설치 해야 함.

https://qwefdg3.tistory.com/698

 

여기 참조.

 

그리고 이제 설정인데..

 

application.properties 쓰다가 application.yml로 쓰신다고 하신다.

뭐 종속성 많아지면 그게 더 편하다고..

하긴 뭐랄까 뭐에 대한 설정인지 들여쓰기로 나눠져 있어서 보기 편하긴 하다.

 

spring:
  datasource:
    url: jdbc:h2:tcp://localhost/./jpashop
    username: sa
    password: 1234
    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

요렇게, 

크게는 spring에 대한 설정, logging에 대한 설정.

 

datasource는 url, username, password 설정 해 주고, driver-class-name 해서 어떤 DB인지 알려주고,

 

jpa에서 ddl-auto모드,

또 하이버네이트 속성에서 show_sql, format_sql 설정했다가, show_sql은 주석처리 했는데,

저기 logging에 level을 하이버네이트 sql은 debug, 그러니까 굉장히 깊은 레벨까지 로그를 보여주는 거임.

 

저 logging은 log 쓰는거고 저 show_sql은 soutv 쓰는거라, logging이 훨씬 효율적이라고 함.

format_sql은 sql포맷 말하는 거겠고.

 

저렇게 해 두긴 했는데..

이게 yml은 조심해야 할 게 있다.

spring: #띄어쓰기 없음
 	datasource: #띄어쓰기 2칸
 		url: jdbc:h2:tcp://localhost/~/jpashop #4칸
 		username: sa
 		password:
 	driver-class-name: org.h2.Driver
 	jpa: #띄어쓰기 2칸
 		hibernate: #띄어쓰기 4칸
 			ddl-auto: create #띄어쓰기 6칸
 		properties: #띄어쓰기 4칸
			hibernate: #띄어쓰기 6칸
 			format_sql: true #띄어쓰기 8칸
            
logging.level: #띄어쓰기 없음
 	org.hibernate.SQL: debug #띄어쓰기 2칸
# org.hibernate.type: trace #띄어쓰기 2칸

띄어 쓰기..

뭐 띄어쓰기 2칸으로 계층을 만든다고 하는데.. 왜 8칸 저러는 거지?

 

여튼..

 

@Entity
@Getter @Setter
public class Member {
    @Id @GeneratedValue
    private Long id;

    String username;
}

엔티티 만듦.

 

 

@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);
    }
}

리포지토리 만듦.

 

@PersistenceContext 직역은 영속성 컨텍스트.. 그거 인데 영속성 컨텍스트 관리해주는 그거 지정하는 애노테이션 인 듯

 

저렇게 하면 알아서 Spring boot jpa에서 넣어주나 봄.

 

save에서 return을 member가 아니라 id를 주는데,

트랜잭션 때문인 거 같긴 함. 

https://www.inflearn.com/questions/1066208

 

커맨드성 - 인프런 | 질문 & 답변

[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]선생님들.8:20 이

www.inflearn.com

질문해 봤음.

뭐 쿼리성이랑 커맨드성이랑 구분한다고 하시는 데, 쿼리는 바로 날려버리지만 커맨드성은 영속성 컨텍스트에 있다가 마지막에 commit 하니까 그거의 사이드 이펙트 때문에 그런가?

 

이제 테스트

@SpringBootTest
class MemberRepositoryTest {

    @Autowired MemberRepository memberRepository;

    @Test
    @Transactional
    @Rollback(false)
    public void testMember(){
        Member member = new Member();
        member.setUsername("memberA");
        Long savedId = memberRepository.save(member);

        Member findedMember = memberRepository.find(savedId);

        assertThat(savedId).isEqualTo(findedMember.getId());
        assertThat(member.getUsername()).isEqualTo(findedMember.getUsername());
        assertThat(member).isEqualTo(findedMember);
    }
}

엔티티를 통한 모든 데이터 변경은 항상 트랜잭션 안에서 이루어 져야 하므로 @Transactional

근데 Test에서의 @Transactional은 추가 기능이 있는데,

테스트 이후 모든 것을 rollback 해주는 기능.

이래야 반복적인 테스트가 가능하니까.

근데 나는 맨 처음에 한번 테스트는 제대로 DB안에 들어가는지 보고 싶어서

@Rollback(false) 

했다.

 

여기서 좀 신기한 건 member랑 isEqualTo 해서 findedMember랑 해도 맞는 것.

 

이거는 같은 영속성 컨텍스트이기 때문에 같은 주소임.

 

 

다음 jar 빌드해서 동작 확인.

그러니까.. 실제로 빌드해서 서버에 넣고,

터미널에서 실행하면 실제로 서버가 켜 지는 거임.

 

cmd에서는 안돼니 파워셀로 해봄

./gradlew clean build

이러면 이제 전꺼는 깔끔하게 지웠다가 빌드.

 

이제 build > libs 로 들어가,

프로젝트명-버전-SNAPSHOT.jar 이렇게 jar 파일이 만들어 진다.

 

그러면 이제 java -jar jpashop-0.0.1-SNAPSHOT.jar 이렇게 실행 하면

 

그게 서버 실행하는 거다.

 

 

배포할 때 이렇게 하면 된다.

 

./gradlew clean build 해서

build > libs로 들어가서 jar파일 서버에 올린다음에,

java -jar 그파일명.jar

해서 실행 시켜 놓으면,

 

서버 켜놓은 거다.

 

실제로 된다. 

처음엔 로딩 길더니 그 이후엔 꽤 빠르게 된다.

터미널 꺼버리니까 꺼짐

 

 

 

자 그리고, 쿼리 파라미터 뭔지 남길 수 있다.

지금까지 파라미터 그냥 

insert 
into
    member
    (username,id) 
values
    (?,?)

이렇게 ?로 나오는 데,

 

이걸 지원해주는 라이브러리가 있다.

 

물론

logging:
  level:
    org.hibernate.SQL: debug
    org.hibernate.orm.jdbc.bind: trace

이렇게 까지 옵션 주면 타입 찍어준다고

 

2023-11-04T17:46:52.165+09:00 TRACE 22868 --- [    Test worker] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [VARCHAR] - [memberA]
2023-11-04T17:46:52.166+09:00 TRACE 22868 --- [    Test worker] org.hibernate.orm.jdbc.bind              : binding parameter [2] as [BIGINT] - [1]

이렇게 찍어준다.

 

그래도

 

더 깔끔하게 보고 싶다.

외부 라이브러리 중에 p6spy 라는 게 있다.

implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'

 

이렇게 해서 받아오고,

 

그냥 아무것도 안건드렸는데도 실행 하면

 

2023-11-04T17:52:05.030+09:00 DEBUG 5616 --- [    Test worker] org.hibernate.SQL                        : 
    insert 
    into
        member
        (username,id) 
    values
        (?,?)
2023-11-04T17:52:05.033+09:00 TRACE 5616 --- [    Test worker] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [VARCHAR] - [memberA]
2023-11-04T17:52:05.033+09:00 TRACE 5616 --- [    Test worker] org.hibernate.orm.jdbc.bind              : binding parameter [2] as [BIGINT] - [1]
2023-11-04T17:52:05.034+09:00  INFO 5616 --- [    Test worker] p6spy                                    : #1699087925034 | took 0ms | statement | connection 4| url jdbc:h2:tcp://localhost/./jpashop
insert into member (username,id) values (?,?)
insert into member (username,id) values ('memberA',1);
2023-11-04T17:52:05.036+09:00  INFO 5616 --- [    Test worker] p6spy                                    : #1699087925036 | took 0ms | commit | connection 4| url jdbc:h2:tcp://localhost/./jpashop

이렇게 로그를 남긴다.

 

 

요런 라이브러리는 개발단계에서만 쓰고, 배포할 땐 빼는걸로..

뭐 남겨놓고 싶으면 성능테스트 해 보고 괜찮으면 하셈.

 

 

'스프링데이터 + JPA > 웹 애플리케이션 개발' 카테고리의 다른 글

6. 도메인 모델과 테이블 설계  (0) 2023.11.04
5. 요구사항 분석  (0) 2023.11.04
3. 뷰 환경설정  (0) 2023.11.04
2. 프로젝트 환경 설정  (0) 2023.11.04
1. 스프링 부트 + JPA  (0) 2023.11.03