TDD / Mybatis - 게시글 필터
필터 기능 추가
- 새로운 테스트 메서드를 생성해서 진행
- findAllTest() 메서드를 사용하지만 오버로딩을 통해 구현(매개변수 다름)
DB에 필터 컬럼 추가
- 기존에 게시글을 분류하는 컬럼이 없었기 때문에 새로 추가
ALTER TABLE BOARD AND TYPE VARCHAR2 (2) DEFAULT 'B1';
-
DB에 새 컬럼이 추가되었다.
-
임의로 B2, B3 타입으로 수정도 진행했다.
티입은 B1, B2, B3 세가지이다.
이제 B1을 선택하여 게시글을 조회할 경우, B2/B3을 선택하여 조회할 경우를 테스트해 볼 것이다.
만약 체크박스라고 생각한다면
<input type="checkbox" name="bType" value="B1">
<input type="checkbox" name="bType" value="B2">
<input type="checkbox" name="bType" value="B3">
위처럼 name 속성은 모두 같고 valus 속성의 값은 각자 다를 것이다.
test 코드 작성
@Test
public void findAllTest() {
// request.getParameterValues("filter");
String[] filters = new String[] {"B2", "B3"}; // B1 타입의 게시글은 너무 많기 때문에 B2, B3만 테스트 진행
// List 객체로 변환
List<Board> list = null;
// sevice한테 요청해서 list 받기
// findAll() 메서드를 실행할 때 filters 배열을 받을 수 있도록 작성
list = service.findAll(filters);
// list를 받아오면 null이 아닐 것이라고 예상
assertThat(list).isNotNull();
}
service 코드 작성
public List<Board> findAll(String[] filters) {
List<Board> list = null;
SqlSession session = getSession();
// dao에 요청(DB 접근)
list = dao.findAll(session, filters);
session.close();
return list;
}
dao 작성
public List<Board> findAll(SqlSession session, String[] filters) {
// dao에 넘기는 두번째 매개값을 filters(배열)로 넘길 경우 내부적으로 map으로 변환하기 때문에
// 직접 map 객체로 생성하여 넘겨줌
Map<String, Object> map = new HashMap<>();
map.put("filters", filters);
// map으로 넘길 경우 쿼리문에서 filters 이름 사용 가능
return session.selectList("boardMapper.selectBoardListByFilters", map);
// filters(배열)로 넘길 경우 쿼리문에서 array로 사용
// list로 넘길 경우는 list로 사용
// return session.selectList("boardMapper.selectBoardListByFilters", filters);
}
쿼리문 작성 - foreach
- foreach 사용
- collection : 파라미터로 넘어온 배열이나 리스트 지정
- item : 배열이나 리스트의 각 요소들 값이 들어가는 변수
- index : 반복 회수(0부터 시작)
- open : 반복문 시작 전 출력할 문자 지정
- separator : 구분자
- close : 반복문 종료 전 출력할 문자 지정
<select id="selectBoardListByFilters" parameterType="map" resultMap="boardListResultMap">
<!-- sql 조각 사용 -->
<include refid="boardListSql" />
<!-- 동적 SQL - if문 사용 -->
<!--
- dao에서 map 객체로 만들어서 넘겼기 때문에 filters로 지정 가능
- 배열로 넘길 경우 array
- list로 넘길 경우 list
-->
<if test="filters != null">
AND B.TYPE IN
<!-- AND B.TYPE IN ('B2', 'B3') -> <foreach>를 사용하여 작성
: 타입은 계속 수정이 될 수 있기 때문에 쿼리문에서는 확장성을 위해 foreach문 사용
-->
<foreach collection="filters" item="filter" open="(" separator="," close=")">
#{ filter }
</foreach>
</if>
</select>