1. emp list 페이징을 구현하시오.
1-1-1. 소스코드(Criteria 객체)
package edu.bit.ex.emp.page;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ToString
@Setter
@Getter
public class Criteria {
private int pageNum;
private int amount;
public Criteria() {
this(1, 10);
}
public Criteria(int pageNum, int amount) {
this.pageNum = pageNum;
this.amount = amount;
}
}
1-1-2. 소스코드(PageVO 객체)
package edu.bit.ex.emp.page;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public class PageVO {
private int startPage;
private int endPage;
private boolean prev, next;
private int total;
private Criteria cri;
public PageVO(Criteria cri, int total) {
this.cri = cri;
this.total = total;
this.endPage = (int) (Math.ceil(cri.getPageNum() / 10.0)) * 10;
this.startPage = this.endPage - 9;
int realEnd = (int) (Math.ceil((total * 1.0) / cri.getAmount()));
if (realEnd <= this.endPage) {
this.endPage = realEnd;
}
this.prev = this.startPage > 1;
this.next = this.endPage < realEnd;
}
public String makeQuery(int page) {
UriComponents uriComponentsBuilder = UriComponentsBuilder
.newInstance()
.queryParam("pageNum", page)
.queryParam("amount", cri.getAmount())
.build();
return uriComponentsBuilder.toUriString();
}
}
1-1-3. 소스코드(Controller 객체)
package edu.bit.ex.emp.controller;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import edu.bit.ex.emp.page.Criteria;
import edu.bit.ex.emp.page.PageVO;
import edu.bit.ex.emp.service.EmpService;
import edu.bit.ex.emp.vo.EmpVO;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
@Log4j
@AllArgsConstructor
@Controller
public class EmpController {
private EmpService empService;
// 직원 리스트
@GetMapping("/emp/list")
public void list(Model model) {
model.addAttribute("list", empService.getList());
log.info("list()");
}
// 페이징을 적용한 직원 리스트
@Transactional
@GetMapping("/emp/list2")
public void list2(Criteria cri, Model model) {
log.info("list2");
log.info(cri);
model.addAttribute("list", empService.getList(cri));
int total = empService.getTotal(cri);
log.info("total" + total);
model.addAttribute("pageMaker", new PageVO(cri, total));
}
...(생략)
}
1-1-4. 소스코드(Service 인터페이스)
package edu.bit.ex.emp.service;
import java.util.List;
import edu.bit.ex.emp.page.Criteria;
import edu.bit.ex.emp.vo.EmpVO;
public interface EmpService {
// 직원정보 리스트
public List<EmpVO> getList();
// 페이징을 적용한 직원정보 리스트
public List<EmpVO> getList(Criteria criteria);
public int getTotal(Criteria criteria);
...(생략)
}
1-1-5. 소스코드(ServiceImpl 객체)
package edu.bit.ex.emp.service;
import java.util.List;
import org.springframework.stereotype.Service;
import edu.bit.ex.emp.mapper.EmpMapper;
import edu.bit.ex.emp.page.Criteria;
import edu.bit.ex.emp.vo.EmpVO;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
@Log4j
@Service
@AllArgsConstructor
public class EmpServiceImpl implements EmpService {
private EmpMapper mapper;
// 직원 정보 리스트
@Override
public List<EmpVO> getList() {
log.info("getList()");
return mapper.getList();
}
// 페이징을 적용한 직원 정보 리스트
@Override
public List<EmpVO> getList(Criteria criteria) {
log.info("get List with criteria" + criteria);
return mapper.getListWithPaging(criteria);
}
@Override
public int getTotal(Criteria criteria) {
log.info("get total count");
return mapper.getTotalCount(criteria);
}
...(생략)
}
1-1-6. 소스코드(BoardMapper 객체)
package edu.bit.ex.emp.mapper;
import java.util.List;
import edu.bit.ex.emp.page.Criteria;
import edu.bit.ex.emp.vo.EmpVO;
public interface EmpMapper {
// 직원 정보 불러오기
public List<EmpVO> getList();
// 페이징을 적용한 직원 정보 불러오기
public List<EmpVO> getListWithPaging(Criteria criteria);
public int getTotalCount(Criteria criteria);
...(생략)
}
1-1-7. 소스코드(BoardMapper XML문서)
<?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="edu.bit.ex.emp.mapper.EmpMapper">
<!-- 전체 직원 정보 리스트 -->
<select id="getList" resultType="edu.bit.ex.emp.vo.EmpVO">
<![CDATA[
SELECT e.empno, e.ename, e.job, e.mgr, e.hiredate, e.sal, e.comm, d.deptno, d.dname, d.loc FROM dept01 d, emp01 e WHERE d.deptno = e.deptno AND e.mgr IN (SELECT employee.mgr FROM emp01 employee, emp01 manager WHERE employee.mgr = manager.empno)
]]>
</select>
<!-- 페이징을 적용한 전체 직원 정보 리스트 -->
<select id="getListWithPaging" resultType="edu.bit.ex.emp.vo.EmpVO">
<![CDATA[
SELECT * FROM (SELECT ROWNUM AS RNUM, A.* FROM (SELECT e.empno, e.ename, e.job, e.mgr, e.hiredate, e.sal, e.comm, d.deptno, d.dname, d.loc FROM emp01 e, dept01 d WHERE e.deptno = d.deptno) A WHERE ROWNUM <= #{pageNum}*#{amount}) WHERE RNUM > (#{pageNum}-1)*#{amount}
]]>
</select>
<select id="getTotalCount" resultType="int">
select count(*) from emp01
</select>
...(생략)
</mapper>
1-1-8. 소스코드(list2 JSP파일)
<%@ 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>
<head>
...(생략)
</head>
<body id="page-top">
...(생략)
<tbody>
<c:forEach items="${list}" var="dto">
<tr>
<td>${dto.empno}</td>
<td>${dto.ename}</td>
<td>${dto.job}</td>
<td>${dto.mgr}</td>
<td>${dto.hiredate}</td>
<td>${dto.sal}</td>
<td>${dto.comm}</td>
<td>${dto.deptno}</td>
<td>${dto.dname}</td>
<td>${dto.loc}</td>
<td><a href="modify_view?empno=${dto.empno}">관리</a></td>
</tr>
</c:forEach>
</tbody>
</table>
<c:if test="${pageMaker.prev}">
<a href="list2${pageMaker.makeQuery(pageMaker.startPage - 1)}">«</a>
</c:if>
<c:forEach begin="${pageMaker.startPage }" end="${pageMaker.endPage}" var="idx">
<c:out value="${pageMaker.cri.pageNum == idx?'':''}" />
<a href="list2${pageMaker.makeQuery(idx)}">${idx}</a>
</c:forEach>
<c:if test="${pageMaker.next && pageMaker.endPage > 0}">
<a href="list2${pageMaker.makeQuery(pageMaker.endPage +1)}"> » </a>
</c:if> <br>
...(생략)
</body>
</html>
1-2. 구현화면
2. 오라클 11g 이하에서의 페이징 처리 방법은 어떻게 하는가?
2-1. 오라클 11g 이하에서의 페이징 처리방법
: Top-N 쿼리를 수행하기 위해 Inline-View를 이용한다.
SELECT *
FROM (SELECT employee_id, last_name
FROM hr.employees
ORDER BY employee_id)
WHERE rownum <= 5;
※. 오라클 12g 부터 적용되는 페이징 처리방법
- ROW_NUMBER()를 이용하여 페이징을 적용한다.
SELECT * FROM (SELECT A.*, ROW_NUMBER() OVER(ORDER BY ID DESC) AS NUM FROM OP_SAMPLE A) WHERE NUM BETWEEN 999991 AND 1000000;
- 페이지 수를 계산한다.
SELECT B.* FROM (SELECT CEIL(ROWNUM/10) PAGE--, COUNT(*) OVER() AS TOTAL_COUNT, A.* FROM (SELECT * FROM OP_SAMPLE ORDER BY ID DESC) A) B WHERE PAGE = 100000;
- ROWNUM을 이용한다.
SELECT * FROM (SELECT ROWNUM AS RNUM, Z.* FROM (SELECT * FROM OP_SAMPLE ORDER BY ID DESC) Z WHERE ROWNUM <= 1000000) WHERE RNUM >= 999991;
- ROWNUM + 인덱스를 이용한다.
SELECT * FROM (SELECT /*+ INDEX_DESC(Z OP_SAMPLE_PK) */ ROWNUM AS RNUM, Z.* FROM (SELECT * FROM OP_SAMPLE) Z WHERE ROWNUM <= 1000000) WHERE RNUM >= 999991;
3. SQL의 ROWNUM 키워드에 대하여 설명하시오.
3-1. ROWNUM의 정의
: 조회된 순서대로 번호를 매겨 조회할 수 있는 키워드로 기존의 특정 컬럼내 속성값에 의존하여 순번을 매기지 않을 수 있는 장점이 있다. 또한 FROM 및 WHERE 절 처리 후, ROWNUM이 할당되어 해당 절에서 전달되는 각각의 출력 로우(ROW)에 대해 증가하는 특징이 있다.
※. SQL의 처리순서
- SELECT … 5th
- FROM … 1st
- WHERE … 2nd
- GROUP BY … 3rd
- HAVING … 4th
- ORDER BY … 6th
'WebDev > 본과정' 카테고리의 다른 글
DB의 설계와 Spring의 MockMVC (0) | 2021.05.16 |
---|---|
SQL의 더미 데이터 처리와 JUnit을 통한 테스트 (0) | 2021.05.16 |
Spring의 리소스 처리와 페이징 및 유효성 검사 (0) | 2021.05.16 |
JQuery 슬라이더와 달력 구현하기 (0) | 2021.05.16 |
Spring의 MVC 패턴 (0) | 2021.05.16 |
최근댓글