BackEnd/WEB

MyBatis_SubQuery_국비Day75

Leo.K 2022. 6. 17. 14:53

초기 프로젝트에 mybatis설정하는 순서 [복사해오는 경우 안 쓰는 내용을 수정하지 말고 모두 삭제해서 새로 만들자.]

  1. mybatis라이브러리 셋팅하기   (WEB-INF)
  2. context.xml파일 가져오기         (META-INF)
  3. sqlMapConfig.xml과 mapper파일 ~~.xml을 생성한다. (복사하는 경우 mapper파일의 명령은 모두 지우자.(에러가 발생할 가능성이 있음.))
  4. MyBatisConnector 생성하기 -> SqlSessionFactory를 만들어 주는 객체

 

[ mybatis를 사용한 서브쿼리 구현하기 ]

1. dept_list가 호출되면, dept테이블에서 읽어온 deptno, dname, loc데이터를 dept_map으로 포장해서 반환한다.

2. 1에서 반환한 dept_map을 수신해서 새로운 명령을 호출한다. 여기서 Vo가 가진 속성명을 property라고 하고, DB가 가진 컬럼명을 column이라고 한다. 위의 이미지를 보면 속성명과 컬럼명이 동일하면 생략이 가능하다고 했지만, 기본키는 생략할 수 없다. -> deptno

기본키인 deptno를 인자로 넘기면서 sawon_list_deptno2를 호출한다. deptno가 전달받은 인자와 같은 레코드(SawonVo)를 사원테이블에서 찾아서 반환하는데(SawonVo을 요소로 가지는 list를 반환한다.) 이 반환된 리스트를 deptVo의 sa_list에 저장한다.

위에서 반환되는 결과를 시각화 시키면 아래와 같다. 예를 들면 10번 부서에 대한 사원 목록을 리스트 형태(sa_list)로 저장해서 DeptVo의 vo에 저장하고 이 vo들을 리스트 형태로 반환한 것이 list이다.

 

[ 심화 응용 과제 ]

특정 부서에 포함된 사원이 담당하는 고객리스트를 출력하라. 구조를 이해하는데 굉장히 어려웠다.. 덤으로 복잡해서 머리가 터질뻔했다. 아래와 같은 구조를 같도록 코드를 조금만 수정해주자. 

1~5~1의 과정으로 설명을 하겠다. 천천히 따라와보면서 어떻게 도식화된 구조가 완성되는지 살펴보자.

  • 1 : dept_list로 매핑되는 명령문을 수행하여, 나오는 결과를 dept_map으로 포장한다. 
  • 2 : dept_map을 인자로 받아서 새로운 함수를 호출하는데, 그 함수에 넘겨줄 인자로 기본키 deptno를 전달한다. 이때, 속성명과 컬럼명이 동일한 경우에만 생략이 가능한 것이다. 하지만 DB의 컬럼명과 Vo의 속성명이 다르다면 아래 이미지와 같이 dept_map에 있는 모든 property와 column을 설정해주어야 한다. 필자는 이름을 맞추어놔서 기본키만 넘겼다. 지난 시간에도 강조했듯이 Vo속성명 == DB컬럼명 기본적으로 맞추고 가자. 상당히 편하다...
  • 3: 기본키 deptno를 받아서 명령을 수행하고 명령의 결과를 다시 sawon_map으로 포장한다.
  • 4 : 3에서 포장한 sawon_map을 인자로 받고 기본키만 다음으로 호출하는 명령에 전달한다. 
  • 5 : 4에서 전달받은 sabun을 이용해서 쿼리를 수행한다. 쿼리의 결과값에서 하나의 레코드를 GogekVo로 포장하고 이 vo들을 리스트로 포장해서 나를 호출한 4번으로 반환한다.
  • 4 : 5에서 반환값으로 받은 list를 SawonVo의 go_list에 저장한다. 나머지 sabun, saname, ... , go_list를 하나의 SawonVo로 포장하고 이 Vo들을 리스트로 포장해서 나를 호출한 3번으로 반환한다. 
  • 3 : 4에서 결과값으로 받은 리스트를 2에 전달한다. 
  • 2 : 3을 거쳐 4로부터 전달받은, SawonVo가 요소로 구성된 리스트를 DeptVo의 sa_list에 저장한다. deptno, dname, loc, sa_list를 하나의 DeptVo로 포장하고, 이 vo들을 리스트로 묶어서 나를 호출한 1번으로 반환한다. 
  • 1 : 전달받은 최종 리스트(도식화부분에서 stack영역에 표시된 list)를 나를 호출한 dao로 반환한다. 

