나와바리 - 식당 서비스

Sungmin·2023년 4월 20일
0

식당 생성

미리 DB에 서울특별시의 식당정보를 저장해 둘 거지만 새로 추가할 경우 사용예정


식당 이름으로 조회

  • 데이터베이스에서 입력된 문자열과 일치하는 식당 정보를 가져온다.
  • name.substring(i, i+2)를 통해 입력된 식당 이름에서 i부터 i+2까지의 두 글자를 추출한다.
  • restaurantRepository.findByName(sub)을 통해 데이터베이스에서 이 두 글자를 포함하는 모든 식당을 찾아온다.
  • 이렇게 찾아온 식당 목록이 비어있지 않으면, 즉 최소 두 글자 이상이 연속된 문자가 같은 다른 식당이 존재하는 경우는 이 목록을 반환

이렇게 다른 이름으로 검색을 시도하는 이유는, 종종 사용자들이 실수로 식당 이름을 잘못 기억하거나, 조금 다르게 입력할 수 있기 때문입니다. 예를 들어, "김밥"을 찾고자 할 때, "김밥"이라는 이름으로 등록된 식당이 없을 수도 있습니다. 그러나 "김밥천국", "김밥나라" 등과 같이, 최소 두 글자 이상이 연속된 문자가 같은 다른 식당들은 존재할 수 있습니다. 따라서 이러한 식당들을 찾아서 결과로 제공해주는 것입니다.


주소로 식당 조회

이 서비스 로직에선 자바 정규식 Regex(Regular Expression)을 사용하였다.
정규식을 이용하면 많은 양의 텍스트 파일 중에서 원하는 데이터를 손쉽게 뽑아낼 수 있고, 입력된 데이터가 형식에 맞는지 체크할 수도 있다.

내가 사용한 정규식

  • (?i) = 대소문자 구분x
  • .* = 모든문자
  • \b = 문자의 경계

예를들어 서초구 양재동으로 입력될 경우 공백을 확인하고 배열에 담고
앞 글자인 서초구가 포함된 주소를 찾고 그 중에서 양재동을 포함하는 주소만 리스트로 가져올 수 있게 만들었다.


삭당 통합검색

    //통합 검색
    public List<Restaurant> searchByNameAndAddress(String keyword) {
        if (keyword.length() < 2) {
            throw new IllegalArgumentException("최소 두 글자 이상 입력해 주세요.");
        }
        List<Restaurant> restaurants = restaurantRepository.SearchByNameAndAddress(keyword);

        if (restaurants.isEmpty()) {
            restaurants = restaurantRepository.searchByKeywordContaining(keyword);
        }

        return restaurants;
    }
  • 최소 두 글자 이상의 키워드를 사용자에게 매개변수로 받아온다.
  • 키워드와 정확히 일치하는 식당의 경우 바로 반환.
  • 일치하는 식당이 없다면 키워드를 포함하고 있는 식당들을 전부 반환.

식당 상세조회


식당 수정


식당 삭제


식당 생성 테스트

    @Test
    public void 식당생성() throws Exception {
        //given
        Restaurant restaurant = Restaurant.builder()
                .name("김밥천국")
                .address_name("강남구")
                .lat(123.123)
                .lng(456.456)
                .build();
        em.persist(restaurant);

        //when
        Long restaurantId = restaurantService.createRestaurant(restaurant);

        Restaurant findRestaurant = restaurantRepository.findOne(restaurantId);

        //then
        assertThat(findRestaurant.getId()).isEqualTo(restaurantId);
    }
  • 식당객체를 하나 생성해 주고 값을 담아 저장
  • DB에 아이디가 일치하는 식당을 가져옴
  • 입력받은 식당과 일치하는지 확인

식당 이름으로 조회 테스트

    @Test
    public void 식당이름으로조회() throws Exception {
        //given
        Restaurant restaurant1 = Restaurant.builder()
                .name("김밥 천국 강남점")
                .address_name("강남구")
                .lat(123.123)
                .lng(456.456)
                .build();
        Restaurant restaurant2 = Restaurant.builder()
                .name("김밥 천국 중구점")
                .address_name("중구")
                .lat(123.456)
                .lng(456.123)
                .build();

        em.persist(restaurant1);
        em.persist(restaurant2);

        String inputName1 = "김밥천국";
        String inputName2 = "김밥";
        String inputName3 = "김";


        //when

        List<Restaurant> restaurants1 = restaurantService.findByRestaurantName(inputName1);
        List<Restaurant> restaurants2 = restaurantService.findByRestaurantName(inputName2);

        //then
        assertThat(restaurants1.size()).isEqualTo(2);
        assertThat(restaurants2.size()).isEqualTo(2);
        assertThrows(IllegalArgumentException.class, () -> {
            restaurantService.findByRestaurantName(inputName3);
        });

    }

