Kim VamPa

[Spring][쇼핑몰 프로젝트][15] 작가목록 기능 구현 - 1 본문

스프링 프레임워크/쇼핑몰 프로젝트

[Spring][쇼핑몰 프로젝트][15] 작가목록 기능 구현 - 1

Kim VamPa 2021. 3. 10. 13:52
728x90
반응형
프로젝트 Github : https://github.com/sjinjin7/Blog_Project
프로젝트 포스팅 색인(index) : https://kimvampa.tistory.com/188

목표

작가 목록 출력 쿼리 구현

 이번 포스팅부터는 작가 관리 페이지(authorManage.jsp)에 작가 목록을 출력을 구현하는 것을 목표로 합니다. 해당 구현은 게시판의 목록 구현과 동일합니다. '게시판 프로젝트' 에서 "[2] 게시판 목록 기능 구현", "[6] 페이징 기능 구현", "[7] 검색 기능 구현" 포스팅 내용을 활용하여 진행합니다. '게시판 프로젝트' 포스팅에서 자세하게 설명하였기 때문에 최대한 진행위주로 작성하겠습니다.

 

서울 자유 게시판

 먼저 정해진 갯수와 페이지의 작가 정보를 출력(빨강색)을 구현한 뒤, 사용자가 마우스를 통해 페이지 이동을 할 수 잇도록 '페이지 이동 인터페이스'(파랑색)을 구현하겠습니다.

 

 이번 포스팅에서는 지정한 수만큼 작가 데이터를 출력시키는데 필요로 한 쿼리 작성과 해당 쿼리를 호출하는 Mapper 작성을 목표로 합니다.

 

 

 

순서

0. 수정사항

1. Criteria 작성

2. AuthorMapper.java

3. AuthorMapper.xml

4. AuthorMapper 메서드 테스트 

 

 

 

0. 수정사항

1) admin폴더 css 파일 코드 수정

 

 /resource/admin 폴더에 있는 css 모든 파일에 ". admin_content_wrap" 식별자가 가지고 있는 height 속성을 지우고 min-height 속성을 작성합니다. height 속성의 경우 고정된 높이지만, min-height 속성의 경우는 속성 값으로 최소 높이를 설정하여 속성 값보다 높이가 작아지는 것을 방지하면서 그 이상의 높이는 유동적으로 변경될 수 있도록 해줍니다.

 

 적용 대상 파일 : authorEnroll.css, authorManage.css, goodsEnroll.css, goodsManage.css, main.css

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
/* 기존 코드 */
.admin_content_wrap{
    width: 80%;
    float:left;
    height: 100%;  
    height:700px;
}
 
/* 수정 코드 */
.admin_content_wrap{
    width: 80%;
    float:left;
    min-height:700px;
}

 

그림 0-1

 

그림 0-2

 

 

 

2) admin 폴더 jsp파일 include 태그 적용

 

 admin 폴더에서 중복이자 공통적으로 적용되는 코드를 <include>태그를 적용을 합니다. 각 jsp파일마다 변경될 코드에 집중할 수 있도록 하기 위함입니다. 더불어 공통되는 코드들을 하나의 파일로 관리하는 것이기 때문에 유지보수에도 용이합니다.

 

 "../WEB-INF/views"경로에 "includes/admin" 폴더를 생성 후 'header.jsp', footer.jsp' 파일을 생성합니다. 각 파일에 아래의 코드만 남기고 모든 태그 코드를 삭제합니다.

 

1
2
3
4
 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 

 

그림 0-3

 

그림 0-4

 

그림 0-5

 

 admin폴더에 있는 jsp 파일 중 한 파일을 선택해서 <body> 태그 다음의 코드부터 class 속성 값이 'admin_content_wrap'인 <div> 태그 이전 코드까지 복사하여 head.jsp 파일에 붙여 넣습니다.

 

그림 0-6

 

그림 0-7

 

 class 속성 값이 'admin_content_wrap'인 <div> 태그 다음 코드부터 </body> 혹은 <script> 태그 이전 코드들을 복사하여 "footer.jsp"파일에 붙여 넣습니다.

 

그림 0-8

 

그림 0-9

 

 아래의 코드를 view/admin 폴더에 있는 모든 파일에 위에서 복사한 코드들과 동일한 코드들을 아래의 태그로 변경해줍니다.

 

1
2
3
4
5
 
    <%@include file="../includes/admin/header.jsp" %>
 
    <%@include file="../includes/admin/footer.jsp" %>
 

 

그림 0-10

 

그림 0-11

 

그리 0-12

 

