7월 20일
1.검색처리하기
MyBatis가 여러모로 편리하긴 하지만 MyBatis로 sql을 만들때 고정이 된다.
상황에 따라서 sql이 동적으로 움직여야 하는데, 그때 제대로 동작하지 못하는 단점이 있다.
아래링클로 가면 상황에 따라 xml을 이용해서 필요한 sql을 만들어 낼수 있다.
https://mybatis.org/mybatis-3/ko/dynamic-sql.html
foreach 태그를 사용하여 동적쿼리를 만들어 줄수 있는데,
반복가능한 객체를 전달하면, 루프를 돌릴수 있다.
(1)BoardMapper 인터페이스에 추가하기
package com.keduit.mapper;
public interface BoardMapper {
List<BoardVO> searchTest(Map<String, Map<String,String>> map);
}
(2)BoardMapper.xml 추가하기
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--dtd라는건 xml문서가 어떻게 구성되는지,어떤 태그들을 몇번 쓸수 있게했는지 알수있는 문서이다.xml 태그들을 지원한다.-->
<mapper namespace="com.keduit.mapper.BoardMapper">
<!-- select이라는 태그를 쓰면 result를 어떻게 처리할껀지 고민해봐야함. 보통 resultMap,resultType을 많이 쓴다.
resultType은 VO,DTO등의 객체를 담을 수 있는 클래스의경로를 명시하고 사용하면됨, resultMap은 개발자가 직접 POJO클래스에 매핑-->
<select id="searchTest" resultType="com.keduit.domain.BoardVO">
<![CDATA[
select * from t_board where
]]>
<!-- 이름으로 전달되는 데이타안에 map이라는 이름이 필요하여 한번더 감싸서 넣었음 -->
<!-- trim은 if문 사이에 지정구문(and)을 true이면 suffix if문 뒤에,prefix if문 앞에 지정구문(and)를 붙인다. -->
<!-- separator는 for구문이 돌때마다 지정구문(or)을 넣어준다. -->
<!-- 우선순위 연산자 때문에 검색조건 부분을 괄호로 묶어줘야 한다. 그래서 for문을 시작하면서 open으로 괄호를 열고, for문이 끝나면서 close로 괄호를 닫는다.-->
<trim suffix="and">
<foreach collection="map" index="key" item="value" separator="or" open="(" close=")">
<if test="key=='T'.toString()">
title like #{value}
</if>
<if test="key=='C'.toString()">
content like #{value}
</if>
<if test="key=='W'.toString()">
writer like #{value}
</if>
</foreach>
</trim>
<!-- CDATA를 준이유는 부등호 표시때문에 필요하다. -->
<![CDATA[
rownum<10
]]>
</select>
</mapper>
(3)BoardMapperTest로 잘되는지 체크하기
package com.keduit.mapper;
@RunWith(SpringJUnit4ClassRunner.class)//이 클래스로 잘돌아가는지 test해볼꺼야
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")//참고할 경로는 여기야
@Log4j //화면에 뿌려주는건 Log4j가 관리 할거야
public class BoardMapperTest {
@Autowired
private BoardMapper boardMapper;
@Test
public void testSearch() {
Map<String,String> map= new HashMap<>();
map.put("T","TTT");
map.put("C","CCC");
map.put("W","WWW");
/* 위에 Map을 집어넣기위하여 outer맵을 생성하여 감싸줌 */
Map<String, Map<String, String>> outer =new HashMap<>();
outer.put("map",map);
List<BoardVO>list= boardMapper.searchTest(outer);
log.info(list);
}
}
2.검색조건을 처리하기위한 Criteria 클래스 변경하기
보통은 키워드 검색방법으로 검색키워드는 고정되고, 검색타입이 변경됨
(1)Criteria 추가하기
package com.keduit.domain;
//파라미터수집은 자바빈이 한다. 그래서 자바빈의 규칙에 따라 Getter 와 Setter가 필요하다. 그래서 아래와 같이 어노테이션 붙여줌
@Getter
@Setter
@ToString
public class Criteria {
private int pageNum;
private int amount;
private String type; //타입지정,문자열이기 때문에 foreach를 돌릴려면 배열로 변경해 줘야한다.
private String keyword; //검색키워드
//생성자로 초기값 주기
//생성자가 다른 생성자 호출할 때 사용, 다른 생성자 호출 시 첫 줄에서만 사용 가능
//마이바티스는 getter와 setter를 이용하기 때문에 문자열을 배열로 만들어주는 식이 필요함.
public String[] getTypeArr() {
//타입이 null이면 빈배열을 만든다.루프를 돌때 배열이 null인걸 체크를 해주는데, null오류가 안나게끔 할려고 빈배열 생성
//null이 아니면 type의 글자를 하나씩 하나씩 쪼갠다.
return type == null? new String [] {}:type.split("");
}
}
(2)BoardMapper.xml 추가하기
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--dtd라는건 xml문서가 어떻게 구성되는지,어떤 태그들을 몇번 쓸수 있게했는지 알수있는 문서이다.xml 태그들을 지원한다.-->
<mapper namespace="com.keduit.mapper.BoardMapper">
<!-- sql조각 선언하여 필요한곳에 include 한다. -->
<!-- Criteria에서 정의한 TypeArr이라는 배열을 가져와서 collection에 넣어주고, 배열이기 때문에 key가 필요없어서, item만 필요함 -->
<sql id="criteria">
<trim prefix="(" suffix=")and">
<foreach collection="typeArr" item="type" separator="or">
<if test="type=='T'.toString()">
title like '%'||#{keyword}||'%'
</if>
<if test="type=='C'.toString()">
content like '%'||#{keyword}||'%'
</if>
<if test="type=='W'.toString()">
writer like '%'||#{keyword}||'%'
</if>
</foreach>
</trim>
</sql>
<!-- select이라는 태그를 쓰면 결과데이터를 어떻게 처리할지에 대해 명시해 줘야함 -->
<!-- <![CDATA[]]>처리는 xml태그에서 부등호부분에 문제를 일으키기때문에 이부분을 xml태그처리를 하지말라는 의미 -->
<select id="getListWithPaging" resultType="com.keduit.domain.BoardVO">
<![CDATA[
select * from
(
select /*+ INDEX_DESC(t_board PK_BPARD)*/ rownum rn, bno, title, writer, regdate, updatedate
from t_board
where
]]>
<!-- 위에 sql조각을 불러서 사용할때 include가 쓰임 -->
<include refid="criteria"></include>
<![CDATA[
bno > 0 and rownum >0 and rownum <= (#{pageNum} * #{amount})
)
where rn > (#{pageNum}-1)* #{amount}
]]>
</select>
<select id="getTotalCount" resultType="int">
select count(bno) from t_board
<!-- 위에 sql조각을 불러서 사용할때 include가 쓰임 -->
<include refid="criteria"></include>
</select>
<select id="searchTest" resultType="com.keduit.domain.BoardVO">
<![CDATA[
select * from t_board where
]]>
</mapper>
(3)BoardMapperTest로 잘되는지 체크하기
@RunWith(SpringJUnit4ClassRunner.class)//이 클래스로 잘돌아가는지 test해볼꺼야
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")//참고할 경로는 여기야
@Log4j //화면에 뿌려주는건 Log4j가 관리 할거야
public class BoardMapperTest {
@Autowired
private BoardMapper boardMapper;
@Test
public void testSearchPaging() {
Criteria cri= new Criteria();
cri.setType("TCW");
cri.setKeyword("테스트");
List<BoardVO>list= boardMapper.getListWithPaging(cri);
list.forEach(b->log.info(b));
}
}