개발노트/jqGrid

[jqGrid] MyBatis 페이징 처리

dev-mylee 2025. 1. 15. 11:36

1. 페이징 처리의 핵심 요소

1.1 jqGrid 페이징 파라미터

  • page: 현재 페이지 번호
  • rows: 한 페이지당 표시할 행 수
  • sidx: 정렬 기준 컬럼
  • sord: 정렬 방향 (asc/desc)
  • _search: 검색 여부
  • total: 전체 페이지 수
  • records: 전체 레코드 수

1.2 핵심 클래스 구조

public class BoardVO {
    private int page = 1;     // 현재 페이지
    private int rows = 20;    // 페이지 사이즈
    private String sidx;      // 정렬 컬럼
    private String sord;      // 정렬 방향
    
    // jqGrid 페이징용 offset 계산
    public int getOffset() {
        return (page - 1) * rows;
    }
    
    // getter, setter...
}

 

2. 계층별 구현

2.1 JSP의 jqGrid 설정

$("#boardGrid").jqGrid({
    url: '/board/list',
    datatype: 'json',
    mtype: 'POST',
    colNames: ['번호', '제목', '작성자', '등록일', '조회수'],
    colModel: [
        {name: 'boardId', index: 'BOARD_ID', width: 80, align: 'center'},
        {name: 'boardTitle', index: 'BOARD_TITLE', width: 300},
        {name: 'writerId', index: 'WRITER_ID', width: 120},
        {name: 'regDate', index: 'REG_DATE', width: 120, align: 'center'},
        {name: 'viewCnt', index: 'VIEW_CNT', width: 80, align: 'center'}
    ],
    pager: '#pager',
    rowNum: 20,
    rowList: [10, 20, 30],
    sortname: 'regDate',
    sortorder: 'desc',
    viewrecords: true,
    caption: '게시판 목록',
    jsonReader: {
        root: "rows",
        page: "page",
        total: "total",
        records: "records",
        repeatitems: false,
        id: "boardId"
    }
});

 

 

2.2 Controller

@Controller
public class BoardController {
    @Autowired
    private BoardService boardService;
    
    @RequestMapping("/board/list")
    @ResponseBody
    public Map<String, Object> getBoardList(BoardVO boardVO) {
        // 게시물 목록 조회
        List<BoardVO> boardList = boardService.selectBoardList(boardVO);
        
        // 전체 데이터 개수 조회
        int records = boardService.selectBoardCount(boardVO);
        int total = (int) Math.ceil((double) records / boardVO.getRows());
        
        // jqGrid 응답 포맷에 맞춰 데이터 설정
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("page", boardVO.getPage());    // 현재 페이지
        resultMap.put("total", total);               // 전체 페이지 수
        resultMap.put("records", records);           // 전체 레코드 수
        resultMap.put("rows", boardList);            // 데이터 목록
        
        return resultMap;
    }
}

 

 

2.3 Mapper

<mapper namespace="com.example.mapper.BoardMapper">
    <select id="selectBoardList" parameterType="BoardVO" resultType="BoardVO">
        SELECT 
            BOARD_ID as boardId,
            BOARD_TITLE as boardTitle,
            WRITER_ID as writerId,
            REG_DATE as regDate,
            VIEW_CNT as viewCnt,
            NOTICE_YN as noticeYn
        FROM TB_BOARD
        WHERE DEL_YN = 'N'
        ORDER BY 
            NOTICE_YN DESC,  
            ${sidx} ${sord}  <!-- jqGrid 정렬 처리 -->
        LIMIT #{offset}, #{rows}
    </select>
</mapper>

 

 

 

3. 개선 포인트

3.1 동적 정렬 처리

<select id="selectBoardList">
    SELECT * FROM TB_BOARD
    WHERE DEL_YN = 'N'
    <choose>
        <when test="sidx != null and sidx != ''">
            ORDER BY 
                NOTICE_YN DESC,
                ${sidx} ${sord}
        </when>
        <otherwise>
            ORDER BY REG_DATE DESC
        </otherwise>
    </choose>
    LIMIT #{offset}, #{rows}
</select>

 

 

 

3.2 검색 조건 처리

<select id="selectBoardList">
    SELECT * FROM TB_BOARD
    <where>
        DEL_YN = 'N'
        <if test="_search">
            <if test="searchField == 'boardTitle'">
                AND BOARD_TITLE LIKE CONCAT('%', #{searchString}, '%')
            </if>
            <if test="searchField == 'writerId'">
                AND WRITER_ID LIKE CONCAT('%', #{searchString}, '%')
            </if>
        </if>
    </where>
    ORDER BY ...
</select>

 

 

 

 

4. 주의사항

  • sidx, sord는 SQL Injection 위험이 있으므로 허용된 컬럼만 사용하도록 처리
  • 정렬 컬럼에 인덱스 필수 생성
  • 공지사항은 항상 최상단에 위치하도록 정렬 처리
  • 날짜 형식은 자바스크립트 포맷과 맞춰서 처리

 

 

5. 성능 최적화 팁

  • 복합 인덱스 활용
-- 정렬 조건을 포함한 인덱스
CREATE INDEX IDX_BOARD_01 ON TB_BOARD(NOTICE_YN, REG_DATE, BOARD_ID);

 

  • 검색 조건 인덱스
-- 자주 사용되는 검색 조건 컬럼 인덱스
CREATE INDEX IDX_BOARD_02 ON TB_BOARD(BOARD_TITLE, WRITER_ID);