그림 0-13

 

 서버를 실행하여 관리자 페이지가 정상적으로 출력이 되는지 확인합니다.

 

그림 0-14

 

그림 0-15

 

 

 

1. Criteria 클래스 작성

 

 com.vam.model 패키지에 Criteria.java 클래스를 생성 후 아래의 코드를 작성합니다. 해당 클래스는 지정한 개수와 검색조건에 따라서 작가 데이터를 출력하는 쿼리를 실행하는데 필요로 한 데이터들의 모임입니다. 참고로 Criteria는 기준이라는 의미입니다. 자세한 설명은 아래의 포스팅의 Criteria 설명을 참고해주세요.

 

[스프링 게시판][6] 페이징 기능 구현(페이징 쿼리 적용)

[스프링 게시판][7] 검색 기능 구현(제목 검색)

[스프링 게시판][7] 주제별 검색 기능 구현

 

Oracle 프로젝트

 

먼저 아래의 코드를 추가합니다.

 

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
 
    /* 현재 페이지 번호 */
    private int pageNum;
    
    /* 페이지 표시 개수 */
    private int amount;
    
    /* 검색 타입 */
    private String type;
    
    /* 검색 키워드 */
    private String keyword;
    
    /* Criteria 생성자 */
    public Criteria(int pageNum, int amount) {
        this.pageNum = pageNum;
        this.amount = amount;
    }
    
    /* Criteria 기본 생성자 */
    public Criteria(){
        this(1,10);
    }
    
    /* 검색 타입 데이터 배열 변환 */
    public String[] getTypeArr() {
        return type == nullnew String[] {}:type.split("");
    }
 

 

 - "[스프링 게시판][7] 주제별 검색 기능 구현"에서는 배열 타입의 typeArr 변수를 선언하여 검색 조건(type) 데이터를 배열로 다시 변환하여 typeArr 변수에 저장하였습니다. 이번 포스팅에서는 typeArr 변수를 굳이 선언하지 않고, 검색 조건(type) 데이터를 배열로 변화한 데이터로 반환해주는 getTypeArr() 메서드만 선언하였습니다. MyBatis xml의 쿼리에서 #{typeArr} 파라미터를 호출하기 위해서 "getTypeArr()"메서드를 호출하기 때문에 typeArr변수를 선언하지 않았음에도 해당 변수가 존재하는 것처럼 처리가 됩니다. (지금 이해가 되지 않는다면 그냥 넘어가셔도 됩니다.)

 

 

 작성한 변수들에 대한 getter/setter, toString 메서드를 선언해줍니다.

 

그림 1-1

 

그림 1-2

 

ㅡ림 1-3

 

