기존의 table을 jpa로 변경하기(1)

zooju·2022년 10월 11일
0

Mepe To JPA 프로젝트..

10/11: User Table을 Entity로 만들고 테스트해보기

오늘 배운 점 요약

  1. repository 만들기
  2. 테스트 코드를 통과시키기 위해 코드를 수정하는 경험!

목표

  • 주요 목표: table을 jpa로 옮기기
  • 간단히 repository 만들기
  • 간단히 test code 만들기

JPA로 바꾸려는 이유

원래 Mepe 프로젝트에서 jdbc로 직접 sql문으로 접근하는 코드를 사용했는데 다음과 같은 이유로 jpa로 변경해야겠다고 생각했다.

  1. “방금 insert한 object의 index 불러오기” 를 하고 싶은 것이 엄청 큰 이유였다.

    현재 sql last_insert_id() 을 사용하고 있기는 하지만 요청이 많아지면 옳지 않은 결과값이 나올 수 있기 때문에 불안하기 때문이다.

  2. 현재 insert나 update관련해서 겹치는 코드의 양이 너무 너무 많다.

  3. jpa를 잘 다뤄보고 싶어서!

User 테이블 JPA로 변경하기

그래서 jpa로 변경하는 첫번째 날… 일단 user만 가볍게 바꿔보기로 했다. fk가 가장 많이 연결되어 있어서 제일 먼저 jpa로 바꾸는게 편할 것 같았다.

1. 새로운 프로젝트에 데이터베이스 연결하기

기존 프로젝트에서 또 병렬적으로 진행중인 업무가 있어서 일단 프로젝트를 새로 파서 entity와 repository, test 코드를 작성해보는 용으로 만들었다.

  • AWS RDB는 이미 만들어져있는 상황!
  • applications.properties에 mysql 관련 정보를 넣어주기
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=[AWS에 나와있는 url]
    spring.datasource.username=admin
    spring.datasource.password=[비밀번호]
    spring.jpa.show-sql=true
    spring.jpa.hibernate.ddl-auto=none
    spring.jpa.properties.hibernate.format_sql=true
    spring.jpa.properties.hibernate.physical_naming_strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
  • build.gradle에 mysql, junit 관련 dependencies 넣기
    //mysql
    implementation 'mysql:mysql-connector-java'
    
    //JUnit4 추가
    testImplementation("org.junit.vintage:junit-vintage-engine") {
    	exclude group: "org.hamcrest", module: "hamcrest-core"
    }
  • 직접 spring compile 해서 테스트 → 잘 돌아가면 성공! (혹은 intellij database 탭으로 해도 굿)

2. Entity 만들기

  • 사실 데이터 베이스 column과 table 자체도 좀 수정하고 싶기는 한데 그렇게 하기엔 좀 어려울 것 같다.
  • 일단 쭉 코드를 작성했다.
    @Entity
    @Getter
    @Setter
    @DynamicInsert
    @DynamicUpdate
    public class user {
        @Id
        private String id;
    
        @ColumnDefault("https://daotool.s3.ap-northeast-2.amazonaws.com/static/user/a4cc74a2-ee79-4098-b4d7-f0f9c3de6099bannerimg-default2.png")
        private String backImage;
    
        private String profileImg;
    
        private String introduction;
        private String url;
    
        @ColumnDefault("0")
        private Integer hits;
    
        @ColumnDefault("0")
        private Integer todayHits;
    
        @ColumnDefault("10")
        private Integer nftRefreshLeft;
    
        @CreationTimestamp
        private Timestamp createdAt;
    
        @GeneratedValue
        private Integer index;
    
        private String nickname;
    
        @ColumnDefault("0")
        private Integer todayFollows;
    
        @Column(updatable = false, nullable = false)
        @CreationTimestamp
        private Timestamp refreshAt;
    }

3. Repository 만들기

  • 일단 테스트용으로 find, save 두개만!
    @Repository
    public class UserRepository {
        @PersistenceContext
        EntityManager em;
    
        public String save(user user){
            em.persist(user);
            return user.getId();
        }
    
        public user find(String id){
            return em.find(user.class, id);
        }
    }

4. 테스트 하기

  • 테스트코드도 간단하게 작성해보았다.
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class UserRepositoryTest {
        @Autowired
        UserRepository userRepository;
    
        @Test
        @Transactional
        @Rollback(false)
        public void testMember(){
            user user = new user();
            user.setId("jpaTest");
            user.setNickname("jpaTest");
            String savedId = userRepository.save(user);
            com.propwave.mepeWithJPA.domain.user findMember = userRepository.find(savedId);
    
            Assertions.assertThat(findMember.getId()).isEqualTo(user.getId());
    
            Assertions.assertThat(findMember).isEqualTo(user);
        }
    }
  • 테스트를 하며 수정한 내용
    • 계속 column이 snake case로 바뀌어서 sql문이 실행되는 것 같아 properties에 다음과 같은 naming strategy를 설정했다.
      spring.jpa.properties.hibernate.physical_naming_strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    • Defalut 있는 친구들은 default를 추가했다.
    • createdAt → creationTimestamp 넣어주었다.
    • default가 있는 친구들은 값을 넣지 않아도 들어갈 수 있게 다음과 같은 annotation 추가해주었다.
      @DynamicInsert
      @DynamicUpdat
    • table 이름이 소문자이므로 user로 테이블명을 바꿔주었다.

이렇게 test가 통과될 수 있도록 하는 것을 목표로 하서 오류를 계속 수정하는 형식으로 코딩을 하니까 굉장히 재밌고 뿌듯했다.

profile
이것 저것 새로운 분야에 관심이 많은 서버 개발자

0개의 댓글