728x90
20221111(금)
- 목차
- 게시판에 페이징 기능
- 게시판에 검색 기능
- cf) 페이징 버튼 만들기
https://java119.tistory.com/85
❤ 코딩을 하기 전에 가볍게 분석하기!!!!
전체 흐름이 어떻게 되는지 동작도 돌려보고~
호출이 어떻게 되는지 돌려보기~
❤ 구성 분석 및 작업 플로우(흐름)
- 각 기능별 작업분석
1) 글쓰기 폼 / 글쓰기 저장
2) 목록
3) 조회
4) 수정폼 / 수정하기
5) 삭제
1. BoardVO.java
package com.demo.domain;
import java.util.Date;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
// 테이블명 : TBL_BOARD
/*
CREATE TABLE TBL_BOARD (
BNO NUMBER(10,0), --일련번호
TITLE VARCHAR2(200) NOT NULL, -- 제목
CONTENT VARCHAR2(2000) NOT NULL, -- 내용
WRITER VARCHAR2(50) NOT NULL, -- 작성자
REGDATE DATE DEFAULT SYSDATE, -- 등록일자
UPDATEDATE DATE DEFAULT SYSDATE -- 수정일자
);
*/
// VO클래스 생성 : 테이블명은 알맞은 이름을 정의하고, 컬럼명은 클래스의 필드명으로 동일하게 정의한다.
@Getter
@Setter
@ToString
public class BoardVO {
//bno, title, content, writer, regdate, updatedate
private Long bno; // 기본데이타 타입인 int, long 을사용 안하고, 참조타입인 Long을 사용.
private String title;
private String content;
private String writer;
private Date regdate;
private Date updatedate;
/* 롬복사용 안하고, 수동으로 작업시 아래 getter, setter, ToString() 메서드 작업해야 함.
public Long getBno() {
return bno;
}
public void setBno(Long bno) {
this.bno = bno;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public Date getRegdate() {
return regdate;
}
public void setRegdate(Date regdate) {
this.regdate = regdate;
}
public Date getUpdatedate() {
return updatedate;
}
public void setUpdatedate(Date updatedate) {
this.updatedate = updatedate;
}
@Override
public String toString() {
return "BoardVO [bno=" + bno + ", title=" + title + ", content=" + content + ", writer=" + writer + ", regdate="
+ regdate + ", updatedate=" + updatedate + "]";
}
*/
}
2. BoardController.java
package com.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.demo.domain.BoardVO;
import com.demo.dto.Criteria;
import com.demo.dto.PageDTO;
import com.demo.service.BoardService;
import lombok.extern.log4j.Log4j;
@Log4j
@Controller // boardController bean 으로 생성
@RequestMapping("/board/*")
public class BoardController {
@Autowired
private BoardService boardService;
//글쓰기 폼. /board/write
@GetMapping("/write")
public void write() {
log.info("write called...");
}
//글저장
@PostMapping("/write")
public String write(BoardVO vo, RedirectAttributes rttr) {
log.info("입력데이타: " + vo);
boardService.insert(vo);
rttr.addFlashAttribute("msg", "write");
return "redirect:/board/list";
}
// 오라클 인덱스 힌트 : https://gent.tistory.com/306
//리스트(목록). 데이타를 JSP에 전달하여 출력
/*
@GetMapping("/list")
public void list(Model model) {
log.info("list called...");
List<BoardVO> list = boardService.getList();
model.addAttribute("list", list);
}
*/
// pageNum, amount
@GetMapping("/list") // 1 2 3 4 5
public void list(Criteria cri, Model model) {
log.info("list: " + cri);
List<BoardVO> list = boardService.getListWithPaging(cri); // pageNum=1, amount=10, type= , keyword=
model.addAttribute("list", list);
//페이징 기능. 1 2 3 4 5
int total = boardService.getTotalCount(cri);
PageDTO pageDTO = new PageDTO(total, cri);
model.addAttribute("pageMaker", pageDTO);
}
//게시물읽기및 수정폼. 데이타를 JSP에 전달하여 출력.
// 요청주소 읽기주소 /board/get?bno=3 수정폼주소 /board/modify?bno=3
//@GetMapping("/get")
@GetMapping(value = {"/get", "/modify"})
public void get(Long bno, @ModelAttribute("cri") Criteria cri, Model model) {
log.info("게시물번호: " + bno);
BoardVO board = boardService.get(bno);
model.addAttribute("board", board);
}
//글 수정하기
@PostMapping("/modify")
public String modify(BoardVO vo, Criteria cri, RedirectAttributes rttr) {
log.info("수정 내용: " + vo);
//db연동작업
boardService.modify(vo);
/*
1)rttr.addAttribute(attributeName, attributeValue);
-> 이동하는 주소의 메서드에 파라미터 값을 전달목적으로 사용.
예>
rttr.addAttribute("bno", 1);
rttr.addAttribute("title", "제목");
주소의 모습 : /board/list?bno=1&title=제목
2)rttr.addFlashAttribute(attributeName, attributeValue);
예>
rttr.addFlashAttribute("msg", "ok");
주소 /board/list 에서 사용하는 jsp에서 변수값을 참조할수가 있다.
*/
rttr.addFlashAttribute("msg", "modify");
//리스트주소에 필요한 파라미터 작업
rttr.addAttribute("pageNum", cri.getPageNum());
rttr.addAttribute("amount", cri.getAmount());
rttr.addAttribute("type", cri.getType());
rttr.addAttribute("keyword", cri.getKeyword());
// /board/list?pageNum=7&amount=10&type=W&keyword=user04
return "redirect:/board/list";
}
//게시물 삭제
@GetMapping("/remove")
public String remove(Long bno, Criteria cri, RedirectAttributes rttr) {
log.info("삭제 글번호: " + bno);
boardService.remove(bno);
//리스트주소에 필요한 파라미터 작업
rttr.addAttribute("pageNum", cri.getPageNum());
rttr.addAttribute("amount", cri.getAmount());
rttr.addAttribute("type", cri.getType());
rttr.addAttribute("keyword", cri.getKeyword());
return "redirect:/board/list";
}
}
3. Criteria.java
package com.demo.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Criteria {
//필수요소
private int pageNum; // 페이지번호. 1 2 3 4 5
private int amount; // 페이지별 게시물 출력건 수
//선택적 요소
private String type; // 검색종류(제목:T, 내용:C, 작성자:W, 제목+내용: TC, 제목+작성자:TW, 제목+작성자+내용:TCW)
private String keyword; //검색어
public Criteria() {
this(1, 10);
}
public Criteria(int pageNum, int amount) {
super();
this.pageNum = pageNum;
this.amount = amount;
}
// mybatis에서 참조하기위하여, type필드의 정보를 가공. getter메서드 형식
// 검색항목에서 [제목 or 작성자] 선택. type ="TW"
public String[] getTypeArr() {
return type == null? new String[] {} : type.split(""); // {"T", "W"}
}
}
4. PageDTO.java
package com.demo.dto;
import lombok.Getter;
// 클래스 목적? [prev] 1 2 3 4 5 [next ]
// 페이지 번호,이전,다음 표시을 위한 정보를 구성.
@Getter
public class PageDTO {
private int startPage; // 각 블럭의 시작페이지 번호
private int endPage; // 각 블럭의 마지막페이지 번호
// 이전, 다음 표시여부
private boolean prev, next;
//게시판테이블의 데이터 총 개수. db에서 정보를 가져와야 한다.
private int total;
private Criteria cri; // pageNum, amount, type, keyword
public PageDTO(int total, Criteria cri) {
super();
this.total = total;
this.cri = cri;
/*
total(총 데이타 개수) : 13
amount(게시물 출력건 수) : 5
페이지수 : 3 예> 1 2 3
*/
// 블럭에 출력된 페이지 번호의 개수
int pageSize = 10;
// 첫번째 블럭 1 2 3 4 5 [next]
// 두번째 블럭 [prev] 6 7 8 9 10
int endPageInfo = pageSize - 1;
this.endPage = (int) (Math.ceil(cri.getPageNum() / (double) pageSize)) * pageSize;
this.startPage = this.endPage - endPageInfo;
//실제 데이타수에 따른 페이지.
int realEnd = (int) ( Math.ceil((total * 1.0) / cri.getAmount()));
if(realEnd <= this.endPage) {
this.endPage = realEnd;
}
this.prev = this.startPage > 1;
this.next = this.endPage < realEnd;
}
}
5. BoardMapper.java
package com.demo.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import com.demo.domain.BoardVO;
import com.demo.dto.Criteria;
// Mapper Interface는 1)XML 이용 2) Annotation 이용
// 프록시 클래스가 bean 생성
public interface BoardMapper {
// 1)XML 이용(전통적인 SI업체에서는 자주 사용)
// mapper xml파일의 메서드명과 일치되는 id를 참조한다.
// 리스트(목록)
public List<BoardVO> getList();
public List<BoardVO> getListWithPaging(Criteria cri); // pageNum, amount, type, keyword
public int getTotalCount(Criteria cri);
// 2)Annotation 이용
@Select("select * from tbl_board where bno > 0")
public List<BoardVO> getList2();
//글저장하기
public void insert(BoardVO vo);
//글읽기(조회)
public BoardVO get(Long bno);
//글수정하기
public void modify(BoardVO vo);
//글삭제하기
public void remove(Long bno);
}
6. BoardMapper.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.demo.mapper.BoardMapper">
<select id="getList" resultType="com.demo.domain.BoardVO">
<!-- select * from tbl_board where bno > 0 -->
select bno, title, content, writer, regdate, updatedate from tbl_board order by bno desc
</select>
<!-- 재사용목적 -->
<!-- foreach 참조 https://java119.tistory.com/85 -->
<!-- 검색조건 : 제목, 내용, 작성자 경우의 수 6가지 -->
<!-- getTypeArr() 예> 제목+작성자 선택시 {"T", "W" } -->
<sql id="criteria">
<trim prefix="(" suffix=") AND " prefixOverrides="OR">
<foreach collection="typeArr" item="type">
<trim prefix="OR">
<choose>
<when test="type == 'T'.toString()">
title like '%' || #{keyword} || '%'
</when>
<when test="type == 'C'.toString()">
content like '%' || #{keyword} || '%'
</when>
<when test="type == 'W'.toString()">
writer like '%' || #{keyword} || '%'
</when>
</choose>
</trim>
</foreach>
</trim>
</sql>
<select id="getListWithPaging" resultType="com.demo.domain.BoardVO">
<![CDATA[
select rn, bno, title, content, writer, regdate, updatedate
from (
SELECT /*+ INDEX_DESC(TBL_BOARD PK_BOARD) */ ROWNUM RN, bno, title, content, writer, regdate, updatedate
FROM TBL_BOARD
WHERE
]]>
<include refid="criteria" />
<![CDATA[
ROWNUM <= #{pageNum} * #{amount}
)
WHERE RN > (#{pageNum}-1) * #{amount}
]]>
</select>
<select id="getTotalCount" resultType="int">
select count(*) from tbl_board where
<include refid="criteria" />
bno > 0
</select>
<select id="get" resultType="com.demo.domain.BoardVO" parameterType="long">
select bno, title, content, writer, regdate, updatedate from tbl_board where bno = #{bno}
</select>
<insert id="insert" parameterType="com.demo.domain.BoardVO">
insert into tbl_board(bno, title, content, writer)
values(seq_board.nextval, #{title}, #{content}, #{writer})
</insert>
<!--
<insert id="insert" parameterType="com.demo.domain.BoardVO">
<selectKey order="BEFORE" resultType="long" keyProperty="bno">
select seq_board.nextval from dual
</selectKey>
insert into tbl_board(bno, title, content, writer)
values(#{bno}, #{title}, #{content}, #{writer})
</insert>
-->
<update id="modify" parameterType="com.demo.domain.BoardVO">
update tbl_board
set title = #{title}, content = #{content}
where bno = #{bno}
</update>
<delete id="remove" parameterType="long">
delete from tbl_board where bno = #{bno}
</delete>
</mapper>
728x90
'🏫 Open API_JAVA' 카테고리의 다른 글
[79일차] 게시판 댓글 목록 / 페이징 / 모달창 구현 / jQuery 눈도장 (0) | 2022.11.17 |
---|---|
[78일차] REST 방식 / gson 라이브러리 추가 / 게시판에 댓글 기능 구현 (ex04) (0) | 2022.11.15 |
[76일차] 게시판 기능구현 순서 / 의존성 주입 / 게시물 삭제 기능 구현 / 오라클 인덱스 힌트 (0) | 2022.11.13 |
[75일차] 게시판 구조 생성 / 디자인 html 파일 ➡ jsp 형태로 만들기 (0) | 2022.11.13 |
[74일차] Ajax / 파일 업로드 처리기능 구현 / bean 설정 및 라이브러리 추가 (0) | 2022.11.09 |