위의 코드를 도식화 해보면 아래와 같다. 

코드는 이렇게 구현한다.

[ gogek.xml ]

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?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="dept">
    
    <!-- 2번 -->
    <!-- dept_map을 DeptVo에 Set한다. -->
    <resultMap type="vo.DeptVo" id="dept_map">
        <result property="deptno" column="deptno" />
        
        <!-- 인자가 하나인 경우는 column에 {}브레이스를 써도 되고 안써도 되지만, 2개 이상인 경우에는 반드시 {}를 사용해서 ,로 구분한다. -->
        <!-- sawon_list_deptno라는 id가 똑같더라도 namespace가 다르다면 물리적으로 다른 구조이므로 충돌이 발생하지 않는다. -->
        <!-- column="변수명=파라미터값" -->
        <collection property="sa_list" 
                    
                    column="{no=deptno}"    
                    select="sawon_list_deptno"
        />
        
    </resultMap>
    
    
    <!-- 4번 -->
    <resultMap type="vo.SawonVo" id="sawon_map">
        <result property="sabun" column="sabun"/>
        
        <collection property="go_list"
                    column="{sabun=sabun}"
                    select="gogek_list_godam"
        />
        
    </resultMap>
    
    
    <!-- 5번 -->
    <select id="gogek_list_godam" resultType="vo.GogekVo">
        select * from gogek where godam=#{sabun}
    </select>
    
    
    <!-- 3번 -->
    <!-- 파라미터는 외부에서 전달해주는 것이 아니라 서브쿼리처럼 특정 쿼리의 결과를 넘겨주는 등 내부에서 넘어오기 때문에 파라미터 타입이 필요x -->
    <select id="sawon_list_deptno" resultMap="sawon_map">
        select * from sawon where deptno=#{no}
    </select>
    
    
    <!-- 1번 -->
    <!-- dept_list select의 결과를 dept_map타입으로 포장하겠다. -->
    <select id="dept_list" resultMap="dept_map">
        select * from dept
    </select>
 
</mapper>
 
cs

 

[ dept_list.jsp ]

출력을 할 때는 JSTL을 사용해서 3중 반복문으로 출력해야 한다. 코드만 보면 이해하기 어려울 수 있으니 반드시 도식화된 내요을 확인하고, 구조를 이해한 뒤에 출력하는 연습을 해보도록 하자.

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
31
32
33
34
35
36
37
38
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
 
<hr>
    부서별 사원 담당 고객목록
<hr>
    <ul>
        <!-- for(DeptVo dept : list) -->
        <c:forEach var="dept" items="${list }">
            <li>
                ${dept.deptno }:${dept.dname }
                <ul>
                    <!-- for(Sawon sawon : dept.sa_list -->
                    <c:forEach var="sawon" items="${dept.sa_list }">
                        <li>
                            ${sawon.sabun }:${sawon.saname }
                            <ul>
                                <c:forEach var="gogek" items="${sawon.go_list }">
                                    <li>${gogek.gobun }:${gogek.goname }</li> 
                                </c:forEach>
                            </ul>
                        </li>
                    </c:forEach>
                </ul>
            </li>
        </c:forEach>
    </ul>
 
</body>
</html>
cs

 

결과는 아래와 같이 나온다.

'BackEnd > WEB' 카테고리의 다른 글

DispatcherServlet  (0) 2022.06.23
MVC_국비Day79  (0) 2022.06.23
mybatis_검색기능_국비Day74  (0) 2022.06.16
mybatis_국비Day73  (0) 2022.06.15
ORM_DB프레임워크_국비_DAY72  (0) 2022.06.14