게시판 페이지처리하기 위한 카운트를 재정의해준다.
우선 BoardMapper.xml에 getBoardCount를 생성해준다.
<select id="getBoardCount" parameterType="com.study.board.vo.BoardSearchVO" resultType="int">
<!-- 카운트는 위에 리스트와 같고 cnt를 리턴하기때문에 int를 resultType에 넣어준다 --> SELECT count(*) as cnt FROM board WHERE 1=1 <if test="search_type != null and search_type != '' and search_word != null and search_word != ''">
<!-- 널체크는 필수.. --> <choose> <when test="search_type == 'id'"> AND bo_mem_id LIKE '%' || #{search_word} || '%' </when> <when test="search_type == 'title'"> AND bo_title LIKE '%' || #{search_word} || '%' </when> <when test="search_type == 'content'"> AND bo_content LIKE '%' || #{search_word} || '%' </when> </choose> </if> </select>
기존 BoardDao의 getBoardCount에 아래에 있던 내용들이 필요없게됐다.
// 게시판 건수 조회 (R:Read) @Override public int getBoardCount(BoardSearchVO searchVO) throws SQLException { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; boolean isSearch = false ; try{ conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:study"); StringBuffer sb = new StringBuffer(); sb.append("SELECT count(*) as cnt "); sb.append(" FROM board "); sb.append(" WHERE 1 = 1 "); if(StringUtils.isNotBlank(searchVO.getSearch_type()) && StringUtils.isNotBlank(searchVO.getSearch_word())){ isSearch = true; switch(searchVO.getSearch_type()) { case "id" : sb.append("and bo_mem_id like '%' || ? || '%' "); break; case "title" : sb.append("and bo_title like '%' || ? || '%' "); break; case "content" : sb.append("and bo_content like '%' || ? || '%' "); break; } } pstmt = conn.prepareStatement(sb.toString()); int idx = 1; if(isSearch) { pstmt.setString(idx++, searchVO.getSearch_word()); } rs = pstmt.executeQuery(); rs.next(); int tot = rs.getInt("cnt"); // getInt(1) return tot; } catch(SQLException ex){ ex.printStackTrace(); throw ex; // }finally{ if(rs != null) {rs.close();} if(pstmt != null) {pstmt.close();} if(conn != null) {conn.close();} } }
위 내용을 아래처럼 정리해준다.
// 게시판 건수 조회 (R:Read) public int getBoardCount(SqlSession session ,BoardSearchVO searchVO) throws SQLException { int cnt = (Integer)session.selectOne("com.study.board.mapper.BoardMapper.getBoardCount", searchVO); return cnt; }
이후 페이징처리를 해주기위해 BoardMapper.xml에 있는 getBoardList에 Sql 쿼리문을 추가해준다.
<select id="getBoardList" resultType="com.study.board.vo.BoardVO" parameterType="com.study.board.vo.BoardSearchVO"> <!-- 메소드명과 동일하다. --> SELECT * FROM(
SELECT ROWNUM AS RNUM, TB.* FROM(
SELECT bo_no, bo_mem_id,123 bo_title, bo_content, bo_ip, bo_hit, bo_del_yn, bo_reg_date, bo_mod_date FROM board WHERE 1=1 <if test="search_type != null and search_type != '' and search_word != null and search_word != ''"> <choose> <when test="search_type == 'id'"> AND bo_mem_id LIKE '%' || #{search_word} || '%' </when> <when test="search_type == 'title'"> AND bo_title LIKE '%' || #{search_word} || '%' </when> <when test="search_type == 'content'"> AND bo_content LIKE '%' || #{search_word} || '%' </when> </choose> </if> ORDER BY bo_no DESC <!-- 정렬까지 끝내줘야 한다. --> ) TB ) WHERE rnum BETWEEN #{start_row} AND #{end_row} <!-- 페이징처리 끝. --> </select>
참고 - 페이징 처리를 위한 SQL 쿼리문
BoardMapper.xml에서 parameterType="", resultType=""에는 항상 풀네임을 넣어줘야하기때문에 같은 내용들이 계속 반복된다.
mybatis-config.xml에서 Alias(별명)을 줄수있다.
<typeAliases> <typeAlias type="com.study.board.vo.BoardVO" alias="BoardVO"/> <typeAlias type="com.study.board.vo.BoardSearchVO" alias="SearchVO"/> </typeAliases>
이때 typeAliases는 <properties resource="db.properties"></properties> 밑에다 넣어준다.
순서가 밑으로 내려갈경우 configuration에 에러가 생긴다.
이후로는 BoardMapper.xml에서 parameterType이나 resultType에서 alias로 대신할수있게된다.
나머지는 간단하게 복붙을 하면된다. BoardMapper.xml에서 insert, update, delete를 만들어준다.
<insert id="insertBoard" parameterType="BoardVO">
<!-- insert, update, delete는 return이 없다. 떄문에 resultType은 없다 --> INSERT INTO board ( bo_no , bo_mem_id , bo_title , bo_content , bo_ip , bo_hit , bo_del_yn , bo_reg_date )VALUES( seq_board.nextval <!-- bo_no은 sql 시퀀스로 받아온다. --> , #{bo_mem_id} , #{bo_title} , #{bo_content} , #{bo_ip} , 0 , 'N' , SYSDATE ) </insert> <update id="updateBoard" parameterType="BoardVO"> UPDATE board SET bo_title = #{bo_title} , bo_content = #{bo_content} , bo_mod_date = SYSDATE WHERE bo_no = #{bo_no} </update> <update id="increaseBoardHit" parameterType="int"> UPDATE board SET bo_hit = bo_hit + 1 WHERE bo_no = #{bo_no} </update> <delete id="deleteBoard" parameterType="int">
<!-- update나 delete나 업데이트 쿼리 사용가능. 이유는 둘다 executeUpdate를 부르기때문 --> UPDATE board SET bo_del_yn = 'Y' WHERE bo_no = #{bo_no} </delete>
위처럼 완료했으면 BoardDao에서도 내용을 줄여준다.
리턴할때에도 같은 풀네임을 지속적으로 입력해줘야하기때문에 상수로 선언해준다.
private static final String NAMESPACE = "com.study.board.mapper.BoardMapper.";
public int insertBoard(SqlSession session, BoardVO board) throws SQLException { return session.insert(NAMESPACE + "insertBoard", board); } public int updateBoard(SqlSession session, BoardVO board) throws SQLException { return session.update(NAMESPACE + "updateBoard", board); } public int deleteBoard(SqlSession session, int bo_no) throws SQLException{ return session.delete(NAMESPACE + "deleteBoard", bo_no); }
public int increaseBoardHit(SqlSession session, int bo_no) throws SQLException{ return session.update(NAMESPACE + "increaseBoardHit", bo_no); }
BoardServiceImpl에서 트랜잭션이 제대로 되지 않기때문에 커밋 작업을 해주고 세션도 클로즈 해준다.
@Override public BoardVO getBoard(BoardVO board) throws Exception { SqlSession session = sqlSessionFactory.openSession();
// 트랜젝션처리가 안되기때문에 auto Commit(true)을 준다. openSession은 기본 false다. BoardVO vo = boardDao.getBoard(session, board.getBo_no()); if(vo != null && board.isIncreaseHit() ) { boardDao.increaseBoardHit(session, board.getBo_no()); } session.commit();
// 위에서 openSession에서 true를 안줄땐 직접 commit을 줄수있지만 getBoard에서는 두번 들어가기때문에 직접커밋을해주는게 좋다 session.close(); return vo; }
'IT공부 > SPRING' 카테고리의 다른 글
DI AOP MVC (0) | 2019.08.09 |
---|---|
스프링 4회차. (0) | 2019.08.07 |
BoardDao를 BoardMapper로 바꿔준다. (0) | 2019.08.05 |
mybatis에서 로그를 보기위해 Log4j 설치하기. (0) | 2019.08.05 |
MyBatis이용한 기존 쿼리문 변경. (0) | 2019.08.02 |