Mybatis Interceptor 자동 Paging처리 만들기(1) 바로가기
Mybatis Interceptor 자동 Paging처리 만들기(2) 바로가기
♣️미리보기
- H2 Database Table Data
- HTTP GET 통신
- return 값
{
"list": [
{
"num": 1,
"id": "test1",
"pw": "test1",
"name": "테스트1"
},
{
"num": 2,
"id": "test2",
"pw": "test2",
"name": "테스트2"
}
],
"pageInfo": {
"page": 1,
"size": 2,
"totalCount": 3
}
}
♦ Controller 매개변수 PageInfo 상속
@RestController
@RequestMapping(path = "/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public PagableResponse<User> selectUserList(@ModelAttribute @Valid UserSearch userSearch) {
return userService.selectUserList(userRequest);
}
}
@ModelAttribute 어노테이션에 의해, 조회조건 데이터를 UserSearch에 Binding
@Data
@EqualsAndHashCode(callSuper = false)
public class UserSearch extends PageInfo {
private String id;
private String name;
}
PageInfo를 상속받는다.
import javax.validation.constraints.Min;
import org.apache.ibatis.session.RowBounds;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
@JsonIgnoreProperties({"offset", "limit"})
public class PageInfo extends RowBounds {
protected Integer page = 1;
@Min(1)
protected Integer size = 10;
protected Long totalCount = -1L; // set이 되지않았다는 의미로 -1
}
조회시 page, size값을 사용, totalCount는 이후 return 시 사용된다.
♦ Mapper 매개변수로 PageInfo를 상속받은 객체를 전달, Return Class는 반드시 PagableResponse<T>
@Mapper
public interface UserMapper {
@Select(value = """
<script>
SELECT * FROM USER
WHERE 1 = 1
<if test='id != null and !id.equals("")'>
AND ID LIKE '%${id}%'
</if>
</script>
""")
public PagableResponse<User> selectUserList(UserSearch userRequest);
}
- Controller에서 넘어온 UserSearch 객체를 그대로 매개변수로 전달
- Return할 Class를 반드시 PagableResponse<T> 로 지정
@Data
@JsonFormat(shape = Shape.OBJECT)
public class PagableResponse<T> implements List<T> {
private List<T> list;
private PageInfo pageInfo;
public PagableResponse() {
list = new ArrayList<>();
pageInfo = new PageInfo();
}
/*
* 아래는 List Method Override
*/
@Override
public int size() {
return list.size();
}
.
.
.
}
♦ 기능 테스트
User 테이블 Data
@Autowired
private UserMapper userMapper;
@Test
@DisplayName("page, size 지정")
void selectUserListTestWithPageAndSize() {
log.debug("■■■ selectUserListTestWithPageAndSize Start ■■■■");
UserSearch userSearch = new UserSearch();
userSearch.setPage(1);
userSearch.setSize(2);
PagableResponse<User> returnObject = userMapper.selectUserList(userSearch);
log.debug(returnObject.getList().toString());
log.debug(returnObject.getPageInfo().toString());
log.debug("■■■ selectUserListTestWithPageAndSize End ■■■■");
}
page, size 지정 결과
c.e.d.api.user.service.UserServiceTests : ■■■ selectUserListTestWithPageAndSize Start ■■■■
c.e.d.c.m.interceptor.QueryInterceptor : ■■ QueryInterceptor intercept: Request Parameter가 PageInfo.class를 상속■■
c.e.d.a.u.m.U.selectUserList-Long : ==> Preparing: SELECT COUNT(*) FROM ( SELECT * FROM USER WHERE 1 = 1 ) COUNT_TABLE
c.e.d.a.u.m.U.selectUserList-Long : ==> Parameters:
c.e.d.a.u.m.U.selectUserList-Long : <== Total: 1
c.e.d.a.u.m.UserMapper.selectUserList : ==> Preparing: SELECT * FROM USER WHERE 1 = 1 LIMIT 0, 2
c.e.d.a.u.m.UserMapper.selectUserList : ==> Parameters:
c.e.d.a.u.m.UserMapper.selectUserList : <== Total: 2
- SELECT COUNT(*) FROM ( ~~~ ) COUNT_TABLE 을 붙여서 totalCount를 먼저 구함
- CountQuery를 Wrapper 형식으로 감싸지않고 SELECT ? FROM 을 정규식으로 COUNT(*)을 삽입하면 성능 향상에 좋을듯
2. Mapper에 작성된 Select문에 LIMIT 을 붙여서 size 갯수만큼 가져옴
c.e.d.api.user.service.UserServiceTests : list: [User(num=1, id=test1, pw=test1, name=테스트1), User(num=2, id=test2, pw=test2, name=테스트2)]
c.e.d.api.user.service.UserServiceTests : pageInfo: PageInfo(page=1, size=2, totalCount=3)
c.e.d.api.user.service.UserServiceTests : ■■■ selectUserListTestWithPageAndSize End ■■■■
- list는 size만큼 2개 확인
- pageInfo도 정상적으로 page, size, totalCount 채워서 반환 확인
@Autowired
private UserMapper userMapper;
@Test
@DisplayName("page, size 미지정")
void selectUserListTestWithoutPageAndSize() {
log.debug("■■■ selectUserListTestWithoutPageAndSize Start ■■■■");
UserSearch userSearch = new UserSearch();
PagableResponse<User> returnObject = userMapper.selectUserList(userSearch);
log.debug(returnObject.getList().toString());
log.debug(returnObject.getPageInfo().toString());
log.debug("■■■ selectUserListTestWithoutPageAndSize End ■■■■");
}
page, size 미지정 결과
c.e.d.c.m.interceptor.QueryInterceptor : ■■ QueryInterceptor intercept: Request Parameter가 PageInfo.class를 상속■■
c.e.d.a.u.m.U.selectUserList-Long : ==> Preparing: SELECT COUNT(*) FROM ( SELECT * FROM USER WHERE 1 = 1 ) COUNT_TABLE
c.e.d.a.u.m.U.selectUserList-Long : ==> Parameters:
c.e.d.a.u.m.U.selectUserList-Long : <== Total: 1
c.e.d.a.u.m.UserMapper.selectUserList : ==> Preparing: SELECT * FROM USER WHERE 1 = 1
c.e.d.a.u.m.UserMapper.selectUserList : ==> Parameters:
c.e.d.a.u.m.UserMapper.selectUserList : <== Total: 3
- SELECT COUNT(*) FROM ( ~~~ ) COUNT_TABLE 을 붙여서 totalCount를 먼저 구함
- page or size 가 없어서 LIMIT 을 하지않고 SELECT
c.e.d.api.user.service.UserServiceTests : list: [User(num=1, id=test1, pw=test1, name=테스트1), User(num=2, id=test2, pw=test2, name=테스트2), User(num=3, id=test3, pw=test3, name=테스트3)]
c.e.d.api.user.service.UserServiceTests : pageInfo: PageInfo(page=null, size=null, totalCount=3)
c.e.d.api.user.service.UserServiceTests : ■■■ selectUserListTestWithoutPageAndSize End ■■■■
- list는 size를 지정하지 않았기에 전체인 3개 확인
- pageInfo도 정상적으로 page, size는 그대로 null, totalCount 채워서 반환 확인
Uploaded by Notion2Tistory v1.1.0