[SpringBoot(2)] 대용량데이터 검색기능

배지원·2022년 11월 22일
0

실습

목록 보기
15/24
post-custom-banner

이전에 사용했던 JPQL을 통해 검색 기능을 구현해볼려고 한다.
방식으로는

유저 값 입력(Form태그 이용) -> Controller(get을 통해 데이터 받음) -> Service -> Repository(JPQL문을 통해 DB에서 원하는 데이터 찾음)

순으로 진행하도록 하겠다.

Front

Hospital List

{{>layouts/header}}
<form action="/hospital/search" method="get">

    {{#keyword}}    <!-- 키워드 값이 있을경우 keyword    칸안에 데이터 입력 -->
        위치검색 <input type="search" name="keyword" value="{{keyword}}">
    {{/keyword}}
    {{^keyword}}
        위치검색 <input type="search" name="keyword">
    {{/keyword}}
    <button class="btn btn-outline-success" type="submit">Search</button>
    </p>
</form>
<table class="table">
    <thead>
    <tr>
        <th scope="col">번호 </th>
        <th scope="col">병원이름</th>
        <th scope="col">병원주소</th>
    </tr>
    </thead>
    <tbody class="table-group-divider">
    {{#hospitals}}
        <tr>
            <th>{{id}}</th>
            <td><a href="/articles/{{id}}">{{hospitalname}}</a></td>
            <td>{{fulladdress}}</td>
        </tr>
    {{/hospitals}}
    </tbody>
</table>

<ul class="pagination justify-content-center">
    <!-- 검색(키워드)가 없이 그냥 전체 리스트 출력일 경우 -->
    {{^keyword}}
    <li class="page-item">
        <a class="page-link" href="?page={{previous}}">Previous</a>
    </li>
    <li class="page-item">
        <a class="page-link" href="?page={{next}}">Next</a>
    </li>
    {{/keyword}}

    <!-- 검색키워드를 포함한 리스트 출력일 경우 -->
    {{#keyword}}
    <li class="page-item">
        <a class="page-link" href="?page={{previous}}&keyword={{keyword}}">Previous</a>
    </li>
    <li class="page-item">
        <a class="page-link" href="?page={{next}}&keyword={{keyword}}">Next</a>
    </li>
    {{/keyword}}
</ul>

{{>layouts/footer}}
  • 유저에게 검색 키워드를 입력받아 get으로 데이터를 넘겨주기 위한 Form 태그 작성
  • 키워드 값이 있을때와 없을때를 구분하여 동작할 수 있도록 함
    {{#keyword}} : 키워드 값이 있을때 동작
    {{^keyword}} : 키워드 값이 없을때 동작
  • 대용량 데이터이기 때문에 검색할때도 페이징이 필수임(안그러면 로딩이 오래 걸림) 이때, 페이징할때는 페이지 번호와 keyword를 함께 넘겨줘야함 ?page={{next}}&keyword={{keyword}}

Back

Controller

@Controller
@RequestMapping("/hospital")
@Slf4j
public class HospitalController {

    private final HospitalService hospitalService;

    public HospitalController(HospitalService hospitalService) {
        this.hospitalService = hospitalService;
    }

    // Hospital 대용량 데이터 리스트 만들기(페이징 하여 출력)
    @GetMapping("/list")
    public String list(Pageable pageable,Model model){
        Page<Hospital> hospitals = hospitalService.getHospitalList(pageable);        // 페이징 추가
        model.addAttribute("hospitals",hospitals);
        model.addAttribute("previous",pageable.previousOrFirst().getPageNumber());
        model.addAttribute("next",pageable.next().getPageNumber());
        return "hospital/list";
    }

    @GetMapping("/search")
    public String searchlist(@RequestParam String keyword, Pageable pageable, Model model){
        log.info("검색 키워드 :"+keyword);
        Page<Hospital> hospitals = hospitalService.searchname(pageable,keyword);
        model.addAttribute("hospitals",hospitals);
        model.addAttribute("keyword",keyword);
        model.addAttribute("previous",pageable.previousOrFirst().getPageNumber());
        model.addAttribute("next",pageable.next().getPageNumber());

        return "hospital/list";
    }

}
  • 유저에게 Form 태그를 통해 입력받은 Keyword를 RequestParam을 통해 받고 동시에 페이징 처리를 이해 Pageable도 받는다.
  • Keyword를 통해 DB에서 해당하는 데이터 리스트를 반환 받고 Model에 담아 View로 넘겨준다.
    이때 View에서 keyword의 존재 여부에 따라 동작하는 것이 달라지기 때문에 Model에는 데이터 리스트, keyword, page 데이터를 담아 넘겨준다.

Service

@Service
public class HospitalService {

    private final HospitalRepository hospitalRepository;

    public HospitalService(HospitalRepository hospitalRepository) {
        this.hospitalRepository = hospitalRepository;
    }

    public Page<Hospital> getHospitalList(Pageable pageable){
        return hospitalRepository.findAll(pageable);
    }

    // 검색 기능
    public Page<Hospital> searchname(Pageable pageable, String keyword){
        return hospitalRepository.findByRoadNameAddressContaining(pageable, keyword);
    }
}

Repository

    Page<Hospital> findByRoadNameAddressContaining(Pageable pageable, String keyword);
  • JPQL문을 통해 입력받은 Keyword가 포함된 데이터들을 모두 list에 반환한다.


결과

profile
Web Developer
post-custom-banner

0개의 댓글