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);
'개발노트 > jqGrid' 카테고리의 다른 글
[jqGrid] 주요 메서드와 이벤트 총정리 (0) | 2025.01.22 |
---|---|
[jqGrid] jqGrid + MyBatis로 오름차/내림차 동적 정렬 구현하기 (1) | 2025.01.20 |
[jqGrid] 이벤트 핸들링 - ready, loadComplete, onSelectRow, change (3) | 2025.01.02 |
[jqGrid] 그리드 데이터 다루기 - 값 가져오기/수정하기 (3) | 2025.01.01 |
[jqGrid] SubGrid로 상세 데이터 표시하기 (1) | 2024.12.31 |