• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Java EE 정리 28

05 Apr 2019

Reading time ~9 minutes

Java EE 정리 28 - MyBatis(3)


컬럼 여러개 레코드 여러개 조회할 때

  • 입력되는 (parameterType) 부서번호에 따른 사원정보 조회(resultType)
    • 입력되는 값이 단일형이라면 자바 데이터형 사용
      • 노드안에서 사용할 때에는 #{ 아무값 }
    • 입력되는 값이 복합형이라면 VO를 사용
      • 이 때는 반드시 #{ getter명 } , ${ getter 명 }을 사용
      • #은 바인드변수로 바뀜, $는 쿼리로 바뀜
        • 문자열일 때 바인드변수므로 작은 따옴표 안붙여도 됨
        • 문자열일 때 $라면 작은 따옴표를 사용해야 한다.
<!-- exam_mapper1.xml -->
...
      <!-- 컬럼 여러개 레코드 여러개 조회할 때 -->
      <select id="multiColumnRow" resultType="kr.co.sist.exam.domain.Emp" parameterType="int">
            SELECT empno, ename, job, sal, mgr,  TO_CHAR(hiredate,'yyyy-mm-dd q') hiredate
            FROM   emp
            WHERE  deptno = #{ deptno }
      </select>
...
package kr.co.sist.exam.domain;

public class Emp {
      private int empno, sal, mgr;
      private String ename, job, hiredate;
      // getter, setter 생성
      ...
// MyBatisDAO
...
      public List<Emp> multiColumnRow(int deptno) {
            List<Emp> list = null;
            
            // 4. MyBatis Handler 얻기
            SqlSession ss = getSessionFactory().openSession();

            // 5. mapper에서 쿼리가 존재하는 id 찾아 실행
            list = ss.selectList("multiColumnRow", deptno);
            ss.close();
            
            return list;
      }
...
// MyBatisService
...
      public List<Emp> multiColumnRow(int deptno) {
            List<Emp> list = null;
            
            MyBatisDAO mb_dao = MyBatisDAO.getInstance();
            list = mb_dao.multiColumnRow(deptno);
            
            return list;
      }
...
  • 페이지가 유지되도록 hidden 태그를 추가해서 page param을 전달
<!-- multi_column_row.jsp -->
...
<%
      MyBatisService mbs = new MyBatisService();
      List<Integer> deptnoList = mbs.multiRow();
      pageContext.setAttribute("deptnoList", deptnoList);


      String deptno = request.getParameter("deptno");
      if(deptno != null) {
            List<Emp> empList =  mbs.multiColumnRow(Integer.parseInt(deptno));
            pageContext.setAttribute("empList", empList);
      }
%>
<form name="frm" action="main.jsp">
<label>부서번호</label>
<select name="deptno">
      <c:forEach var="deptno" items="${ deptnoList }">
      <option value="${ deptno }"><c:out value="${ deptno }"  escapeXml="false"/></option>  
      </c:forEach>
</select>
<input type="hidden" name="page" value="date0405/multi_column_row"/>
<input type="submit" value="부서별 사원조회" class="btn"/>
</form>
<div>
<c:if test="${ not empty param.deptno }">
      <table border="1">
            <tr>
                  <th width="40">번호</th>
                  <th width="80">사원번호</th>
                  <th width="120">사원명</th>
                  <th width="80">매니저번호</th>
                  <th width="80">연봉</th>
                  <th width="150">입사일</th>
                  <th width="100">직무</th>
            </tr>
            <c:if test="${ empty empList }">
            <tr>
                  <td colspan="7" align="center">
                        <strong>${ param.deptno }</strong>번 부서에는  사원이 존재하지 않습니다.
                  </td>
            </tr>
            </c:if>
            <c:forEach var="emp" items="${ empList }">
            <c:set var="i" value="${ i+1 }"/>
            <tr>
                  <td><c:out value="${ i }"/></td>
                  <td><c:out value="${ emp.empno }"/></td>
                  <td><c:out value="${ emp.ename }"/></td>
                  <td><c:out value="${ emp.mgr }"/></td>
                  <td><c:out value="${ emp.sal }"/></td>
                  <td><c:out value="${ emp.hiredate }"/></td>
                  <td><c:out value="${ emp.job }"/></td>
            </tr>
            </c:forEach>
      </table>
</c:if>
</div>

01

resultMap 노드

02

