-
ddl-auto - Spring jpa (활용 part1)Java&Spring 2022. 7. 5. 16:16
이글은 인프런 강의 jpa 활용1 을 보고 만든 글입니다.
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
Test 를 했는데, ddl-auto option 이 안된다? -> 띄어쓰기를 확인해보자. 공백 주의 like python
ddl-auto: create
spring: datasource: url: jdbc:h2:tcp://localhost/~/jpashop username: sa password: driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create properties: hibernate: format_sql: true #show_sql: true logging.level: org.hibernate.SQL: debug
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
Bakend : 쿼리 , DB 어떻게 할지
spring의 장점은 DB transaction 의 효과 적인 처리와 객체를 이용한 작업으로 인하여 생산성을 높인점이다.
Lombok , getter setter 와 같은 귀찮은 코드를 어노테이션을 통해 쉽게 만들어준다.
Applicatation.java
package jpabook.jpashop; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class JpapracApplication { public static void main(String[] args) { Hello h = new Hello(); h.setData("this is data"); String data =h.getData(); System.out.println("data = " + data); SpringApplication.run(JpapracApplication.class, args); } }
Hello.java (class)
package jpabook.jpashop; import lombok.Getter; import lombok.Setter; @Getter @Setter public class Hello { private String data ; }
tip, intellij 단축키 :
soutv : systemprinout , 조건 : 상단의 객체를 만든 코드가 있어야한다.
work flow !
1. member class 작성 : DB 의 column 을 만들어줌 : (C 에서 구조체를 만드는 과정이다 . )
2.MemberRepository class 작성 : JPA manager 을 붙어 spring 에서 enttity를 handle 해줄 준비
1. @Repository spring 의 component scan 의 대상! 자세한건 Command +B 로 anotaion class 파일을 읽어보자.,
Repository.java
/* * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.stereotype; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor; /** * Indicates that an annotated class is a "Repository", originally defined by * Domain-Driven Design (Evans, 2003) as "a mechanism for encapsulating storage, * retrieval, and search behavior which emulates a collection of objects". * * <p>Teams implementing traditional Java EE patterns such as "Data Access Object" * may also apply this stereotype to DAO classes, though care should be taken to * understand the distinction between Data Access Object and DDD-style repositories * before doing so. This annotation is a general-purpose stereotype and individual teams * may narrow their semantics and use as appropriate. * * <p>A class thus annotated is eligible for Spring * {@link org.springframework.dao.DataAccessException DataAccessException} translation * when used in conjunction with a {@link * org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor * PersistenceExceptionTranslationPostProcessor}. The annotated class is also clarified as * to its role in the overall application architecture for the purpose of tooling, * aspects, etc. * * <p>As of Spring 2.5, this annotation also serves as a specialization of * {@link Component @Component}, allowing for implementation classes to be autodetected * through classpath scanning. * * @author Rod Johnson * @author Juergen Hoeller * @since 2.0 * @see Component * @see Service * @see org.springframework.dao.DataAccessException * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Repository { /** * The value may indicate a suggestion for a logical component name, * to be turned into a Spring bean in case of an autodetected component. * @return the suggested component name, if any (or empty String otherwise) */ @AliasFor(annotation = Component.class) String value() default ""; }
Member.java
package jpabook.jpashop; import lombok.Getter; import lombok.Setter; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity @Getter @Setter public class Member { @Id @GeneratedValue private Long id; private String username; }
MemberRepository.java
package jpabook.jpashop; import org.springframework.stereotype.Repository; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @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); } }
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test code 작성:
MemberRepository.java 에 커서 두고 커맨드 + shift + t -> testcode
tdd 작성
Tip : intellij live+ templete 을 등록 하자.
memberRepository.save(member);
save 에 커서 두고 커맨드 옵션 v 로 extract value 하자
MemberRepositorytest.java
package jpabook.jpashop; import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.transaction.Transactional; import static org.junit.Assert.*; // junit 4 @RunWith(SpringRunner.class) @SpringBootTest public class MemberRepositoryTest { // get injection @Autowired MemberRepository memberRepository; @Test @Transactional //모든 entity 변화는 Transaction 안 , entity manager 가 필요하다 public void testMember()throws Exception{ //given Member member = new Member(); member.setUsername("memberA"); // when Long savedId = memberRepository.save(member); Member findMember = memberRepository.find(savedId); // then Assertions.assertThat(findMember.getId()).isEqualTo(member.getId()); Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername()); } }
: 일반적으로 스프링에서는 testcase 에 transaction 이 있으면 결과 DB 에 data 가 저장 되지 않고 Roll back 이된다
--> 반복적인 test 를 위한 방식이다 .
Roll back 없이 test 를 위하면. > @Rollback(false) 어노테이션을 붙여준다.
----------------------------------------------------------------------------------------------------------------------
System.out.println("fm == m : "+ (findMember==member));
resurlt : ture
같은 transaction 안, 같은 영속성 안에서 같은 id 는 같은것으로 본다.
영속석 context 안 같은 식별자 => 1차 캐쉬 안 에서 가져온다.
즉 , insert 쿼리만 날라가고 select 쿼리는 없다.
>> insert
into
member
(username, id)
values
(?, ?)----------------------------------------------------------------------------------------------------------------------jar 빌드해서 동작 확인. >> 배포 할때 중요, port 안겹치는지 미리 확인하자.
folder -> gradlew 확인
$./gradlew clean build
$ll
$java -jar jpashop-0.0.1-SNAPSHOT.jar
----------------------------------------------------------------------------------------------------------------------
쿼리 파라미터 로그 남기기!!!!
1. yml 파일 , type option 추가
logging.level: org.hibernate.SQL: debug org.hibernate.type: trace
2. 다음 깃허브 링크에 들어가 gradle implementaion을 찾아 추가하고 , 버전확인 필수 , 바로 test 를 돌리면 된다.
자료 : 추가 적인 원하는 방식의 로그 형식을 찾아서 설정도 가능하다.
https://github.com/gavlyukovskiy/spring-boot-data-source-decorator
implementation("com.github.gavlyukovskiy:p6spy-spring-boot-starter:${version}")
버전 1.8.0 date : 2022.7.05
> 참고: 쿼리 파라미터를 로그로 남기는 외부 라이브러리는 시스템 자원을 사용하므로, 개발 단계에서는 편하 게 사용해도 된다
하지만 운영시스템에 적용하려면 꼭 성능테스트를 하고 사용하는 것이 좋다.
찾아볼것들 : 다음 글에서 알아보자.
------------------------------------------------------------------------------------------------------------------
DAO VS Repositiory ?
Class Vs Interface?
Directroy. vs Package?
------------------------------------------------------------------------------------------------------------------