WIL 4주차 리액트!

스프링 부트를 활용하여 에브리타임 백엔드 구현하기!

entity란?

  • 실제 DB 테이블과 매칭될 클래스를 의미한다.
  • @Entity 어노테이션을 이용하여 Entity 클래스임을 명시해줘야 한다.
  • 간단한 사용법
@Id //PK로 사용될 칼럼
@Column(nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY) // auto increment 될 계획임을 명시
private int id;

@Column(nullable = false) // null이 불가능한 칼럼
private String title;
  • Builder 패턴 사용하기
    • @Builder 어노테이션을 사용하여 생성자를 만들어 보자
    • 장점으로는 생성자를 들어오는 모든 파라미터 경우의 수 별로 만들지 않아도 된다. 즉 불필요한 코드의 반복을 줄여준다.
    • 가독성을 높여준다.
    • setter를 사용하지 않게 해줌으로써 불변성을 제공한다.
    • 자세한 예시 https://mangkyu.tistory.com/163
    • 간단한 사용법
    // 빌더 패턴 사용하여 생성자 만들기
        User newUser = User.builder()
            .userId(userId)
            .password(password)
            .email(email)
            .hp(hp)
            .name(name)
            .nickname(nickname)
            .major(major)
            .build();
        
    // entity column 설정에서
        @Column(nullable = false, columnDefinition = "INT DEFAULT 0")
        @Builder.Default // default 값이 있다는 것을 명시해야 = 0 을 썻을때 오류가 나오지 않음.
        private int likeNum = 0;
    
  • 자주 사용되는 create_data, update_date 칼럼 class로 만들기
    • 해야 되는 일
      • main에 @EnableJpaAuditing 어노테이션 추가하기
      • class 만든 후 entity class에 extends BaseTimeEntity 추가하기
      • https://webcoding-start.tistory.com/53 자세한 설명
    • 사용 코드
      @Getter
      @MappedSuperclass
      //JPA Entity 클래스들이 BaseTimeEntity를 상속할경우 필드들도 칼럼으로 인식하도록 함
      @EntityListeners(AuditingEntityListener.class)
      //BaseTimeEntity클래스에 Auditing 기능을 포함시킨다.
      //Auditing -> Spring Data JPA에서 시간에 대해서 자동으로 값을 넣어주는 기능
      public abstract class BaseTimeEntity {
      @CreatedDate
      private LocalDateTime createdAt;
      
      @LastModifiedDate
      private LocalDateTime updatedAt;
      }
      

      Repository CRUD 외 Query문 만들기

  • JpaRepository를 extends 하면 기본적인 crud 코드들이 있음, 만약 자신이 원하는 코드를 추가하고 싶으면 아래와 같이 추가 할 수 있음 / 같은 기능이여도 다양한 방법으로 추가 가능 아래 코드들은 제가 예전에 공부할때 사용했었던 코드들 입니다.
    List<Board> findByTitle(String searchKeyword); //title을 기준으로 찾기 findBy{칼럼명}()으로 간단하게 생성 가능
    
    List<Board> findByCategory(String searchKeyword); // 카테고리를 기준으로 찾기
    
    Page<Board> findByTitleContaining(String searchKeyword, Pageable paging);
    
    List<Board> findByTitleContaining(String searchKeyword, Pageable paging);
    
    @Query("select b from Board b WHERE b.title like %?1% ORDER BY b.seq DESC")
    List<Board> queryAnnotationTest1(String searchKeyword);
    //위에랑 똑같음
    @Query("select b from Board b WHERE b.title like %:searchKeyword% ORDER BY b.seq DESC")
    List<Board> queryAnnotationTest2(@Param("searchKeyword")  String searchKeyword);
    
    //특정값 조회하기
    @Query("select b.seq, b.title, b.writer from Board b WHERE b.title like %:searchKeyword% ORDER BY b.seq DESC")
    List<Object[]> queryAnnotationTest3(@Param("searchKeyword")  String searchKeyword);
    
    //나만의 쿼리 만들어 사용하기
    @Query(value="select seq, title, writer from board WHERE title like '%'||?1||'%' ORDER BY seq DESC", nativeQuery = true)
    List<Object[]> queryAnnotationTest4( String searchKeyword);
    
    @Query("select b from Board b ORDER BY b.seq DESC")
    List<Board> queryAnnotationTest5(Pageable paging);
    

test code 작성

  • save code
        Optional<User> newUser = userRepository.findById(1);
         // findById 를 이용할시에 Id에 해당하는 row가 없을 수도 있기 때문에 ifPresent 코드가 없으면 상관은 없지만 노란 밑줄이 그어짐 
            newUser.ifPresent(getUser -> { // newUser가 있다면
                newBoard = Board.builder()
                        .userId(getUser)
                        .title("테스트 게시글")
                        .content("테스트 게시글 입니다.")
                        .category(2)
                        .commentNum(3)
                        .build();
            });
        boardRepository.save(newBoard);
    
  • get code
        Optional<Board> newBoard = boardRepository.findById(2);
        newBoard.ifPresent(getBoard->{
            System.out.println("user id : " + getBoard.getUserId());
            System.out.println("title : " + getBoard.getTitle());
            System.out.println("content : " + getBoard.getContent());
            System.out.println("category : " + getBoard.getCategory());
            System.out.println("isSecret : " + getBoard.getIsSecret());
            System.out.println("likeNum : " + getBoard.getLikeNum());
            System.out.println("comment Num : " + getBoard.getCommentNum());
            System.out.println("is hot : " + getBoard.getIsHot());
            System.out.println("created at : " + getBoard.getCreatedAt());
            System.out.println("updated at : " + getBoard.getUpdatedAt());
        });
    
  • delete code
        public void deleteBoardTest(){
        boardRepository.deleteById(4); //id에 해당하는 row 삭제
    }
    
  • update code
        Optional<Board> changeBoard = boardRepository.findById(2);
        String changeTitle = "바뀐 제목";
        changeBoard.ifPresent(getBoard ->{
            getBoard.setTitle(changeTitle);
            boardRepository.save(getBoard);
        });
        //가져와서 제목만 바꾼후 다시 저장 
        //id가 pk이므로 sava를 사용해도 이미 있으면 update됨.
    
        //다시 가져와서 출력해보기
        Optional<Board> newBoard = boardRepository.findById(2);
        newBoard.ifPresent(getBoard->{
            System.out.println("user id : " + getBoard.getUserId());
            System.out.println("title : " + getBoard.getTitle());
            System.out.println("content : " + getBoard.getContent());
            System.out.println("category : " + getBoard.getCategory());
            System.out.println("isSecret : " + getBoard.getIsSecret());
            System.out.println("likeNum : " + getBoard.getLikeNum());
            System.out.println("comment Num : " + getBoard.getCommentNum());
            System.out.println("is hot : " + getBoard.getIsHot());
            System.out.println("created at : " + getBoard.getCreatedAt());
            System.out.println("updated at : " + getBoard.getUpdatedAt());
        });
    

헷갈렸던 부분

DB 생성

귀신에 홀렸는지 DB를 먼저 만들어야 한다고 생각해서 직접 sql문을 작성하여 db를 작성했더니 @ManyToOne에서 FK를 제대로 인식하지 못하는 문제가 생김..

@JoinColumn 어노테이션을 사용하여 해결하려 했지만

또 새로운 문제가 생겨서 아예 db를 삭제 후 테스트 코드로 db를 생성하니 오류 해결..

내 머리를 안믿고 자동화된 코드를 믿기로 함!

테스트 코드를 이용하여 db를 생성하고 진행 하자!

다음 목표

  1. 각종 기능들 만들어보기