  • resultMap
    • 조회하는 컬럼과 Domain의 setter를 미리 mapping시키는 일을 함
    • 조회결과를 미리 매핑한 resultMap노드를 선언했다면 select노드에서에서 resultMap 속성을 사용
<!-- mapper.xml -->
...
<mapper namespace="kr.co.sist.exam1">
    <resultMap id="mapId" type="패키지명.Domain명">
        <result column="컬럼명" property="setter명"/>
        ...
    </resultMap>
    ...
    <select id="아이디" parameterMap="Map" parameterType="기본형" resultMap="mapId">
        ...
    </selecT>
...
  • 컬럼명은 대소문자 구분하지 않음, setter는 대소문자 구분
<!-- exam_mapper1.xml -->
...
<mapper namespace="kr.co.sist.exam1">
      <!-- Emp Domain을 resultMap으로 설정 -->
      <resultMap type="kr.co.sist.exam.domain.Emp" id="empResult">
            <result column="empno" property="empno"/>
            <result column="ENAME" property="ename"/>
            <result column="job" property="job"/>
            <result column="sal" property="sal"/>
            <result column="hiredate" property="hiredate"/>
            <result column="MGR" property="mgr"/>
      </resultMap>
...
      <select id="multiColumnRow" resultMap="empResult"  parameterType="int">
            SELECT empno, ename, job, sal, mgr,  TO_CHAR(hiredate,'yyyy-mm-dd q') hiredate
            FROM   emp
            WHERE  deptno = #{ deptno }
      </select>
...

WHERE의 값이 여러개인 경우

  • parameterType에 VO를 설정하고 #{ getter명 }, ${ getter명 } 을 사용한다.
  • 입력되는(parameterType) 부서번호와 직무에 해당하는 사원 정보를 조회(resultType)
<!-- exam_mapper1.xml -->
...
      <!--  조회 컬럼이 여러개인 경우 -->
      <select id="multiparam" parameterType="kr.co.sist.exam.vo.EmpVO"  resultMap="empResult">
            SELECT empno, ename, job, sal, mgr,  TO_CHAR(hiredate,'yyyy-mm-dd q') hiredate
            FROM   emp
            WHERE  deptno = #{ deptno } and job=#{ job }
      </select>
...
package kr.co.sist.exam.vo;
public class EmpVO {
      private int deptno;
      private String job;
      // 인자있는 생성자, getter, setter 생성
      ...
public class MyBatisDAO1 {
      public List<Emp> multiParam(EmpVO ev) {
            List<Emp> list = null;
            // 4. 핸들러 얻기
            SqlSession ss =  MyBatisDAO.getInstance().getSessionFactory().openSession();
            
            list = ss.selectList("multiparam", ev);
            ss.close();
            
            return list;
      }
}
public class MyBatisService1 {
      public List<Emp> multiParam(EmpVO ev) {
            List<Emp> list = null;
            
            MyBatisDAO1 mb_dao1 = new MyBatisDAO1();
            list = mb_dao1.multiParam(ev);
            
            return list;
      }
}
<!-- multi_param.jsp -->
...
<%
      String deptno = request.getParameter("deptno");
      String job = request.getParameter("job");
      
