저희는 지금까지 게시글 작성, 상세보기, 수정, 삭제, 게시글 목록을 구현했는데요
현재 게시글 목록은 페이징 기능이 없어서 mysql 서버에서 데이터를 조회해오는 것도 부담이고, 사용자 입장에서도
보기가 그렇게 썩 좋지는 않기 때문에 페이징기능을 추가해보도록 하겠습니다!
먼저 BoardMapper에 다음과 같은 쿼리문을 만들어줍니다.
<!-- board 페이징 조회 -->
<select id="listPage" resultType="BoardVO">
select *
from board
order by board_number sesc, create_dat dsc
limit #{dataStart}, #{perPagNum}
</select>
이해를 돕기 위해서 예시를 들어보겠습니다.
limit 절을 이용해서
select *
from board
limit 10, 10
limit 10, 10의 의미는 11번째 데이터부터 10개를 출력한다! 라는 의미입니다.
dataStart는 (page-1) * perPageNum 입니다.
page가 1이라고 하면 1번 게시글부터 10번 게시글까지 나와야 하겠죠?
page가 2이라고 하면 11번 게시글부터 20번 게시글까지 출력 됩니다.
이제 페이징 처리를 도와줄 Critera.java를 작성하겠습니다.
Criteria.java 생성
Criteria.java는 파라미터 값으로 가져와서 사용할것이기 때문에 kr.co.web.domain패키지의 VO로 사용할 것입니다.
package kr.co.web.domain;
public class Criteria {
private int page;
private int perPageNum;
public Criteria() {
// TODO Auto-generated constructor stub
this.page = 1;
this.perPageNum = 10;
}
public int getDataStart() {
return (this.page - 1) * perPageNum;
}
public int getPage() {
return page;
}
public void setPage(int page) {
if(page < 0) {
this.page = 1;
}else {
this.page = page;
}
}
public int getPerPageNum() {
return perPageNum;
}
public void setPerPageNum(int perPageNum) {
this.perPageNum = perPageNum;
}
@Override
public String toString() {
return "Criteria [page=" + page + ", perPageNum=" + perPageNum + "]";
}
}
이 코드에서 꼭 알아야 하는 코드가 있습니다.
Critera.java에서 멤버변수가 없는데 DataStart getter가 있는데요?
이 getDataStart는 mapper에서 작성한 SQL문의 limit부분의 시작데이터인 dataStart를 계산하여 SQL문으로 반환하는 메서드 입니다.
이제 Criteria클래스를 매개변수로 받아야 합니다.
listPage 메서드 추가
<!-- BoardController.java -->
@RequestMapping(value = "/listPage", method = RequestMethod.GET)
public void listPage(Criteria cri, Model model) throws Exception {
logger.info("listPageGET!!!");
}
컨트롤러를 만들었으니 이제 mapper에 추가한 SQL처리를 하기 위한 Service와 Dao를 추가하겠습니다.
BoardService, BoardServiceImpl 수정
<!-- BoardService.java -->
public List<BoardVO> listPage(Criteria cri) throws Exception;
<!-- BoardServiceImpl.java -->
@Override
public List<BoardVO> listPage(Criteria cri) throws Exception {
return boardDAO.listPage(cri);
}
이제 service단을 작성했으니 Dao단도 추가해줘야 합니다.
<!-- BoardDAO.java -->
public List<BoardVO> listPage(Criteria cri) throws Exception;
<!-- BoardDAOImpl.java -->
private static String LISTPAGE = NS + ".listPage";
@Override
public List<BoardVO> listPage(Criteria cri) throws Exception {
return session.selectList(LISTPAGE, cri);
}
위의 listPage에서 session은 아까 mapper에 추가한 sql문을 실행시켜주는데요
CriteriaVO에 있는 멤버변수로 SQL문에 있는 pageStart 부분은 Criteria의 getDataStart()를 호출해서 채워집니다.
이제 Service 객체에서 Dao 객체가 제대로 생성되고 Dao 객체가 아까 mapeer에 있는 쿼리를 제대로 실행하는지 테스트를 해보겠습니다.
page가 1이고, perPageNum가 10일 때 mysql 서버에서 데이터를 잘 가지고 오는지 확인하겠습니다.
에러를 확인하면 mapper쪽에 문제가 있는 것 같습니다.
저희는 그동안 root-context.xml에 있는 다음과 같은 코드를 사용했지만 CRUD는 잘 출력됐는데 말이죠
아마 테스트코드는 조금 다른것 같습니다.
다시 에러를 보면 BoardMapper.listPage쪽에 문제가 있는것 같습니다.
저희는 root-context.xml에 다음과 같이 알맞게 설정했습니다만
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:/mybatis-config.xml"></property>
<property name="mapperLocations" value="classpath:mappers/**/*Mapper.xml"></property>
</bean>
에러가 발생하니 mapper 경로를 명확하게 해보겠습니다.
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:/mybatis-config.xml"></property>
<property name="mapperLocations">
<list>
<value>classpath:mappers/boardMapper.xml</value>
</list>
</property>
</bean>
다시 UnitTest를 진행해보면
다음과 같이 잘 출력이 되는것을 확인했습니다!!
이제 다음과 같은 에러가 발생하면 mapper 값을 명확히 하는게 좋을 것 같습니다.