본문 바로가기

포트폴리오 개발일지

2024.06.03 게시판 검색 1.2

이전 노트검색 1.1 의 문제점

1. 검색 조건이 늘어날수록 mybatis xml 에 <if test=""> 가 늘어나야 함을 뒤늦게 깨달았다.... 검색 타입을 지정하는 SearchDTO 클래스에


   public class SearchDTO{
   private String title;
   private String content;

}


  1. 검색 타입 하나하나가 지정되어 있기 때문이다. - 검색 조건이 늘어날수록 DTO 변수도 계속 추가되어야 한다

mybatis 문서(https://mybatis.org/mybatis-3/dynamic-sql.html) 를 볼때<foreach> 구문이 있었는데 Collection 에 대한 반복처리를 지원하는 구문이라고 한다.

당장 드는 생각에는 검색 조건을 Collection 타입으로 받아 각 원소를 mybatis 의 <foreeach> / <if test="">로 비교하여 sql 구문을 적용하면 될것 같다.

SearchDTO 수정

Collection 타입으로 수정을 할것인데 컬렉션 타입 중에서 어느 것이 효율적일지 고르지 못해서 우선 내가 검색에 사용할 조건을 생각해봤다.

  1. 같은 검색 조건에 여러값이 들어가는가? = 검색 조건에는 한개의 밸류만 들어간다.
  2. 여러 검색조건을 한번에 검색할수 있는가? = 제목 or 내용 등 동시에 여러 검색조건을 검색할수 있어야 한다.

위 조건을 바탕으로 정리해보았다.

  1. 검색 조건을 저장할 Collection 타입 변수(순서 중요하지 않음 검색 조건의 종류가 엄청 많지 않을것으로 예상)
    1. 어떤 검색 조건을 사용자가 선택할지 미리 알수 없으므로 인덱스를 통해 순회 후 검색조건 가져오기 = Array or List
    2. 검색어(키워드)가 문자열일지 숫자일지 날짜일지 알수 없으므로(바뀔수도 있으므로) 유연성을 위해
      List 사용해보기
  2. 검색 키워드를 저장할 String 변수가 필요함을 알았다.

types 를 테스트 하기 위해 기존 SearchDTO 의 변수를 주석처리 하고 새로추가



@Data  
@ToString  
@Builder  
@NoArgsConstructor  
@AllArgsConstructor  
public class SearchDTO {
private List<String> types;  

private String keyword;

}


NoteMapper.xml 수정



<select id="selectSearchList" resultType="org.leeinwon.studylink.domain.NoteVO">

    select * from notes  
    <where>
        <foreach collection="types" item="type" open="(" close=")" separator="OR">  

            <if test="type == 'title'.toString()">  
                title like concat('%', #{keyword}, '%')  
            </if>  
            <if test="type == 'content'.toString()">  
                content like concat('%', #{keyword}, '%')  
            </if>

        </foreach>  
    </where>
    order by id asc
</select>

다음으로는 MapperTest 를 진행하였다.



@Log4j2  
@ExtendWith(SpringExtension.class)  
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/root-context.xml")  
public class NoteMapperTests {

    @Autowired(required = false)  
    private NoteMapper noteMapper;

    @Test  
    public void testSelectSearchList(){  

        SearchDTO searchDTO = SearchDTO.builder()  
                .types(Arrays.asList("title","content"))  
                .keyword("2")  
                .build();  

        List noteVOList = noteMapper.selectSearchList(searchDTO);  

        noteVOList.forEach(vo -> log.info(vo));  
    }
}

테스트 진행 결과 현재 단계에선 큰 문제가 없었고, 다음으로 서비스와 컨트롤러 뷰를 만들었다.

현재 문제점

서비스를 구현하던 중 뭔가 이상함을 깨달았다ㅠ

지금 NoteMapper 클래스의
List<NoteVO> selectSearchList(SeartDTO searchDTO)
메서드가 나중에 문제가 될것 같았다. 반환형이 DB에서 select 문을 실행한 결과인 List 인데
검색결과 리스트 반환은 가능하지만 사용자가 검색했던 검색조건과 검색어를 반환할수 없는 문제가 있다.