      if(deptno != null && job != null) {
            MyBatisService1 mbs = new MyBatisService1();

            EmpVO ev = new EmpVO(Integer.parseInt(deptno), job);
            List<Emp> empList = mbs.multiParam(ev);

            pageContext.setAttribute("empList", empList);
      }
%>
<form name="frm" action="main.jsp">
<label>부서번호</label>
<c:set var="deptno" value="10,20,30,40"/>
<c:forTokens items="${ deptno }" delims="," var="deptno">
      <input type="radio" name="deptno" value="${ deptno }"/>
      <c:out value="${ deptno }" escapeXml="false"/>
</c:forTokens>
<br/>
<label>직무</label>
<c:set var="job" value="ANALYST,CLERK,MANAGER,SALESMAN,PRESIDENT"/>
<c:forTokens items="${ job }" delims="," var="job">
      <input type="radio" name="job" value="${ job}"/>
      <c:out value="${ job }" escapeXml="false"/>
</c:forTokens>
<input type="hidden" name="page" value="date0405/multi_param"/><br/>
<input type="submit" value="부서별 사원조회" class="btn"/>
</form>
<div>
<c:if test="${ not empty param.deptno }">
      <table border="1">
            <tr>
                  <th width="40">번호</th>
                  <th width="80">사원번호</th>
                  <th width="120">사원명</th>
                  <th width="80">매니저번호</th>
                  <th width="80">연봉</th>
                  <th width="150">입사일</th>
                  <th width="100">직무</th>
            </tr>
            <c:if test="${ empty empList }">
            <tr>
                  <td colspan="7" align="center">
                        <strong>${ param.deptno }</strong>번 부서에는  사원이 존재하지 않습니다.
                  </td>
            </tr>
            </c:if>
            <c:forEach var="emp" items="${ empList }">
            <c:set var="i" value="${ i+1 }"/>
            <tr>
                  <td><c:out value="${ i }"/></td>
                  <td><c:out value="${ emp.empno }"/></td>
                  <td><c:out value="${ emp.ename }"/></td>
                  <td><c:out value="${ emp.mgr }"/></td>
                  <td><c:out value="${ emp.sal }"/></td>
                  <td><c:out value="${ emp.hiredate }"/></td>
                  <td><c:out value="${ emp.job }"/></td>
            </tr>
            </c:forEach>
      </table>
</c:if>
</div>
  • 선택한 라디오 버튼이 유지되도록 만들기
...
<label>부서번호</label>
<c:set var="deptno" value="10,20,30,40"/>
<c:forTokens items="${ deptno }" delims="," var="deptno">
      <input type="radio" name="deptno" value="${ deptno }" ${ deptno eq  param.deptno ? "checked='checked'" : "" }/>
      <c:out value="${ deptno }" escapeXml="false"/>
</c:forTokens>
<br/>
<label>직무</label>
<c:set var="job" value="ANALYST,CLERK,MANAGER,SALESMAN,PRESIDENT"/>
<c:forTokens items="${ job }" delims="," var="job">
      <input type="radio" name="job" value="${ job}" ${ job eq param.job  ? "checked='checked'" : "" }/>
      <c:out value="${ job }" escapeXml="false"/>
</c:forTokens>
...

03

SQL 노드

04

  • 중복사용되는 쿼리를 sql노드에 설정하고
<sql id="아이디">
    중복 쿼리
</sql>
  • 사용될 때 include해서 사용
<include refid="아이디"/>
  • SQL 노드 사용 예
    • 중복 쿼리가 존재
...
      <select id="multiColumnRow" resultMap="empResult"  parameterType="int">
            SELECT empno, ename, job, sal, mgr,  TO_CHAR(hiredate,'yyyy-mm-dd q') hiredate
            FROM   emp
            WHERE  deptno = #{ deptno }
      </select>
      <select id="multiparam" parameterType="kr.co.sist.exam.vo.EmpVO"  resultMap="empResult">
            SELECT empno, ename, job, sal, mgr,  TO_CHAR(hiredate,'yyyy-mm-dd q') hiredate
            FROM   emp
            WHERE  deptno = #{ deptno } and job=#{ job }
      </select>
...
...
      <!-- sql 노드를 사용해서 중복 쿼리를 줄임 -->
      <sql id="empDup">
            SELECT empno, ename, job, sal, mgr,  TO_CHAR(hiredate,'yyyy-mm-dd q') hiredate
            FROM   emp
      </sql>
...
      <select id="multiColumnRow" resultMap="empResult"  parameterType="int">
            <include refid="empDup"/>
            WHERE  deptno = #{ deptno }
      </select>
      <select id="multiparam" parameterType="kr.co.sist.exam.vo.EmpVO"  resultMap="empResult">
            <include refid="empDup"/>
            WHERE  deptno = #{ deptno } and job=#{ job }
      </select>
...

<의 조회

  • 사원테이블에서 입력된 연봉보다 적게 받는 사원의 사원 번호, 사원명, 직무, 매니저번호, 입사일을 조회
  • ’<’는 직접 사용할 수 없다.
    • ‘&lt’을 사용.
<!-- exam_mapper1.xml -->
...
      <!-- < 의 조회 -->
      <select id="lessThan" resultMap="empResult"  parameterType="Integer">
            <include refid="empDup"/>
            WHERE sal &lt; #{ sal }
      </select>
...
  • ’<’를 직접 사용하고 싶다면 CDATA Section을 사용한다.
    • CDATA Section 사이는 노드가 아닌 단순한 문자열임을 알려주는 것
<![CDATA[
    CDATA Section
]]>
...
      <select id="lessThan" resultMap="empResult"  parameterType="Integer">
            <include refid="empDup"/>
            <![CDATA[
                WHERE sal < #{ sal }
            ]]>
      </select>
...
// MyBatisDAO1
      ...
      public List<Emp> lessThan(int sal) {
            List<Emp> list = null;
            
            SqlSession ss =  MyBatisDAO.getInstance().getSessionFactory().openSession();
            list = ss.selectList("lessThan",sal);
            ss.close();
            
            return list;
      }
      ...
// MyBatisService1
      ...
      public List<Emp> lessThan(int sal) {
            List<Emp> list = null;
            
            if (sal < 0) { // 음수는 절대값 처리
                  sal = Math.abs(sal);
                  // 또는 sal = -sal;
            }
            
            MyBatisDAO1 mb_dao1 = new MyBatisDAO1();
            list = mb_dao1.lessThan(sal);
            
            return list;
      }
}
<!-- main_menu.jsp -->
...
<li><a href="main.jsp?page=date0405/less_than">&lt;의 비교</a></li>
...
<!-- less_than.jsp -->
<%
      MyBatisService1 mbs = new MyBatisService1();
      String sal = request.getParameter("sal");
      
