728x90
반응형
수정과 삭제처리
get.jsp 에 input ~ 복사
modify.jsp form밑에 붙여넣기
modify.jsp 자바스크립트 추가
수정/삭제 처리 후 이동
추가
remove 부분도 추가
MyBatis 에서 전체 데이터의 개수 처리
<BoardMapper.java>
<boardmapper.xml>
sqldeveloper에서 bno 갯수를 구하는 쿼리문 복사 붙여넣기
total bno 갯수를 구하기 위함
<boardService.java>
<BoardServiceImpl.java>
보드서비스에서 기능이 추가되었기 떄문에 보드서비스 구현 클래스에서 기능 추가하라고 에러가 뜬다.
BoardController.java
package org.zerock.controller;
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.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;
import org.zerock.domain.PageDTO;
import org.zerock.service.BoardService;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
@Controller
@Log4j
@RequestMapping("/board/*")
@AllArgsConstructor
public class BoardController {
private BoardService service;
// // Page300 소스코딩 할 때, 아래 5줄 소스는 주석 처리를 해줍니다.
// @GetMapping("/list")
// public void list(Model model) {
// log.info("list 글 목록 조회를 처리합니다!");
// model.addAttribute("list", service.getlList());
// 컨트롤러에서 뷰로 데이터 넘길 때 쓰는 뷰모델에 속성명을 추가하여 서비스에 담긴 겟리스트를 list에 담아서 처리함
// }
// Page300 : 페이징 매개변수 적용 /list 소스 코딩을 아래와 같이 5줄추가합니다.
@GetMapping("/list")
public void list(Criteria cri, Model model) {
log.info("list 글 목록 조회를 처리합니다!" + cri);
model.addAttribute("list", service.getList(cri));
int total = service.getTotal(cri);
log.info("total 전체 데이터 수 = " + total);
// total 변수 데이터 수 = 123로 가정함
// realEnd 13페이지로 13다음에 next없음
// model.addAttribute("pageMaker", new PageDTO(cri, 123));
model.addAttribute("pageMaker", new PageDTO(cri, total));
}
// Page238 11.3 등록 입력 페이지와 등록 처리
// 게시물의 등록 작업은 POST방식으로 처리하지만,
// 화면에서 입력을 받아야 하므로 GET 방식으로 입력 페이지를 볼 수 있도록
// BoardController에 메서드를 추가해 줍니다.
// register() 메서드는 입력 페이지를 보여주는 역할만을 하기 때문에
// 별도의 처리가 필요하지 않습니다.
@GetMapping("/register")
public void register() {
}
@PostMapping("/register") // @PostMapping() POST 방식 URL 메핑
// register() 메서드는 String을 리턴 타입으로 지정하고, Redirect Attributes를
// 파라미터로 지정합니다. 이것은 등록 작업이 끝난 후 다시 목록 화면으로 이동하기 위함이며,
// 추가적으로 새롭게 등록된 게시물의 번호를 같이 전달하기 위해서 RedirectAttributes를
// 이용합니다. 이때, 리턴 시에는 "redirect:" 접두어를 사용하는데,
// 이것을 이용하면 스프링 MVC가 내부적으로 response.sendRedirect()를 처리해 주기
// 때문에 편리합니다.
public String register(BoardVO board, RedirectAttributes rttr) {
log.info("regiser(등록): " + board);
service.register(board);
rttr.addFlashAttribute("result", board.getBno());
//redirect : 갱신해서 보내줌
return "redirect:/board/list";
}
// 조회 처리와 테스트 : 등록처리와 유사하게 조회 처리도 BoardController를 이용해서
// 처리할 수 있습니다. 특별한 경우가 아니라면 조회는 GET 방식으로 처리하므로,
// @GetMapping을 이용합니다.
// @GetMapping({"/get","/modify"})
// Page316 소스 코딩할 때, 아래 5줄 소스 주석처리합니다.
// BoardController의 get() 메서드에는 bno 값을 좀 더 명시적으로 처리하는
// @RequestParam을 이용해서 지정합니다.(파라미터 이름과 변수 이름을 기준으로 동작하기
// 때문에 생략해도 됩니다). 또한 화면 쪽으로 해당 번호의 게시물을 전달해야 하므로
// Model을 파라미터로 지정합니다.
// public void get(@RequestParam("bno") Long bno, Model model) {
// log.info("/get 조회처리");
// log.info("/get or modify 조회처리");
// model.addAttribute("board", service.get(bno));
// }
// Page316 : 조회 페이지에서 다시 목록 페이지로 이동 : 페이지 번호 유지를 위한 BoardController 소스 코딩을 해줍니다.
@GetMapping({"/get","/modify"})
public void get(@RequestParam("bno") Long bno, @ModelAttribute("cri") Criteria cri, Model model) {
log.info("/get or modify 조회처리");
model.addAttribute("board", service.get(bno));
}
// 수정 처리와 테스트 : 수정 작업은 등록과 비슷합니다. 변경된 내용을 수집해서
// BoardVO 파라미터로 처리하고, BoardService를 호출합니다. 수정 작업을 시작하는
// 화면의 경우에는 GET 방식으로 접근하지만 실제 작업은 POST 방식으로 동작하므로
// @PostMapping을 이용해서 처리합니다.
@PostMapping("/modify")
public String modify(BoardVO board, @ModelAttribute("cri") Criteria cri, RedirectAttributes rttr) {
log.info("modify: 수정 처리" + board);
// service.modify() 메서드는 수정 여부를 boolean으로 처리하므로
// 이것을 이용해서 성공한 경우에만 RedirectAttributes에 추가합니다.
if (service.modify(board)) {
rttr.addFlashAttribute("result","success");
}
rttr.addAttribute("pageNum", cri.getPageNum());
rttr.addAttribute("amount", cri.getAmount());
return "redirect:/board/list";
}
// 삭제 처리와 테스트 : 삭제 처리도 조회와 유사하게 BoardController와 테스트 코드를
// 작성합니다. 삭제는 반드시 POST 방식으로만 처리합니다.
@PostMapping("/remove")
public String remove(@RequestParam("bno") Long bno, @ModelAttribute("cri") Criteria cri, RedirectAttributes rttr) {
log.info("remove : 삭제 처리 " + bno);
// BoardController의 remove() 메서드는 삭제 후 페이지의 이동이 필요하므로
// RedirectAttributes를 파라미터로 사용하고, 'redirect'를 이용해서
// 삭제 처리 후에 다시 목록 페이지로 이동 처리 합니다.
if (service.remove(bno)) {
rttr.addFlashAttribute("result", "success");
}
rttr.addAttribute("pageNum", cri.getPageNum());
rttr.addAttribute("amount", cri.getAmount());
return "redirect:/board/list";
}
}
BoardMapper.java
package org.zerock.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;
public interface BoardMapper {
// select * from tbl_board WHERE bno > 0;
// mybtis의 애노테이션 방식
// @Select("select * from tbl_board WHERE bno > 0") // 마이바티스 애노테이션 활용 DB 정보 SELECT구문
public List<BoardVO> getlist();
// Page294 : Criteria 타입을 파라미터로 사용하는 getListWithPaging() 메서드를 선언해 줍니다.
public List<BoardVO> getListWithPaging(Criteria cri);
// xml 형식으로 구현
// insert만 처리되고 생성된 PK 값을 알 필요가 없는 경우에 활용하는 insert() 추상 메서드 선언
public void insert(BoardVO board);
// insert문이 실행되고 생성된 PK값을 알아야하는 경우에 활용하는 insertSelectKey() 추상 메서드 선언
public void insertSelectKey(BoardVO board);
// read(select) 처리를 위한 read() 추상 메서드 정의
public BoardVO read(Long bno);
// delete 처리를 위한 delete() 추상 메서드 정의
public int delete(Long bno);
// update 처리 : 게시물의 업데이트는 제목, 내용, 작성자를 수정 처리 합니다.
// 업데이트할 때는 최종 수정 시간을 데이터베이스 내 현재 시간으로 수정 처리 합니다.
// update는 delete와 마찬가지로 "몇 개의 데이터가 수정되었는가"를 처리할 수 있도록
// int 타입으로 메서드를 설계합니다.
// update 처리를 위한 update() 추상 메서드 정의
public int update(BoardVO board);
// 전체 데이터의 개수를 반환해주는 getTotalCount() 메서드 정의
public int getTotalCount(Criteria cri);
}
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" >
<!-- MyBatis xml 파일 작성 시 반드시 mapper 태그의 namespace 속성값을
Mapper 인터페이스와 동일한 이름으로 설정해야 합니다. -->
<mapper namespace="org.zerock.mapper.BoardMapper">
<!-- select 태그의 id 속성값은 메서드의 이름과 일치하게 작성합니다.
resultType 속성의 값은 select 쿼리의 결과를 특정 클래스의 객체로
만들기 위해서 설정합니다. -->
<!-- select * from tbl_board WHERE bno > 0; -->
<select id="getlist" resultType="org.zerock.domain.BoardVO">
<!-- MyBatis xml 파일 작성에 사용한 CDATA 부분은 XML에서 부등호를
사용하기 위해서 사용합니다. 쿼리문이 한 눈에 보임, 관리 측면에서 XML활용하기 좋음-->
<!-- ↓ @SELECT 역할을 함 -->
<![CDATA[
select * from tbl_board WHERE bno > 0
]]>
</select>
<!-- create(insert) 처리 -->
<!-- MyBatis는 내부적으로 JDBC의 PreparedStatement를 활용하고,
필요한 파라미터를 처리하는 ?에 대한 치환은 #{속성}을 이용해서 처리합니다. -->
<!-- insert만 처리되고 생성된 PK 값을 알 필요가 없는 경우 -->
<!-- insert into tbl_board (bno, title, content, writer)
values (seq_board.nextval, '테스트 제목', '테스트 내용', 'user00'); -->
<insert id="insert">
insert into tbl_board (bno, title, content, writer) values (seq_board.nextval, #{title}, #{content}, #{writer})
</insert>
<!-- insert문이 실행되고 생성된 PK 값을 알아야 하는 경우 -->
<insert id="insertSelectKey">
<!-- selectKey는 주로 PK값을 미리(BEFORE) SQL을 통해서 처리해 두고
특정한 이름으로 결과를 보관하는 방식입니다. -->
<selectKey keyProperty="bno" order="BEFORE" resultType="long">
SELECT seq_board.nextval from dual
</selectKey>
<!-- bno 를 지정하면 select에서 값을 가져옴, 연계값이 있을 때 먼저 만들어진 게시물을 조회하고 처리-->
insert into tbl_board (bno, title, content, writer) values (#{bno}, #{title}, #{content}, #{writer})
</insert>
<!-- read(select) 처리 -->
<!-- select * from tbl_board where bno =3; -->
<select id="read" resultType="org.zerock.domain.BoardVO">
select * from tbl_board where bno = #{bno}
</select>
<!-- DELETE 처리 -->
<!-- delete from tbl_board where bno = 40 -->
<delete id="delete">
delete from tbl_board where bno = #{bno}
</delete>
<!-- UPDATE 처리 -->
<!-- 기존에 있는 글을 인지 한 다음에 처리 -->
<!-- update 칼럼이 최종 수정 시간을 의미하는 칼럼이기 때문에 현재 시간으로 변경해 줍니다.
regdate 칼럼은 최초 등록 생성 시간이므로 수정하지 않습니다. #{title}과 같은
부분은 파라미터로 전달된 BoardVO 객체의 getTitle()과 같은 메서드들을
호출해서 파라미터들이 처리 됩니다. -->
<!-- UPDATE tbl_board set title = '수정된 제목', content = '수정된 내용', writer = '김국진', updatedate = sysdate where bno = 5; -->
<update id="update">
UPDATE tbl_board set title = #{title}, content = #{content}, writer = #{writer}, updatedate = sysdate where bno = #{bno}
</update>
<!-- SELECT 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 ROWNUM <=20
)
WHERE RN > 10;
(ROWNUM이 11 ~ 20 번까지 기준으로 데이터보여줘)
-->
<!-- Page294 : 아래에 getListWithPageing 메서드 처리 태그르 추가해줍니다-->
<select id="getListWithPaging" resultType="org.zerock.domain.BoardVO">
<![CDATA[
SELECT 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 ROWNUM <= #{pageNum} * #{amount}
)
WHERE RN > (#{pageNum}-1) * #{amount}
]]>
</select>
<!-- SELECT COUNT(*) FROM tbl_board WHERE bno > 0; -->
<select id="getTotalCount" resultType="int">
SELECT COUNT(*) FROM tbl_board WHERE bno > 0
</select>
</mapper>
BoardService.java
package org.zerock.service;
import java.util.List;
import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;
public interface BoardService {
// register = insert
public void register(BoardVO board);
// get = 상세보기
public BoardVO get(Long bno);
// modify = update
public boolean modify(BoardVO board);
// remove = delete
public boolean remove(Long bno);
// Page299 코딩할 때, 아래 1줄 소스는 주석 처리해줍니다.
// public List<BoardVO> getlList();
// Page299 : 페이징 처리가 적용되는 getList() 메서드 선언
public List<BoardVO> getList(Criteria cri);
// Page323 : 전체 데이터스르 구해주는 getTotal() 메서드 선언
public int getTotal(Criteria cri);
}
BoardServiceImpl.java
package org.zerock.service;
import java.util.List;
import org.springframework.stereotype.Service;
import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;
import org.zerock.mapper.BoardMapper;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
@Log4j
@Service // 계층 구조상 주로 비즈니스 영역을 담당하는 객체임을 표시하기 위해 사용함.
@AllArgsConstructor
public class BoardServiceImpl implements BoardService{
// @Setter(onMethod_ = @Autowired)
// Spring 4.3 이상에서는 단일 파라미터를 받는 생성자의 경우 자동 처리
// (파라미터를 자동으로 주입할 수 있음. 즉, 위에 @Setter 구문 안써도 됨)
private BoardMapper mapper;
@Override
public void register(BoardVO board) {
log.info("register 게시글 등록 서비스 실행!" + board);
mapper.insertSelectKey(board);
// service > 기능 . mapper >> mybatis
}
// 특정 글 상세 조회 작업의 기능 구현
@Override
public BoardVO get(Long bno) {
log.info("get... 특정 글 내용을 조회합니다!" + bno);
return mapper.read(bno);
}
@Override
public boolean modify(BoardVO board) {
log.info("modify... 게시글을 수정 처리합니다!" + board);
// 정상적으로 수정이 이루어지면 1이라는 값이 반환되기 때문에
// '==' 연산자를 이용해서 true/false를 처리할 수 있습니다.
return mapper.update(board) == 1;
}
@Override
public boolean remove(Long bno) {
log.info("remove... 게시글을 삭제 처리합니다!" + bno);
// 정상적으로 수정이 이루어지면 1이라는 값이 반환되기 때문에
// '==' 연산자를 이용해서 true/false를 처리할 수 있습니다.
return mapper.delete(bno) == 1;
}
// 목록(리스트) 작업의 기능구현
// Page299 코딩할 때, 아래 5줄 소스는 주석 처리해줍니다.
// @Override
// public List<BoardVO> getlList() {
// log.info("getList... 목록 리스트 정보를 보여줍니다!");
// return mapper.getlist();
// }
// Page299 : 페이징 매개변수가 적용된 getList() 메서드 선언
@Override
public List<BoardVO> getList(Criteria cri){
log.info("get List with criteria : " + cri);
return mapper.getListWithPaging(cri);
}
// 전체 데이터수를 구해주는 getTotal() 메서드 선언
@Override
public int getTotal(Criteria cri) {
log.info("get total count: 전체 데이터수를 구해줍니다!");
return mapper.getTotalCount(cri);
}
}
728x90
반응형
'☭DEVELOPER > #2 웹개발(자바기반 풀스택)' 카테고리의 다른 글
[BACKEND]검색 후 글 목록으로 돌아가기 (1) | 2023.10.05 |
---|---|
[BACKEND] 검색처리 (0) | 2023.10.04 |
[BACKEND] MyBatis와 스프링에서 페이징 처리 (0) | 2023.10.02 |
[BACKEND]오라클 데이터베이스 페이징 처리 (0) | 2023.10.02 |
[BACKEND]스프링_스프링의 특징과 의존성 주입 (0) | 2023.09.21 |