빅데이터 Java 개발자 교육 [Spring - (일괄기능 및 뷰)]

Jun_Gyu·2023년 5월 10일
0
post-thumbnail

게시글 일괄수정 및 삭제 (+ 페이지네이션)

Board Entity

package com.example.entity;

import java.math.BigDecimal;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.SequenceGenerator;

import org.hibernate.annotations.CreationTimestamp;
import org.springframework.format.annotation.DateTimeFormat;

import lombok.Data;

@Data
@Entity
@SequenceGenerator(name = "SEQ_BOARD_NO", sequenceName = "SEQ_BOARD_NO", initialValue = 1, allocationSize = 1)
public class Board {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_BOARD_NO")
    @Column(name = "NO")
    private BigDecimal no;

    private String title; // 글제목

    @Lob
    private String content;

    private String writer;

    private BigDecimal hit;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    @CreationTimestamp
    private Date regdate;
}

BigDecimal 타입 오류 수정 import java.math.BigDecimal; 임포트

Board Repository (+ Pagenation)

package com.example.repository;

import java.math.BigDecimal;
import java.util.List;

import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.entity.Board;

@Repository
public interface BoardRepository extends JpaRepository<Board, BigDecimal> {

    // SELECT * FROM board ORDER BY no DESC;
    List<Board> findAllByOrderByNoDesc();


    /*----------------- 3. 검색어 타입에 따른 메소드 3개 만들기 -------------------*/

    // SELECT * FROM board WHERE title LIKE '% || ? || %' ORDER BY no DESC;
    List<Board> findByTitleIgnoreCaseContainingOrderByNoDesc(String titleText);
    // IgnoreCase는 대소문자 구분없이 검색할 수 있게 해줌.

    // SELECT * FROM board WHERE content LIKE '% || ? || %' ORDER BY no DESC;
    List<Board> findByContentIgnoreCaseContainingOrderByNoDesc(String contentText);

    // SELECT * FROM board WHERE writer LIKE '% || ? || %' ORDER BY no DESC;
    List<Board> findByWriterIgnoreCaseContainingOrderByNoDesc(String writerText);


    // 페이지네이션
    List<Board> findByTitleIgnoreCaseContainingOrderByNoDesc(String titleText, Pageable pageable);
    List<Board> findByContentIgnoreCaseContainingOrderByNoDesc(String contentText, Pageable pageable);
    List<Board> findByWriterIgnoreCaseContainingOrderByNoDesc(String writerText, Pageable pageable);

    // 페이지네이션용 갯수 cnt
    long countByTitleIgnoreCaseContainingOrderByNoDesc(String titleText);
    long countByContentIgnoreCaseContainingOrderByNoDesc(String contentText);
    long countByWriterIgnoreCaseContainingOrderByNoDesc(String writerText);
}

Board2Controller

package com.example.controller.jpa;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.example.entity.Board;
import com.example.repository.BoardRepository;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Slf4j
@Controller
@RequestMapping(value = "/board2")
@RequiredArgsConstructor
public class Board2Controller {

    final BoardRepository bRepository; // 저장소 객체
    final String format = "Board2Controller => {}";
    final HttpSession httpSession;// 세션객체

    @PostMapping(value = "/updatebatchaction.pknu")
    public String updatePOST(
            @RequestParam(name = "no[]") long[] no,
            @RequestParam(name = "title[]") String[] title,
            @RequestParam(name = "content[]") String[] content,
            @RequestParam(name = "writer[]") String[] writer) {
        try {
            List<Board> list = new ArrayList<>();
            for (int i = 0; i < no.length; i++) {
                // 1. no를 이용하여 기존 정보 가져오기
                Board board = bRepository.findById(BigDecimal.valueOf(no[i])).orElse(null);
                // 2. 기존정보에 위에서 받은 제목, 내용, 작성자 변경하기
                board.setTitle(title[i]);
                board.setContent(content[i]);
                board.setWriter(writer[i]);
                // 3. list에 담기
                list.add(board);
            }

            // 4.일괄저장하기
            bRepository.saveAll(list);
            return "redirect:/board2/selectlist.pknu";
        } catch (Exception e) {
            return "redirect:/home.do";
        }
    }