      if(sal != null) {
            List<Emp> list = mbs.lessThan(Integer.parseInt(sal));
            pageContext.setAttribute("empList", list);
      }
%>
<form name="frm" action="main.jsp">
<label>연봉</label>
<input type="text" name="sal" class="inputBox"/>
<input type="hidden" name="page" value="date0405/less_than"/>
<input type="submit" value="사원조회" class="btn"/>
</form>
<div>
<c:if test="${ not empty param.sal }">
      <div>
            ${ param.sal } 보다 연봉을 적게 받는 사원 정보
      </div>
      <table border="1">
            <tr>
                  <th width="40">번호</th>
                  <th width="80">사원번호</th>
                  <th width="120">사원명</th>
                  <th width="80">매니저번호</th>
                  <th width="80">연봉</th>
                  <th width="150">입사일</th>
                  <th width="100">직무</th>
            </tr>
            <c:if test="${ empty empList }">
            <tr>
                  <td colspan="7" align="center">
                        <strong>${ param.sal }</strong>보다 적게 받는  사원은 존재하지 않습니다.
                  </td>
            </tr>
            </c:if>
            <c:forEach var="emp" items="${ empList }">
            <c:set var="i" value="${ i+1 }"/>
            <tr>
                  <td><c:out value="${ i }"/></td>
                  <td><c:out value="${ emp.empno }"/></td>
                  <td><c:out value="${ emp.ename }"/></td>
                  <td><c:out value="${ emp.mgr }"/></td>
                  <td><c:out value="${ emp.sal }"/></td>
                  <td><c:out value="${ emp.hiredate }"/></td>
                  <td><c:out value="${ emp.job }"/></td>
            </tr>
            </c:forEach>
      </table>
</c:if>
</div>

05

> 의 조회

  • ’>’는 ‘<’와 다르게 에러가 안난다.
    • &gt도 사용 가능하다.
  • 사원테이블에서 입력된 연봉보다 많이 받는 사원의 empno, ename, job, sal, mgr, hiredate 조회
<!-- exam_mapper1.xml -->
...
      <!-- > 의 조회 -->
      <select id="greaterThan" resultMap="empResult"  parameterType="Integer">
            <include refid="empDup"/>
            WHERE sal > #{ sal }
      </select>
...
// MyBatisDAO1
...
      public List<Emp> greaterThan(int sal) {
            List<Emp> list = null;
            
            SqlSession ss =  MyBatisDAO.getInstance().getSessionFactory().openSession();
            list = ss.selectList("greaterThan",sal);
            ss.close();
            
            return list;
      }
...
// MyBatisService1
...
      public List<Emp> greaterThan(int sal) {
            List<Emp> list = null;
            
            if (sal < 0) { // 음수는 절대값 처리
                  sal = Math.abs(sal);
                  // 또는 sal = -sal;
            }
            
            MyBatisDAO1 mb_dao1 = new MyBatisDAO1();
            list = mb_dao1.greaterThan(sal);
            
            return list;
      }
}
<!-- main_menu.jsp -->
...
<li><a href="main.jsp?page=date0405/greater_than">&gt;의 비교</a></li>
...
<!-- greater_than.jsp -->
...
<%
      MyBatisService1 mbs = new MyBatisService1();
      String sal = request.getParameter("sal");
      
      if(sal != null) {
            List<Emp> list = mbs.greaterThan(Integer.parseInt(sal));
            pageContext.setAttribute("empList", list);
      }
