IT 개발,관리,연동,자동화

PostgreSQL 만일에 select해서 json으로 변환함에 있어 페이징 처리 할때 현페이지 정보라든지 총 페이지 수라든지 부가 정보를 더해서 json을 변환하려면?

_Blue_Sky_ 2024. 11. 29. 23:55
728x90
728x90

페이징 처리를 위해 현 페이지 정보, 총 페이지 수, 데이터 개수 등 부가 정보를 JSON으로 포함하려면 다음과 같은 방식으로 구현할 수 있습니다.

1. PostgreSQL 쿼리 수정

PostgreSQL에서 페이징 처리를 위해 LIMIT과 OFFSET을 사용하고, 데이터와 함께 부가 정보를 반환하는 쿼리를 작성합니다.

예제:

SELECT 
    json_build_object(
        'currentPage', :currentPage,
        'totalPages', CEIL(COUNT(*) OVER() / :pageSize),
        'totalItems', COUNT(*) OVER(),
        'data', json_agg(row_to_json(users))
    )
FROM (
    SELECT id, name, age
    FROM users
    ORDER BY id
    LIMIT :pageSize OFFSET :offset
) AS users;
  • :currentPage: 현재 페이지 번호 (파라미터로 전달).
  • :pageSize: 한 페이지에 표시할 데이터 개수.
  • COUNT(*) OVER(): 전체 데이터 개수 계산 (윈도우 함수 사용).
  • LIMIT & OFFSET: 페이징 처리.

2. MyBatis Mapper 수정

위 쿼리를 MyBatis에 맞게 작성합니다.

Mapper XML (UserMapper.xml):


http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        SELECT 
            json_build_object(
                'currentPage', #{currentPage},
                'totalPages', CEIL(COUNT(*) OVER() / CAST(#{pageSize} AS NUMERIC)),
                'totalItems', COUNT(*) OVER(),
                'data', json_agg(row_to_json(users))
            )
        FROM (
            SELECT id, name, age
            FROM users
            ORDER BY id
            LIMIT #{pageSize} OFFSET (#{currentPage} - 1) * #{pageSize}
        ) AS users
    

728x90

Mapper 인터페이스 (UserMapper.java):

package com.example.demo.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface UserMapper {
    String fetchUsersWithPaging(@Param("currentPage") int currentPage, @Param("pageSize") int pageSize);
}

3. 서비스 구현

package com.example.demo.service;

import com.example.demo.mapper.UserMapper;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    private final UserMapper userMapper;

    public UserService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    public String getUsersWithPaging(int currentPage, int pageSize) {
        return userMapper.fetchUsersWithPaging(currentPage, pageSize);
    }
}

4. 컨트롤러

package com.example.demo.controller;

import com.example.demo.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/users/paged")
    public String getPagedUsers(
        @RequestParam(defaultValue = "1") int currentPage,
        @RequestParam(defaultValue = "10") int pageSize
    ) {
        return userService.getUsersWithPaging(currentPage, pageSize);
    }
}

728x90

5. 결과 테스트

요청:

GET http://localhost:8080/users/paged?currentPage=2&pageSize=5

결과:

{
    "currentPage": 2,
    "totalPages": 10,
    "totalItems": 50,
    "data": [
        {
            "id": 6,
            "name": "Alice",
            "age": 25
        },
        {
            "id": 7,
            "name": "Bob",
            "age": 30
        },
        ...
    ]
}

요약

  • PostgreSQL 윈도우 함수를 활용해 전체 데이터 개수를 계산하고 페이지 정보를 추가.
  • **json_build_object**를 사용해 부가 정보를 JSON 형태로 반환.
  • MyBatis에서 페이징 파라미터 (currentPage, pageSize)를 매핑.
  • API 요청 시 페이지 번호와 크기를 전달받아 JSON 형태로 데이터를 반환.

이 방식은 효율적이며, 클라이언트가 필요한 페이징 정보를 한 번에 제공할 수 있습니다.

728x90
728x90