    @SuppressWarnings("unchecked") // 경고 없애기
    @GetMapping(value = "/updatebatch.pknu")
    public String updateBatchGET(Model model) {
        try {
            List<BigDecimal> chk = (List<BigDecimal>) httpSession.getAttribute("chk[]");
            List<Board> list = bRepository.findAllById(chk);
            model.addAttribute("list", list);
            return "/board2/updatebatch";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
    }

    @PostMapping(value = "/updatebatch.pknu")
    public String updateBatchPOST(@RequestParam(name = "chk[]") List<BigDecimal> chk) {
        try {
            httpSession.setAttribute("chk[]", chk);
            return "redirect:/board2/updatebatch.pknu";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
    }

    @PostMapping(value = "/deletebatch.pknu")
    public String deleteBatchPOST(
            @RequestParam(name = "chk[]") List<BigDecimal> chk) {
        try {
            log.info(format, chk.toString());
            bRepository.deleteAllById(chk);
            return "redirect:/board2/selectlist.pknu";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
    }

    @PostMapping(value = "/insertbatch.pknu")
    public String insertBatchPOST(
            @RequestParam(name = "title[]") String[] title,
            @RequestParam(name = "content[]") String[] content,
            @RequestParam(name = "writer[]") String[] writer) {
        try {
            List<Board> list = new ArrayList<>();
            for (int i = 0; i < title.length; i++) {
                Board brd = new Board();
                brd.setTitle(title[i]);
                brd.setContent(content[i]);
                brd.setWriter(writer[i]);
                brd.setHit(BigDecimal.valueOf(1));
                list.add(brd);
            }
            bRepository.saveAll(list);

            return "redirect:/board2/selectlist.pknu";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
    }

    @GetMapping(value = "/insertbatch.pknu")
    public String insertBatchGET(Model model) {
        try {
            return "/board2/insertbatch";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
    }

    // 127.0.0.1:9090/ROOT/board2/selectlist.pknu
    // 1. 전달값 받기 ?page=1&type=writer&text=검색어
    @GetMapping(value = "/selectlist.pknu")
    public String selectListGET(
            Model model,
            @RequestParam(name = "page", defaultValue = "1") int page,
            @RequestParam(name = "type", defaultValue = "title") String type,
            @RequestParam(name = "text", defaultValue = "") String text) {
        try {
            // 2. 타입에 따라서 다른 메소드 호툴
            // findByTitle...()
            if(page==0){
                return "redirect:/board2/selectlist.pknu?page=1&type=title&text=";
            }
            PageRequest pageRequest = PageRequest.of((page-1), 10);

            List<Board> list = bRepository.findByTitleIgnoreCaseContainingOrderByNoDesc(text, pageRequest);
            long total = bRepository.countByTitleIgnoreCaseContainingOrderByNoDesc(text);
            if (type.equals("content")) {
                list = bRepository.findByContentIgnoreCaseContainingOrderByNoDesc(text, pageRequest);
                total = bRepository.countByContentIgnoreCaseContainingOrderByNoDesc(text);
            } else if (type.equals("writer")) {
                list = bRepository.findByWriterIgnoreCaseContainingOrderByNoDesc(text, pageRequest);
                total = bRepository.countByWriterIgnoreCaseContainingOrderByNoDesc(text);
            }
            model.addAttribute("list", list);
            model.addAttribute("pages", (total-1)/10+1);
            return "/board2/selectlist";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }

    }

}

insertbatch.html

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h3>일괄추가하기</h3>
    <a th:href="@{/board2/selectlist.pknu}"><button>목록으로</button></a>
    <hr />

    <form th:action="@{/board2/insertbatch.pknu}" method="post">
        <th:block th:each="i : ${#numbers.sequence(1,3)}">
            <input type="text" name="title[]" th:value="|title_${i}|" placeholder="제목" />
            <input type="text" name="content[]" th:value="|contnent_${i}|" placeholder="내용" />
            <input type="text" name="writer[]" th:value="|writer_${i}|" placeholder="작성자" />
            <br />
        </th:block>
        <input type="submit" value="일괄추가">
    </form>
</body>

</html>

updatebatch.html

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h3>일괄수정하기(board)</h3>
    <a th:href="@{/board2/insertbatch.pknu}"><button>일괄추가</button></a>
    <hr />
    <form th:action="@{/board2/updatebatchaction.pknu}" method="post">
        <table>
            <tr th:each="obj : ${list}">
                <td><input type="text" name="no[]" th:value="${obj.no}" readonly /></td>
                <td><input type="text" name="title[]" th:value="${obj.title}" /></td>
                <td><input type="text" name="content[]" th:value="${obj.content}" /></td>
                <td><input type="text" name="writer[]" th:value="${obj.writer}" /></td>
                <td><input type="text" th:value="${obj.hit.longValue()}" readonly /></td>
                <td><input type="text" th:value="${obj.regdate}" readonly /></td>
            </tr>
        </table>
        <input type="submit" value="일괄수정">
    </form>
</body>

</html>

테이블뷰

Board1View Entity

package com.example.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import org.springframework.data.annotation.Immutable;

import lombok.Data;

@Data
@Immutable // 뷰일경우에 추가. => 조회만 가능한 entity가 됨.
@Entity
@Table(name = "BOARD1_VIEW")
public class Board1View {

    @Id
    @Column(name = "NO")
    private Long no = 0L;
    
    @Column(name = "TITLE")
    private String title = null;

}

@Immutable는 뷰일때 추가하는 어노테이션으로, 추가시 조회만 가능한 entity가 됨.

Board1View Repository

package com.example.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.entity.Board1View;

@Repository
public interface Board1ViewRepository extends JpaRepository<Board1View, Long> {

   // SELECT * FROM Board1View WHERE title = 1? AND no = 2?;
   List<Board1View> findByNoAndTitle(Long no, String title);

   // SELECT * FROM Board1View WHERE title = 1? OR no = 2?;
   List<Board1View> findByNoOrTitle(Long no, String title);

   // SELECT * FROM Board1View WHERE no IN 1?;
   List<Board1View> findByNoIn(Long[] no);

   // SELECT * FROM Board1View WHERE title IN 1?;
   List<Board1View> findByTitleIn(String[] title);

}

Board1View Controller

package com.example.controller.jpa;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.example.entity.Board1View;
import com.example.repository.Board1ViewRepository;

import lombok.RequiredArgsConstructor;

@Controller
@RequestMapping(value = "/board1view")
@RequiredArgsConstructor
public class Board1ViewController {

   final Board1ViewRepository b1vRepository;

   // num이 없으면 0 또는 전체
   // num이 1이면 and
   // num이 2이면 or
   // num이 3이면 글번호 in
   // num이 4이면 제목 in

   // 127.0.0.1:9090/ROOT/board1view/selectlist.pknu
   @GetMapping(value = "/selectlist.pknu")
   public String selectlistGET(
           Model model,
           @RequestParam(name = "num", defaultValue = "0", required = false) Long num,
           @RequestParam(name = "boardNo", defaultValue = "0", required = false) Long boardNo,
           @RequestParam(name = "boardTitle", defaultValue = "", required = false) String boardTitle,
           @RequestParam(name = "boardNo1", defaultValue = "", required = false) String boardNo1,
           @RequestParam(name = "boardTitle1", defaultValue = "", required = false) String boardTitle1
           ) {
       try {
           List<Board1View> list = b1vRepository.findAll();
           if (num == 0L) {
               
           } else if (num == 1L) {
              list = b1vRepository.findByNoAndTitle(boardNo, boardTitle);
           } else if (num == 2L) {
              list = b1vRepository.findByNoOrTitle(boardNo, boardTitle);
           } else if (num == 3L) {
               String[] arr = boardNo1.split(","); // split 활용, ","을 구분
               Long[] arrLong = new Long[arr.length];
               for(int i = 0; i<arr.length;i++){
                arrLong[i] = Long.parseLong(arr[i]);
               }
               list = b1vRepository.findByNoIn(arrLong);
           } else if (num == 4L) { 
               String[] arr = boardTitle1.split(",");
               list = b1vRepository.findByTitleIn(arr);
           }
           model.addAttribute("list", list);
           return "/board1view/selectlist";
       } catch (Exception e) {
           e.printStackTrace();
           return "redirect:/home.do";
       }

   }

}

selectlist.html

<!DOCTYPE html>
<html lang="ko">

<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>

<body>
   <h3>게시판목록(board1View)</h3>

   <hr />
   <form th:action="@{/board1view/selectlist.pknu}" method="get">
       <input type="hidden" name="num" value="1" />
       <input type="text" name="boardNo" placeholder="글번호 입력" />
       <input type="text" name="boardTitle" placeholder="제목" />
       <input type="submit" value="글번호와 제목이 정확하게 일치하는 것만 조회">
   </form>
   <hr />

   <form th:action="@{/board1view/selectlist.pknu}" method="get">
       <input type="hidden" name="num" value="2" />
       <input type="text" name="boardNo" placeholder="글번호 입력" />
       <input type="text" name="boardTitle" placeholder="제목" />
       <input type="submit" value="글번호와 제목 둘 중 하나이상 일치하는 것만 조회">
   </form>
   <hr />

   <form th:action="@{/board1view/selectlist.pknu}" method="get">
       <input type="hidden" name="num" value="3" />
       <input type="text" name="boardNo1" placeholder="글번호를 ,로 구분해서 입력" />
       <input type="submit" value="글번호에 해당하는 항목만 조회">
   </form>
   <hr />

   <form th:action="@{/board1view/selectlist.pknu}" method="get">
       <input type="hidden" name="num" value="4" />
       <input type="text" name="boardTitle1" placeholder="제목을 ,로 구분해서 입력" />
       <input type="submit" value="글번호에 해당하는 항목만 조회">
   </form>
   <hr />

   <table border="1">
       <thead>
           <tr>
               <td>글번호</td>
               <td>제목</td>
           </tr>
       </thead>
       <tbody>
           <tr th:each="obj :${list}">
               <td th:text="${obj.no.longValue()}"></td>
               <td th:text="${obj.title}"></td>
           </tr>
       </tbody>
   </table>
</body>

</html>
profile
시작은 미약하지만, 그 끝은 창대하리라

0개의 댓글