%>
<form name="frm" action="main.jsp">
<label>연봉</label>
<input type="text" name="sal" class="inputBox"/>
<input type="hidden" name="page" value="date0405/greater_than"/>
<input type="submit" value="사원조회" class="btn"/>
</form>
<div>
<c:if test="${ not empty param.sal }">
      <div>
            ${ param.sal } 보다 연봉을 많이 받는 사원 정보
      </div>
      <table border="1">
            <tr>
                  <th width="40">번호</th>
                  <th width="80">사원번호</th>
                  <th width="120">사원명</th>
                  <th width="80">매니저번호</th>
                  <th width="80">연봉</th>
                  <th width="150">입사일</th>
                  <th width="100">직무</th>
            </tr>
            <c:if test="${ empty empList }">
            <tr>
                  <td colspan="7" align="center">
                        <strong>${ param.sal }</strong>보다 적게 받는  사원은 존재하지 않습니다.
                  </td>
            </tr>
            </c:if>
            <c:forEach var="emp" items="${ empList }">
            <c:set var="i" value="${ i+1 }"/>
            <tr>
                  <td><c:out value="${ i }"/></td>
                  <td><c:out value="${ emp.empno }"/></td>
                  <td><c:out value="${ emp.ename }"/></td>
                  <td><c:out value="${ emp.mgr }"/></td>
                  <td><c:out value="${ emp.sal }"/></td>
                  <td><c:out value="${ emp.hiredate }"/></td>
                  <td><c:out value="${ emp.job }"/></td>
            </tr>
            </c:forEach>
      </table>
</c:if>
</div>

06

LIKE 의 조회

  • 우편번호 검색
    • 동을 입력받아(parameterType) 우편번호, 시도, 구군, 동, 번지를 조회(resultType 또는 resultMap)
package kr.co.sist.exam.domain;

public class Zipcode {
      private String zipcode, sido, gugun, dong, bunji;
      // getter, setter
      ...
<!-- exam_mapper1.xml -->
...
      <!-- Zipcode Domain을 컬럼과 매핑 -->
      <resultMap id="zipcodeResult"  type="kr.co.sist.exam.domain.Zipcode">
            <result column="zipcode" property="zipcode"/>
            <result column="sido" property="sido"/>
            <result column="gugun" property="gugun"/>
            <result column="dong" property="dong"/>
            <result column="bunji" property="bunji"/>
      </resultMap>
...
      <!-- LIKE 의 조회 -->
      <select id="like" resultMap="zipcodeResult" parameterType="String">
            SELECT zipcode, sido, gugun, dong,  NVL(bunji, ' ') bunji
            FROM zipcode
            where dong LIKE '%'||#{ dong }||'%'
      </select>
...
// MyBatisDAO1
...
      public List<Zipcode> like(String dong) {
            List<Zipcode> list = null;
            
            SqlSession ss =  MyBatisDAO.getInstance().getSessionFactory().openSession();
            list = ss.selectList("like", dong);
            ss.close();
            
            return list;
      }
...
// MyBatisService1
...
      public List<Zipcode> like(String dong) {
            List<Zipcode> list = null;
            
            MyBatisDAO1 mb_dao1 = new MyBatisDAO1();
            list = mb_dao1.like(dong);
            
            return list;
      }
...
<!-- main_menu.jsp -->
...
<li><a href="main.jsp?page=date0405/like">LIKE의 조회</a></li>
...
<!-- like.jsp -->
<%
      MyBatisService1 mbs = new MyBatisService1();
      String dong = request.getParameter("dong");
      if(dong != null) {
            List<Zipcode> list = mbs.like(dong);
            pageContext.setAttribute("addrList", list);
      }
%>
<form name="frm" action="main.jsp">
<label>동 이름</label>
<input type="text" name="dong" class="inputBox"/>
<input type="hidden" name="page" value="date0405/like"/>
<input type="submit" value="검색" class="btn"/>
</form>
<div>
<c:if test="${ not empty param.dong }">
      <div>
            ${ param.dong } 의 조회
      </div>
      <table border="1">
            <tr>
                  <th width="100">우편번호</th>
                  <th width="400">주소</th>
            </tr>
            <c:if test="${ empty addrList }">
            <tr>
                  <td colspan="7" align="center">
                        <strong>${ param.dong }</strong>은 존재하지  않습니다.
                  </td>
            </tr>
            </c:if>
            <c:forEach var="addr" items="${ addrList }">
            <tr>
                  <td>
                        <c:out value="${ addr.zipcode }"/>
                  </td>
                  <td>
                        <c:out value="${ addr.sido } ${ addr.gugun } ${  addr.dong } ${ addr.bunji }"/>
                  </td>
            </tr>
            </c:forEach>
      </table>
</c:if>
</div>

07



Java EEMyBatis