ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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?

    ------------------------------------------------------------------------------------------------------------------

     

Designed by Tistory.