같은 이름의 식당 2개를 설정한 후 3가지 경우
1. 완전일치
2. 한 단어만 일치
3. 예외문구
를 입력받았을때 값이 잘 들어가는지 예외가 잘 발생하는지 코드를 만듦


주소로 식당조회 테스트

    @Test
    public void 주소로식당조회() throws Exception {
        //given
        Restaurant restaurant1 = Restaurant.builder()
                .name("마루심")
                .address_name("서초구 반포동 54-10")
                .lat(123.123)
                .lng(456.456)
                .build();
        Restaurant restaurant2 = Restaurant.builder()
                .name("메종조")
                .address_name("서초구 서초동 1476-10")
                .lat(123.456)
                .lng(456.123)
                .build();
        Restaurant restaurant3 = Restaurant.builder()
                .name("서관면옥")
                .address_name("서초구 서초동 1675-5")
                .lat(123.456)
                .lng(456.123)
                .build();

        em.persist(restaurant1);
        em.persist(restaurant2);
        em.persist(restaurant3);

        String inputName1 = "서초구";
        String inputName2 = "서";
        String inputName3 = "반포동";

        //when

        List<Restaurant> address1 = restaurantService.findByAddressName(inputName1);
        List<Restaurant> address3 = restaurantService.findByAddressName(inputName3);


        //then
        assertThat(address1.size()).isEqualTo(3);
        assertThrows(IllegalArgumentException.class, () -> {
            restaurantService.findByAddressName(inputName2);
        });
        assertThat(address3.size()).isEqualTo(1);
    }
  • 구를 입력했을때 입력받은 구를 포함한 식당 모두 조회
  • 한 글자 입력시 예외발생
  • 동을 입력받았을때 입력받은 동을 포함하는 식당 모두 조회

식당 상세조회 테스트

    @Test
    public void 식당상세조회() throws Exception {
        //given
        Restaurant restaurant = Restaurant.builder()
                .name("마루심")
                .address_name("서초구 반포동 54-10")
                .lat(123.123)
                .lng(456.456)
                .reviews(new ArrayList<>())
                .build();
        em.persist(restaurant);

        Review review1 = Review.builder()
                .title("Good")
                .likeCount(18)
                .build();

        Review review2 = Review.builder()
                .title("fuck")
                .likeCount(3)
                .build();

        Review review3 = Review.builder()
                .title("soso")
                .likeCount(4)
                .build();

        Review review4 = Review.builder()
                .title("bad")
                .likeCount(1)
                .build();

        restaurant.addReview(review1);
        restaurant.addReview(review2);
        restaurant.addReview(review3);
        restaurant.addReview(review4);

        em.persist(restaurant);
        em.persist(review1);
        em.persist(review2);
        em.persist(review3);
        em.persist(review4);
        em.flush();

        //when
        Restaurant detail = restaurantService.detailRestaurant(restaurant.getId());

        //then
        List<Review> top3Reviews = detail.getReviews();
        assertThat(detail.getReviews().size()).isEqualTo(3);
        assertThat(top3Reviews).containsExactly(review1, review3, review2);
    }

저장된 식당아이디와 조회하려는 식당의 아이디가 같으면 식당정보 리턴

식당 통합검색 테스트

    @Test
    public void 통합검색() throws Exception {
        //given
        Restaurant restaurant1 = Restaurant.builder()
                .name("미분당")
                .address_name("서울특별시 강남구 역삼동 148-1")
                .lat(123.123)
                .lng(456.456)
                .build();
        Restaurant restaurant2 = Restaurant.builder()
                .name("미소야(역삼점)")
                .address_name("서울특별시 강남구 논현동 527-96")
                .lat(123.456)
                .lng(456.123)
                .build();

        em.persist(restaurant1);
        em.persist(restaurant2);

        String inputName1 = "미소야";
        String inputName2 = "서울";
        String inputName3 = "미";


        //when

        List<Restaurant> restaurants1 = restaurantService.searchByNameAndAddress(inputName1);
        List<Restaurant> restaurants2 = restaurantService.searchByNameAndAddress(inputName2);
        
        assertThat(restaurants1.size()).isEqualTo(1);
        assertThat(restaurants2.size()).isEqualTo(2);
        assertThrows(IllegalArgumentException.class, () -> {
            restaurantService.findByRestaurantName(inputName3);
        });

    }

변경사항

식당 이름 검색과 주소검색을 각각 사용하지않고 통합 검색으로 수정

기존 식당이름으로 검색과 주소로 검색을 나눴었는데 나눌 필요성과 사용성을 고려하여 통합검색 하나로 수정.

profile
Let's Coding

0개의 댓글