오라클(Oracle) 데이터베이스에서 페이징(Paging)을 구현하려면 ROWNUM 또는 ROW_NUMBER()를 사용하는 방식이 일반적입니다. 최신 오라클 버전에서는 FETCH FIRST를 활용하는 방식도 지원됩니다. 아래에 세 가지 방식을 각각 예제를 들어 설명드리겠습니다.
1. ROWNUM을 사용한 페이징
SELECT *
FROM (
SELECT ROWNUM AS RNUM, A.*
FROM (
SELECT *
FROM 테이블명
ORDER BY 컬럼명 ASC
) A
WHERE ROWNUM <= :최대_행_번호 -- 끝 번호
)
WHERE RNUM >= :최소_행_번호; -- 시작 번호
설명:
- 내부 쿼리에서 데이터를 정렬 후 ROWNUM으로 행 번호를 부여합니다.
- 원하는 시작 번호와 끝 번호 범위에 맞게 필터링합니다.
2. ROW_NUMBER()를 사용한 페이징
SELECT *
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY 컬럼명 ASC) AS RNUM,
A.*
FROM 테이블명 A
)
WHERE RNUM BETWEEN :시작_번호 AND :끝_번호;
설명:
- ROW_NUMBER() 함수는 정렬 기준에 따라 고유한 행 번호를 생성합니다.
- 외부 쿼리에서 BETWEEN 조건으로 범위를 지정하여 페이징 처리합니다.
3. FETCH FIRST를 사용한 페이징 (Oracle 12c 이상)
SELECT *
FROM 테이블명
ORDER BY 컬럼명 ASC
OFFSET :건너뛸_행_수 ROWS FETCH NEXT :가져올_행_수 ROWS ONLY;
설명:
- OFFSET은 건너뛸 행의 수를 지정합니다.
- FETCH NEXT는 가져올 행의 수를 지정합니다.
- 더 간단하고 가독성이 좋지만, 오라클 12c 이상에서만 사용할 수 있습니다.
예제 데이터 및 실행
예를 들어, 직원 테이블에서 10번째부터 19번째 데이터를 가져오려면:
ROWNUM 방식
SELECT *
FROM (
SELECT ROWNUM AS RNUM, A.*
FROM (
SELECT *
FROM EMPLOYEES
ORDER BY EMPLOYEE_ID ASC
) A
WHERE ROWNUM <= 20
)
WHERE RNUM >= 10;
ROW_NUMBER() 방식
SELECT *
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY EMPLOYEE_ID ASC) AS RNUM,
A.*
FROM EMPLOYEES A
)
WHERE RNUM BETWEEN 10 AND 19;
FETCH FIRST 방식
SELECT *
FROM EMPLOYEES
ORDER BY EMPLOYEE_ID ASC
OFFSET 9 ROWS FETCH NEXT 10 ROWS ONLY;
페이징을 스토어프로시져로 한다면 ?
오라클에서 페이징 처리를 스토어드 프로시저(Stored Procedure)로 구현하는 방법을 예제로 보여드리겠습니다. 아래는 ROW_NUMBER()를 활용한 방식으로 구현한 스토어드 프로시저입니다.
스토어드 프로시저 구현
1. 기본 구조
CREATE OR REPLACE PROCEDURE PAGING_PROC (
P_PAGE_NUMBER IN NUMBER, -- 요청 페이지 번호
P_PAGE_SIZE IN NUMBER, -- 페이지 크기 (한 페이지당 행 수)
P_RESULT OUT SYS_REFCURSOR -- 결과를 반환할 커서
)
AS
V_OFFSET NUMBER; -- 건너뛸 행의 수
V_FETCH_SIZE NUMBER; -- 가져올 행의 수
BEGIN
-- OFFSET 계산
V_OFFSET := (P_PAGE_NUMBER - 1) * P_PAGE_SIZE;
V_FETCH_SIZE := P_PAGE_SIZE;
-- REF CURSOR에 결과 할당
OPEN P_RESULT FOR
SELECT *
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY EMPLOYEE_ID ASC) AS RNUM, -- 정렬 기준 필요
E.*
FROM EMPLOYEES E
)
WHERE RNUM BETWEEN V_OFFSET + 1 AND V_OFFSET + V_FETCH_SIZE;
END PAGING_PROC;
/
2. 프로시저 호출
스토어드 프로시저를 호출하려면 아래처럼 실행합니다:
VARIABLE P_CURSOR REFCURSOR;
BEGIN
PAGING_PROC(
P_PAGE_NUMBER => 2, -- 두 번째 페이지
P_PAGE_SIZE => 10, -- 페이지당 10행
P_RESULT => :P_CURSOR -- 결과 커서에 저장
);
END;
/
-- 결과 확인
PRINT P_CURSOR;
상세 설명
- 매개변수
- P_PAGE_NUMBER: 요청한 페이지 번호를 지정합니다.
- P_PAGE_SIZE: 한 페이지에 표시할 행 수를 지정합니다.
- P_RESULT: 결과를 반환받기 위한 커서입니다.
- 페이징 로직
- V_OFFSET은 (페이지 번호 - 1) * 페이지 크기로 계산됩니다.
- ROW_NUMBER()를 사용하여 각 행에 고유 번호를 부여합니다.
- BETWEEN을 통해 OFFSET + 1부터 OFFSET + 페이지 크기까지 필터링합니다.
- REF CURSOR 반환
- SYS_REFCURSOR를 사용하여 결과를 반환합니다.
- 호출 후 PRINT 명령어로 결과를 확인하거나, 애플리케이션에서 커서를 처리할 수 있습니다.
FETCH FIRST 방식으로 변경한 예제 (12c 이상)
오라클 12c 이상에서는 OFFSET과 FETCH NEXT를 활용할 수도 있습니다.
CREATE OR REPLACE PROCEDURE PAGING_PROC (
P_PAGE_NUMBER IN NUMBER,
P_PAGE_SIZE IN NUMBER,
P_RESULT OUT SYS_REFCURSOR
)
AS
V_OFFSET NUMBER;
BEGIN
V_OFFSET := (P_PAGE_NUMBER - 1) * P_PAGE_SIZE;
OPEN P_RESULT FOR
SELECT *
FROM EMPLOYEES
ORDER BY EMPLOYEE_ID ASC
OFFSET V_OFFSET ROWS FETCH NEXT P_PAGE_SIZE ROWS ONLY;
END PAGING_PROC;
/
테스트 데이터
아래와 같은 테이블(EMPLOYEES)이 있다고 가정합니다:
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | DEPARTMENT |
1 | John | Doe | HR |
2 | Jane | Smith | IT |
3 | Alice | Johnson | Finance |
... | ... | ... | ... |
P_CURSOR 를 mybatis에서 활용하는 예제
MyBatis에서 Oracle의 SYS_REFCURSOR를 활용하려면, REF CURSOR를 매핑할 수 있는 MyBatis 설정과 매퍼 인터페이스를 작성해야 합니다. 아래는 MyBatis에서 P_CURSOR를 활용하는 예제를 단계별로 설명드립니다.
1. Oracle Stored Procedure
아래는 기존의 PAGING_PROC 프로시저입니다:
CREATE OR REPLACE PROCEDURE PAGING_PROC (
P_PAGE_NUMBER IN NUMBER, -- 요청 페이지 번호
P_PAGE_SIZE IN NUMBER, -- 페이지 크기 (한 페이지당 행 수)
P_RESULT OUT SYS_REFCURSOR -- 결과를 반환할 커서
)
AS
BEGIN
OPEN P_RESULT FOR
SELECT *
FROM EMPLOYEES
ORDER BY EMPLOYEE_ID ASC
OFFSET (P_PAGE_NUMBER - 1) * P_PAGE_SIZE ROWS FETCH NEXT P_PAGE_SIZE ROWS ONLY;
END PAGING_PROC;
/
2. MyBatis Mapper XML
MyBatis에서 SYS_REFCURSOR를 처리하려면 매퍼 XML에서 RESULT_MAP과 CALL 구문을 작성해야 합니다.
매퍼 XML (PagingMapper.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="com.example.mapper.PagingMapper">
<!-- REF CURSOR 결과를 매핑 -->
<resultMap id="employeeResultMap" type="com.example.model.Employee">
<result property="employeeId" column="EMPLOYEE_ID" />
<result property="firstName" column="FIRST_NAME" />
<result property="lastName" column="LAST_NAME" />
<result property="department" column="DEPARTMENT" />
</resultMap>
<!-- Stored Procedure 호출 -->
<select id="getPagedEmployees" statementType="CALLABLE" resultMap="employeeResultMap">
{CALL PAGING_PROC(
#{pageNumber, mode=IN, jdbcType=INTEGER},
#{pageSize, mode=IN, jdbcType=INTEGER},
#{cursor, mode=OUT, jdbcType=CURSOR, resultMap=employeeResultMap}
)}
</select>
</mapper>
3. 매퍼 인터페이스
MyBatis 매퍼 인터페이스에서 프로시저 호출 메서드를 정의합니다.
인터페이스 (PagingMapper.java)
package com.example.mapper;
import com.example.model.Employee;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface PagingMapper {
List<Employee> getPagedEmployees(
@Param("pageNumber") int pageNumber,
@Param("pageSize") int pageSize
);
}
4. Employee 모델 클래스
Oracle EMPLOYEES 테이블에 매핑되는 Java 클래스입니다.
모델 클래스 (Employee.java)
package com.example.model;
public class Employee {
private int employeeId;
private String firstName;
private String lastName;
private String department;
// Getters and Setters
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
}
5. Service Layer
서비스 계층에서 MyBatis 매퍼를 호출하여 데이터를 가져옵니다.
서비스 클래스 (EmployeeService.java)
package com.example.service;
import com.example.mapper.PagingMapper;
import com.example.model.Employee;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmployeeService {
private final PagingMapper pagingMapper;
public EmployeeService(PagingMapper pagingMapper) {
this.pagingMapper = pagingMapper;
}
public List<Employee> getPagedEmployees(int pageNumber, int pageSize) {
return pagingMapper.getPagedEmployees(pageNumber, pageSize);
}
}
6. Controller Layer
컨트롤러에서 요청을 받아 페이징 결과를 반환합니다.
컨트롤러 (EmployeeController.java)
package com.example.controller;
import com.example.model.Employee;
import com.example.service.EmployeeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class EmployeeController {
private final EmployeeService employeeService;
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
@GetMapping("/employees")
public List<Employee> getPagedEmployees(
@RequestParam("page") int pageNumber,
@RequestParam("size") int pageSize
) {
return employeeService.getPagedEmployees(pageNumber, pageSize);
}
}
7. 실행 및 테스트
- 서버를 실행합니다.
- REST API 호출:
- 예: GET /employees?page=1&size=10
- 결과는 JSON 형식으로 반환됩니다.
참고 사항
- MyBatis에서 SYS_REFCURSOR를 사용하려면 Oracle JDBC 드라이버가 제대로 설정되어 있어야 합니다.
- 성능을 위해 페이징 처리 시 적절한 인덱스를 활용하세요.
35개 행이 있고 페이지당 10개행이라고 할때 10페이지를 호출하면 마지막페이지 3페이지를 리턴하고 리턴한 페이지가 3이라는걸 알려주도록 수정해
요청하신 "마지막 페이지를 리턴하고, 리턴한 페이지가 몇 페이지인지 반환"하는 방식으로 MyBatis와 프로시저를 수정해 보겠습니다. 아래는 수정된 예제입니다.
1. Oracle Stored Procedure 수정
프로시저에서 총 페이지 수를 계산하고, 요청한 페이지가 총 페이지 수를 초과하면 마지막 페이지의 데이터를 반환하도록 수정합니다.
CREATE OR REPLACE PROCEDURE PAGING_PROC (
P_PAGE_NUMBER IN NUMBER, -- 요청 페이지 번호
P_PAGE_SIZE IN NUMBER, -- 페이지 크기
P_ACTUAL_PAGE OUT NUMBER, -- 실제 반환된 페이지 번호
P_RESULT OUT SYS_REFCURSOR -- 결과를 반환할 커서
)
AS
V_TOTAL_ROWS NUMBER; -- 총 행 수
V_TOTAL_PAGES NUMBER; -- 총 페이지 수
V_OFFSET NUMBER; -- 건너뛸 행의 수
BEGIN
-- 총 행 수 계산
SELECT COUNT(*) INTO V_TOTAL_ROWS FROM EMPLOYEES;
-- 총 페이지 수 계산
V_TOTAL_PAGES := CEIL(V_TOTAL_ROWS / P_PAGE_SIZE);
-- 요청 페이지가 총 페이지를 초과하면 마지막 페이지로 설정
IF P_PAGE_NUMBER > V_TOTAL_PAGES THEN
P_PAGE_NUMBER := V_TOTAL_PAGES;
END IF;
-- 실제 반환된 페이지 번호 설정
P_ACTUAL_PAGE := P_PAGE_NUMBER;
-- OFFSET 계산
V_OFFSET := (P_PAGE_NUMBER - 1) * P_PAGE_SIZE;
-- REF CURSOR에 결과 할당
OPEN P_RESULT FOR
SELECT *
FROM EMPLOYEES
ORDER BY EMPLOYEE_ID ASC
OFFSET V_OFFSET ROWS FETCH NEXT P_PAGE_SIZE ROWS ONLY;
END PAGING_PROC;
/
2. MyBatis Mapper XML 수정
P_ACTUAL_PAGE를 OUT 파라미터로 추가합니다.
매퍼 XML (PagingMapper.xml)
<select id="getPagedEmployees" statementType="CALLABLE">
{CALL PAGING_PROC(
#{pageNumber, mode=IN, jdbcType=INTEGER},
#{pageSize, mode=IN, jdbcType=INTEGER},
#{actualPage, mode=OUT, jdbcType=INTEGER},
#{cursor, mode=OUT, jdbcType=CURSOR, resultMap=employeeResultMap}
)}
</select>
3. Mapper 인터페이스 수정
actualPage를 매핑하기 위해 반환값을 담을 객체를 사용합니다.
인터페이스 (PagingMapper.java)
package com.example.mapper;
import com.example.model.Employee;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface PagingMapper {
void getPagedEmployees(
@Param("pageNumber") int pageNumber,
@Param("pageSize") int pageSize,
@Param("actualPage") Map<String, Object> actualPage, // OUT 파라미터 저장
@Param("cursor") List<Employee> cursor // 결과 데이터 저장
);
}
4. Service Layer 수정
결과와 실제 반환된 페이지 번호를 함께 처리하도록 수정합니다.
서비스 클래스 (EmployeeService.java)
package com.example.service;
import com.example.mapper.PagingMapper;
import com.example.model.Employee;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class EmployeeService {
private final PagingMapper pagingMapper;
public EmployeeService(PagingMapper pagingMapper) {
this.pagingMapper = pagingMapper;
}
public Map<String, Object> getPagedEmployees(int pageNumber, int pageSize) {
Map<String, Object> result = new HashMap<>();
Map<String, Object> actualPage = new HashMap<>();
List<Employee> employees;
pagingMapper.getPagedEmployees(pageNumber, pageSize, actualPage, employees);
result.put("employees", employees);
result.put("actualPage", actualPage.get("actualPage"));
return result;
}
}
5. Controller Layer 수정
최종 반환값에 실제 페이지 번호를 포함합니다.
컨트롤러 (EmployeeController.java)
package com.example.controller;
import com.example.service.EmployeeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class EmployeeController {
private final EmployeeService employeeService;
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
@GetMapping("/employees")
public Map<String, Object> getPagedEmployees(
@RequestParam("page") int pageNumber,
@RequestParam("size") int pageSize
) {
return employeeService.getPagedEmployees(pageNumber, pageSize);
}
}
6. REST API 호출 결과 예시
- 요청: GET /employees?page=10&size=10
- 결과 (JSON):
{
"employees": [
{"employeeId": 31, "firstName": "Alice", "lastName": "Johnson", "department": "Finance"},
{"employeeId": 32, "firstName": "Bob", "lastName": "Smith", "department": "IT"},
{"employeeId": 33, "firstName": "Carol", "lastName": "Jones", "department": "HR"},
{"employeeId": 34, "firstName": "David", "lastName": "Brown", "department": "Marketing"},
{"employeeId": 35, "firstName": "Eve", "lastName": "Davis", "department": "Sales"}
],
"actualPage": 3
}
주요 변경 사항
- Stored Procedure에서 요청 페이지가 총 페이지를 초과하면 마지막 페이지를 반환하도록 처리.
- P_ACTUAL_PAGE를 통해 실제 반환된 페이지 번호를 전달.
- MyBatis와 서비스, 컨트롤러 계층을 수정하여 결과에 actualPage 값을 포함.
페이지 리본이 10개 단위라고 할때 actualPage가 3이면 1~10 까지고 15이면 11~20 까지 잖아.. 이걸 구현해봐
페이지 리본이 10개 단위로 나뉘는 방식으로 요청에 따라 리본 범위를 계산하고 반환하도록 구현하겠습니다. 아래는 이를 포함하여 수정된 예제입니다.
1. Stored Procedure 수정
PAGE RIBBON의 범위(START_PAGE, END_PAGE)를 계산하고 반환하도록 프로시저를 수정합니다.
프로시저 (PAGING_PROC)
CREATE OR REPLACE PROCEDURE PAGING_PROC (
P_PAGE_NUMBER IN NUMBER, -- 요청 페이지 번호
P_PAGE_SIZE IN NUMBER, -- 페이지 크기
P_ACTUAL_PAGE OUT NUMBER, -- 실제 반환된 페이지 번호
P_START_RIBBON OUT NUMBER, -- 페이지 리본 시작 번호
P_END_RIBBON OUT NUMBER, -- 페이지 리본 끝 번호
P_RESULT OUT SYS_REFCURSOR -- 결과를 반환할 커서
)
AS
V_TOTAL_ROWS NUMBER; -- 총 행 수
V_TOTAL_PAGES NUMBER; -- 총 페이지 수
V_OFFSET NUMBER; -- 건너뛸 행의 수
BEGIN
-- 총 행 수 계산
SELECT COUNT(*) INTO V_TOTAL_ROWS FROM EMPLOYEES;
-- 총 페이지 수 계산
V_TOTAL_PAGES := CEIL(V_TOTAL_ROWS / P_PAGE_SIZE);
-- 요청 페이지가 총 페이지를 초과하면 마지막 페이지로 설정
IF P_PAGE_NUMBER > V_TOTAL_PAGES THEN
P_PAGE_NUMBER := V_TOTAL_PAGES;
END IF;
-- 실제 반환된 페이지 번호 설정
P_ACTUAL_PAGE := P_PAGE_NUMBER;
-- 페이지 리본 범위 계산
P_START_RIBBON := FLOOR((P_PAGE_NUMBER - 1) / 10) * 10 + 1;
P_END_RIBBON := P_START_RIBBON + 9;
-- 리본 끝 페이지가 총 페이지를 초과하면 조정
IF P_END_RIBBON > V_TOTAL_PAGES THEN
P_END_RIBBON := V_TOTAL_PAGES;
END IF;
-- OFFSET 계산
V_OFFSET := (P_PAGE_NUMBER - 1) * P_PAGE_SIZE;
-- REF CURSOR에 결과 할당
OPEN P_RESULT FOR
SELECT *
FROM EMPLOYEES
ORDER BY EMPLOYEE_ID ASC
OFFSET V_OFFSET ROWS FETCH NEXT P_PAGE_SIZE ROWS ONLY;
END PAGING_PROC;
/
2. MyBatis Mapper XML 수정
P_START_RIBBON과 P_END_RIBBON을 OUT 파라미터로 추가합니다.
매퍼 XML (PagingMapper.xml)
<select id="getPagedEmployees" statementType="CALLABLE">
{CALL PAGING_PROC(
#{pageNumber, mode=IN, jdbcType=INTEGER},
#{pageSize, mode=IN, jdbcType=INTEGER},
#{actualPage, mode=OUT, jdbcType=INTEGER},
#{startRibbon, mode=OUT, jdbcType=INTEGER},
#{endRibbon, mode=OUT, jdbcType=INTEGER},
#{cursor, mode=OUT, jdbcType=CURSOR, resultMap=employeeResultMap}
)}
</select>
3. Mapper 인터페이스 수정
startRibbon과 endRibbon을 추가합니다.
인터페이스 (PagingMapper.java)
package com.example.mapper;
import com.example.model.Employee;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface PagingMapper {
void getPagedEmployees(
@Param("pageNumber") int pageNumber,
@Param("pageSize") int pageSize,
@Param("actualPage") Map<String, Object> actualPage, // 실제 페이지
@Param("startRibbon") Map<String, Object> startRibbon, // 리본 시작
@Param("endRibbon") Map<String, Object> endRibbon, // 리본 끝
@Param("cursor") List<Employee> cursor // 결과 데이터
);
}
4. Service Layer 수정
리본 범위 값을 반환하도록 로직을 수정합니다.
서비스 클래스 (EmployeeService.java)
package com.example.service;
import com.example.mapper.PagingMapper;
import com.example.model.Employee;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class EmployeeService {
private final PagingMapper pagingMapper;
public EmployeeService(PagingMapper pagingMapper) {
this.pagingMapper = pagingMapper;
}
public Map<String, Object> getPagedEmployees(int pageNumber, int pageSize) {
Map<String, Object> result = new HashMap<>();
Map<String, Object> actualPage = new HashMap<>();
Map<String, Object> startRibbon = new HashMap<>();
Map<String, Object> endRibbon = new HashMap<>();
List<Employee> employees;
pagingMapper.getPagedEmployees(pageNumber, pageSize, actualPage, startRibbon, endRibbon, employees);
result.put("employees", employees);
result.put("actualPage", actualPage.get("actualPage"));
result.put("startRibbon", startRibbon.get("startRibbon"));
result.put("endRibbon", endRibbon.get("endRibbon"));
return result;
}
}
5. Controller Layer 수정
결과에 리본 범위를 포함하도록 수정합니다.
컨트롤러 (EmployeeController.java)
package com.example.controller;
import com.example.service.EmployeeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class EmployeeController {
private final EmployeeService employeeService;
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
@GetMapping("/employees")
public Map<String, Object> getPagedEmployees(
@RequestParam("page") int pageNumber,
@RequestParam("size") int pageSize
) {
return employeeService.getPagedEmployees(pageNumber, pageSize);
}
}
6. REST API 호출 결과 예시
- 요청: GET /employees?page=15&size=10
- 결과 (JSON):
{
"employees": [
{"employeeId": 141, "firstName": "Alice", "lastName": "Johnson", "department": "Finance"},
{"employeeId": 142, "firstName": "Bob", "lastName": "Smith", "department": "IT"},
{"employeeId": 143, "firstName": "Carol", "lastName": "Jones", "department": "HR"},
{"employeeId": 144, "firstName": "David", "lastName": "Brown", "department": "Marketing"},
{"employeeId": 145, "firstName": "Eve", "lastName": "Davis", "department": "Sales"}
],
"actualPage": 15,
"startRibbon": 11,
"endRibbon": 20
}
주요 변경 사항
- Stored Procedure
- P_START_RIBBON과 P_END_RIBBON을 계산.
- 요청 페이지에 따라 리본 범위를 조정.
- Service & Controller
-
- 리본 범위를 클라이언트에 반환.
추가적인 요청이 있으시면 언제든 말씀해 주세요! 😊
2024.12.14 - [Oracle Database 강좌] - 오라클 페이지네이션 성능 최적화: ROWNUM vs ROW_NUMBER() 심층 분석 및 추가 최적화 방안
오라클 페이지네이션 성능 최적화: ROWNUM vs ROW_NUMBER() 심층 분석 및 추가 최적화 방안
2024.12.14 - [Oracle Database 강좌] - 오라클 페이징 구현 및 스토어드 프로시저 활용: 심층 분석 및 실제 예제 오라클 페이징 구현 및 스토어드 프로시저 활용: 심층 분석 및 실제 예제오라클(Oracle) 데
notion4570.tistory.com
'Oracle Database 강좌' 카테고리의 다른 글
오라클 스토어드 프로시저에서 JSON 데이터 생성 및 출력: 심층 분석 (0) | 2024.12.16 |
---|---|
오라클 페이지네이션 성능 최적화: ROWNUM vs ROW_NUMBER() 심층 분석 및 추가 최적화 방안 (1) | 2024.12.14 |
오라클 스토어드 프로시저 : 실무에서 활용하는 다양한 기능 (2) | 2024.12.08 |
Oracle 외래 키 제약 조건 무시 및 데이터 대량삽입 (1) | 2024.12.08 |
오라클 프로시저에서 사용되는 테이블 추적하기 (0) | 2024.12.08 |