티스토리 뷰





반응형

이전에 서블릿에서 들어오는 데이터의 조건에 따라 쿼리문을 바꾸는게 불가능 했다. 그렇기 때문에 비슷하지만 다른 조건의 쿼리문을 만들거나 for문으로 1개씩 데이터를 나눠서 담거나 그랬다. 하지만 mybatis에 와서는 JSTL태그를 사용할 수가 있기 때문에 이러한 번거로움을 조금 줄일 수 있다.


위 사진은 사원명으로만 검색을 하거나 사원명+성별, 사원명+성별+급여 등등 아주 다양한 방법으로 해당하는 사원을 찾을 수 있도록 폼을 구성한 것이다. 이전에는 이런식으로 구성을 한다면 디비에서의 쿼리문이 꽤나 복잡하게 만들어야했는데 mybatis에선 어떻게 되는지 한번 봅시다~!



1
2
3
4
5
6
7
8
9
10
11
12
13
14
    <div>
        <h2>회원관리</h2>
        <div id="searchMember">
            <form method='get' action='${path }/admin/searchMember.do'>
            <select name="searchType">
                <option value="" disabled selected>검색타입</option>
                <option value="memberid" <c:if test="${searchType eq 'memberid'}">selected</c:if>>아이디</option>
                <option value="membername"<c:if test="${searchType eq 'membername'}">selected</c:if>>이름</option>
            </select>
            <input type="text" name="keyword" value="${keyword!=null?keyword:''}"/>
            <input type="submit" value="검색">
            </form>
        </div>
    </div>
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@RequestMapping("/admin/searchMember.do")
   public ModelAndView searchMember(@RequestParam(value="cPage",required=false,defaultValue="0")int cPage, String searchType, String keyword,ModelAndView mv) 
   {
       Map<String,String> searchData = new HashMap<String,String>();
       searchData.put("searchType", searchType);
       searchData.put("keyword", keyword);
       
       int searchListAll = service.searchListAll(searchData);
       int numPerPage = 10;
       List<Map<String,String>> searchList = service.searchList(searchData,cPage,numPerPage);
       mv.addObject("pageBar", PageFactory.getPageBar(searchListAll, cPage, numPerPage,"/odagada/admin/memberList.do"));
       mv.addObject("memberList", searchList);
       mv.addObject("searchType", searchType);
       mv.addObject("keyword", keyword);
       mv.setViewName("board/memberManagement");
       return mv;
   }
 
cs





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        request.setCharacterEncoding("utf-8");
        String searchType =request.getParameter("searchType");
        String keyword = request.getParameter("keyword");
        String gender = request.getParameter("gender");
        String salary = request.getParameter("salary");
        String salaryLeGe = request.getParameter("salary_le_ge");
        
        
        Map<String,String> map = new HashMap();
        map.put("searchType",searchType);
        map.put("keyword",keyword);
        map.put("gender",gender);
        map.put("salary", salary);
        map.put("salaryLeGe", salaryLeGe);
        
        List<Map<String,String>> list = service.search2(map);
    
        request.setAttribute("list", list);
        request.getRequestDispatcher("/views/emp/search2.jsp").forward(request, response);
    }
 
cs

위와 같이 일단 name들의 값들을 받고 map에 put한 뒤에 아래 mapper.xml에서 값이 있으면 조건을 추가하여 붙이는 형식으로다가 진행이 된다.



mapper.xml

먼저 9~12번째 줄 부터 시작하겠다. 위에 사진을 보면 사원명이라는 선택사항이 있는데 사실 저건 select 태그로 밑에 다른 옵션으로도 검색이 가능한 형태다. 사진에는 안보이지만 사번, 사원명, 이메일, 전화번호등으로 검색이 가능하도록 <option>들이 숨어 있다. 그렇다면 쿼리문이 <option>이 어떤 것이냐에 따라 달라져야 하기 때문에 11번째 줄에 조건절이 ${searchType}으로 되어 있는 것이다. 


이는 #으로 했을 때와 뭐가 다르냐면 #은 DB에 들어가는 데이터이기에 '홍길동' 이런식으로 싱글컨텐션이 들어간다. 하지만 조건절에는 그런 처리가 들어가면 오류가 생기기 때문에 그 자체의 값인 리터럴값을 넣기 위해 $를 사용하는것이다. 그래서 데이터를 보낼 때 어떤 조건으로 검색하는지? 와 해당 값을 동시에 보내는 것이다.

ex) select * from kh.employee where emp_name like '홍길동' <-- 이런식이 되도록 하기 위함


다음은 2번째 where 1=1에 대해 이야기 할 것이다. 조건은 사원명만 사용할 수 있고 사원명+성별이 올 수도 있다. 이렇게 가변적이기 때문에 where 1=1라는 불변의 true값을 넣어주고 그 아래 <if>태그를 통해 변수 gender가 null이 아니고 공란('')도 아닐 시 and를 붙여 where조건을 늘려 나가는것이다. 이렇게 하면 salary도 값이 있으면 자연스레 조건문이 1개가 더 추가가 되는것이다. 다만 주의할점은 마지막 빨간네모인데 꺽쇠(<) 이미 예약어로 사용되는 기호이므로 이스케이프문을 통해 사용해야한다. <![CDATA[조건기호]]> 이렇게 사용하면 된다.


mapper에서의 foreach문

1
2
3
4
5
6
7
8
9
10
<?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" >
<mapper namespace="demo">
    <insert id="insertDev" parameterType="com.kh.spring.demo.model.vo.Dev">
        INSERT INTO DEV VALUES(seq_dev_no.nextval,#{devName},#{devAge},#{devEmail},#{devGender},
        <foreach collection="devLang" item="lang" open="'" close="'" separator=",">
        ${lang}
        </foreach
        <!-- #{devLang, typeHandler = strArray}) -->
    </insert>
cs

위 내용은 직전의 포스팅 내용인 typeHandler를 사용하기전의 데이터를 넣는 방식인데 좋은 예제라 생가되어 가져옴

mapper에서도 반복문인 foreach를 사용가능하다!! 하지만 주의할점이 있다.

JSTL에서는 <forEach>고 mybatis는 <foreach>다. 용어가 다른만큼 잘못쓰면 에러 발생!! 안에 옵션도 다른데....

JSTL은 굳이 언급 안하겠다. mybatis는 collection에 배열을 담고 item으로 해당 변수를 사용한다. forEach의 var와 같다. 그리고 opne과 close를 통해 이 변수의 제일 앞과 맨뒤에 붙일 기호를 넣을 수 있다. 마지막으로 separator를 통해서 값 사이사이에 , 를 찍어서 데이터를 저장할 수 있게 도와준다.


ex) devLang[]={등산,코딩,여행} --> '등산, 코딩, 여행' 이 형태로 DB에 저장된다. 

저장될 때 양옆 '  는 당연히 빠지고 들어가니 헷갈리지 마시길.. 

반응형
댓글
반응형
최근에 달린 댓글
글 보관함
Total
Today
Yesterday
최근에 올라온 글
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30