MySQL 프로젝트

 

 MySQL 프로젝트의 쿼리의 경우 limit을 활용할 것이기 때문에 Criteria클래스에 아래와 같이 작성합니다. Oracle에서의 Criteria 클래스와 다른 점은 skip 변수가 추가된 점과 생성자에서 해당 변수의 값을 초기화시켜주는 코드가 추가된 점입니다.

 

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
 
    /* 현재 페이지 번호 */
    private int pageNum;
    
    /* 페이지 표시 개수 */
    private int amount;
    
    /* 페이지 skip */
    private int skip;
    
    /* 검색 타입 */
    private String type;
    
    /* 검색 키워드 */
    private String keyword;
    
    /* Criteria 생성자 */
    public Criteria(int pageNum, int amount) {
        this.pageNum = pageNum;
        this.amount = amount;
        this.skip = (pageNum -1* amount;
    }
    
    /* Criteria 기본 생성자 */
    public Criteria(){
        this(1,10);
    }
    
    /* 검색 타입 데이터 배열 변환 */
    public String[] getTypeArr() {
        return type == nullnew String[] {}:type.split("");
    }
 

 

그림 1-4

 

 동일하게 getter/setter, toString 메서드를 추가해줍니다.

 

 

 amout와 pageNum 변수의 값이 변경될때 skip변수의 값도 변경되도록 setAmout(), setPageNum() 메서드를 일부 수정해줍니다. Criteria 클래스의 데이터를 사용할 때 매번 새로운 생성자를 호출하여 사용하기 때문에 해당 과정이 필요 없지만 혹시 모를 경우를 위해 작업하였습니다.

 

그림 1-6

 

 

 

2. AuthorMapper.java 인터페이스

 

 작가 데이터 목록 쿼리를 실행하는 메서드를 선언합니다.  여러 작가의 데이터를 반환받아야 하기 때문에 리턴 타입으로 List 자료 구조를 지정하였습니다.(List는 배열과 비슷한 자료구조입니다. 배열과는 다르게 삽입되는 데이터에 따라 크기가 동적으로 변합니다.) List에 저장될 데이터가 AuthorVO(작가 정보) 임을 명시하기 위해 AuthorVO 제네릭을 선언하였습니다.

 

 List는 java.util.List를 import 해야 합니다.

 

1
2
3
 
public List<AuthorVO> authorGetList(Criteria cri);
 

 

그림 2-1

 

 

 

3. AuthorMapper.xml

 

  AuthorMapper.java 인터페이스에서 선언한 메서드가 실행할 쿼리 코드를 작성합니다. <select> 태그의 resultType 속성 값은 'com.vam.model.AuthorVO'을 부여합니다. resultType을 클래스로 지정하였지만 메서드의 리턴 타입을 List로 선언하였기 때문에 MyBatis가 지정된 클래스 인스턴스를 요소를 가지는 List로 자동으로 변환해줍니다.

 

 사용한 쿼리에 대한 설명은 아래의 링크를 참고해주세요. 

 

[스프링 게시판][6] 페이징 기능 구현(페이징 쿼리 정리)

[스프링 게시판][6] 페이징 기능 구현(페이징 쿼리 적용)

 

Oracle 프로젝트

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
      <!-- 작가 목록 -->
      <select id="authorGetList" resultType="com.vam.model.AuthorVO">
      
      <![CDATA[
          select * from (
              select /*+INDEX_DESC(vam_author 인덱스명) */ 
                  rownum as rn, authorid, authorname, nationid, regdate, updatedate
            from vam_author 
            where
             
    ]]>         
            <if test="keyword != null">
                authorname like '%'||#{keyword}||'%' and
            </if>
            
    <![CDATA[        
             rownum <= #{pageNum}*#{amount}
            )
        where rn > (#{pageNum} - 1) * #{amount}
      ]]>
      
      </select>
 

 

그림 3-1

 

※ '인덱스 힌트'인 "/*+INDEX_DESC(테이블명 인덱스명)*/"을 작성해주어야 하는데 우리는 인덱스(index)를 지정해주지 않았습니다. 하지만 기본키를 설정을 하게 되면 오라클에서 자동으로 기본키 칼럼(column)을 대상으로 하는 인덱스(index)를 생성합니다. 따라서 자동으로 생성된 인덱스를 찾아서 인덱스명을 입력해주면 됩니다.

 

 생성된 인덱스를 찾는 명령어는 아래와 같습니다.

 

그림 3-2

 

그림 3-2

 

 

 

MySQL 프로젝트

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
    <!-- 작가 목록 -->
    <select id="authorGetList" resultType="com.vam.model.AuthorVO">
    
        select  authorid, authorname, nationid, regdate, updatedate
        from vam_author 
        <if test="keyword != null">
            where authorname like concat('%',#{keyword}, '%')
        </if>
        order by authorid desc 
        limit #{skip}, #{amount}    
    
    </select>
 

 

 

 

 

4. AuthorMapper 메서드 테스트 

 새로 작성한 authorGetList() 메서드가 정상적으로 동작하는지 확인하기 위해 테스트를 진행합니다.

 

 테스트하기 앞서 페이징 적용이 되는지 확인하기 위해서 재귀 복사를 통해 여러 행을 추가해주었습니다. Oralce의 경우 아래의 명령어를 실행 한 뒤 반드시 "commit;" 명령어를 실행해줍니다.

 

1
2
3
4
 
    --재귀 복사
    insert into vam_author(authorname, nationid)(select authorname, nationid from vam_author);
 

 

그림 4-1 Oracle

 

그림 4-2 MySQL

 

 AuthorMapperTests.java 클래스에 기존 테스트 코드는 주석 처리를 한 후 아래의 코드를 추가합니다. Junit 테스트를 하여 정상적으로 동작하는지를 확인합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
    /* 작가 목록 테스트 */
    @Test
    public void authorGetListTest() throws Exception{
        
        Criteria cri = new Criteria(3,10);    // 3페이지 & 10개 행 표시
        
        List<AuthorVO> list = mapper.authorGetList(cri);
        
        for(int i = 0; i < list.size(); i++) {
            System.out.println("list" + i + ".........." + list.get(i));
        }
        
    }
 

 

그림 4-3

 

그림 4-4

 

그림 4-5

 

 검색어를 입력한 경우에도 쿼리가 정상적으로 동작하는지를 확인하기 위해서 keyword 변수에 데이터를 부여한 후 테스를 진행합니다.

 

그림 4-6

 

그림 4-7

 

 

 

REFERENCE

  •  

DATE

  • 2020.03.10
728x90
반응형
Comments