spring 2022/03/07 (admin,book,alert)

무간·2022년 3월 7일

파일명 alert.jsp

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
    <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">

        <script th:inline="javascript">
            /*<![CDATA[*/
            const msg = [[${msg}]];
            alert(msg); //알림표시
            window.location.replace( [[${url}]] ); //이동하는 페이지
            /*]]*/ 
        </script>
    </head>
</html>

파일명 Boot20220228Application.java

package com.example.boot_20220228;

import java.time.Duration;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.session.data.mongo.JdkMongoSessionConverter;
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;

@SpringBootApplication

// 임의로만들 컨트롤러, 서비스의 위치
@ComponentScan(basePackages = {"com.example.controller","com.example.service"})

// 임의로 만든저장소 위치	
@EnableMongoRepositories(basePackages = {"com.example.repository"})

// 세션 정보를 몽고DB에 저장하기 위한 설정
@EnableMongoHttpSession(collectionName = "sessions", maxInactiveIntervalInSeconds = 1800)
public class Boot20220228Application {

	public static void main(String[] args) {
		SpringApplication.run(Boot20220228Application.class, args);
	}
	
	// 몽고DB에서 attr을 쉽게 확인하기 위해서, 객체, 배열 X 
	// @Bean
	// public JacksonMongoSessionConverter mongoSessionConverter(){
	// 	return new JacksonMongoSessionConverter();
	// }

	// attr의 값이 byte[]로 보여짐, 객체, 배열.. 가능
	@Bean
	public JdkMongoSessionConverter mongoSessionConverter(){
		return new JdkMongoSessionConverter(Duration.ofMinutes(30));
	}
}

파일명 AdminController.java

package com.example.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpSession;

import com.example.entity.Book;
import com.example.service.BookDB;
import com.example.service.SequenceService;

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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

// 1. 컨트롤러
@Controller
@RequestMapping(value = "/admin")
public class AdminController {

    @Autowired
    BookDB bookDB;    

    @Autowired
    SequenceService sequenceService;

    @Autowired
    HttpSession httpSession;
    
    @PostMapping(value = "/insertbatch")
    public String insertPOST(
        @RequestParam(name = "title")String[] title,
        @RequestParam(name = "price")long[] price,
        @RequestParam(name = "writer")String[] writer,
        @RequestParam(name = "category")String[] category ){

        // 1. 빈 리스트 만들기
        List<Book> list = new ArrayList<>();
        for(int i=0; i<title.length; i++ ){ //0 1
            // jsp에서 controller로 데이터 전달 되는지 확인
            // System.out.println(title[i] + "," + price[i] + "," + writer[i] + ","+category[i] );
            
            // 2. Book객체 만들기(시퀀스를 코드를 채워, 날짜도)
            // 시퀀스명 SEQ_BOOK4_CODE
            Book book = new Book();
            book.setCode(sequenceService.generatedSequence("SEQ_BOOK4_CODE"));
            book.setTitle(title[i]);
            book.setPrice(price[i]);
            book.setWriter(writer[i]);
            book.setCategory(category[i]);
            book.setRegdate(new Date());
            
            // 3. 리스트에 추가하기
            list.add(book);
        }        
        bookDB.insertBatchBook(list);
        return "redirect:/admin/selectlist";
    }
    
    //127.0.0.1:8080/admin/insertbatch
    @GetMapping(value = "/insertbatch")
    public String insertGET() {
        return "admin/insertbatch";
    }
    
    //127.0.0.1:8080/admin/selectlist?page=1&text=
    @GetMapping(value = "/selectlist")
    public String selectlistGET(Model model,
        @RequestParam(name = "page",defaultValue = "1")int page,
        @RequestParam(name = "text",defaultValue = "")String text ){            

        List<Book> list = bookDB.selectListPageSearchBook(page, text);
        System.out.println(list.size());
        long pages = bookDB.countSearchBook(text);
        
        // jsp로 전달(변수,값) => 변수사용
        model.addAttribute("list", list);
        model.addAttribute("pages", (pages-1)/10 +1);
        
        return "admin/selectlist";
    }

    @PostMapping(value = "/action")
    public String actionPOST(
        @RequestParam(name = "btn")String btn,
        @RequestParam(name = "chk")List<Long> code) {      
        // // warpper 클래스
        // private long a = 0L;
        // private Long a = null; Long클래스 형식
        // long Long
        // int Integer
        // double Double        
        // List<Object>
        // long[] == List<long>
        for(Long tmp : code){
            System.out.println("체크된 코드 : " + tmp);
        }

        System.out.println("누른 버튼 : " + btn); // 일괄삭제 or 일괄수정
        if(btn.equals("일괄삭제")){
            // 1) DB에 삭제하기 구현
            bookDB.deleteBatchBook(code);
            // 2) 회원목록, 물품목록 검색기능 추가하기
        }
        else if(btn.equals("일괄수정")){
            httpSession.setAttribute("CHK", code);
            //페이지를 이동후에 세션에서 꺼내기
            return "redirect:/admin/updatebatch";

        }
        // 목록으로 이동하기
        return "redirect:/admin/selectlist";
    }

    //127.0.0.1:8080/admin/updatebatch
    @GetMapping(value = "/updatebatch")
    public String updateGET(Model model) {
        // 형변환을 하면 데이터가 안전하지 않음을 경고
        // 세션에 추가할때와 가지고 올때의 타입을 정확하게 매칭
        @SuppressWarnings({"unchecked"})
        // DB에서 code에 해당하는 항목 정보만 Session에 가져옴
        // jsp로 전달함.
        // jsp를 표시함.
        List<Long> code = (List<Long>)httpSession.getAttribute("CHK");

        List<Book> list = bookDB.selectListWhereIn(code);
        model.addAttribute("list", list);
        
        return "admin/updatebatch";
    }

    @PostMapping(value = "/updatebatch")
    public String updatePOST(
        Model model,
        @RequestParam(name = "code")long[] code,
        @RequestParam(name = "title")String[] title,
        @RequestParam(name = "price")long[] price,
        @RequestParam(name = "writer")String[] writer,
        @RequestParam(name = "category")String[] category ){

        // 빈 리스트 만들기
        List<Book> list = new ArrayList<>();
        for(int i=0; i<code.length; i++ ){
            Book book = new Book();
            book.setCode(code[i]);
            book.setTitle(title[i]);
            book.setPrice(price[i]);
            book.setWriter(writer[i]);
            book.setCategory(category[i]);
            // 리스트에 추가하기
            list.add(book);
        }        
        long ret = bookDB.updateBatchBook(list);
        if(ret == 1){
            model.addAttribute("msg","일괄수정되었습니다.");
            model.addAttribute("url","/admin/selectlist");
            return "alert";
        }
        
        model.addAttribute("msg","일괄수정 실패하였습니다.");
        model.addAttribute("url","/admin/selectlist");
        return "alert";
    }
}

파일명 BookDB.java

package com.example.service;

import java.util.List;

import com.example.entity.Book;

import org.springframework.stereotype.Service;

@Service
public interface BookDB {

    // 일괄등록
    public int insertBatchBook(List<Book> list);

    // 목록(페이지 + 검색)
    public List<Book> selectListPageSearchBook(int page, String text);
    
    // 페이지네이션용 (검색어)
    public long countSearchBook(String text);

    // 일괄 삭제
    public long deleteBatchBook(List<Long> code);

    // 코드에 해당하는 목록 가져오기
    public List<Book> selectListWhereIn(List<Long> code);

    // 일괄 수정
    public long updateBatchBook(List<Book> list);

}

파일명 bookDBImpl.java

package com.example.service;

import java.util.Collection;
import java.util.List;

import com.example.entity.Book;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

// 1. 서비스
@Service
public class BookDBImpl implements BookDB{ // 2. 설계 인터페이스 구현

    // 3. DB연결 객체 생성
    @Autowired
    MongoTemplate mongoDB;

    @Override
    public int insertBatchBook(List<Book> list) {        
        try {
            // 4. 실제 수행
            // collection 구조에 의해서 list를 사용할때는 부모인 collection사용이 유리함
            Collection<Book> retList = mongoDB.insert(list, Book.class);

            if(retList.size() == list.size()){
                return 1;
            }
            return 0;            
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    @Override
    public List<Book> selectListPageSearchBook(int page, String text) {
        try {
            Query query = new Query();
            
            //검색패턴( .*a.*  => a가 포함된 것 해당 ), 정규식
            Criteria criteria = Criteria.where("title").regex(".*"+ text + ".*");            
            query.addCriteria(criteria);
            
            // 페이지네이션(0 부터 시작)
            Pageable pageable = PageRequest.of(page-1,10);
            query.with(pageable);

            // 정렬 (_id기준 내림차순)
            Sort sort = Sort.by(Direction.DESC,"_id");
            query.with(sort);

            return mongoDB.find(query, Book.class);            
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public long countSearchBook(String text) {
        try {
            Query query = new Query();
            
            //검색패턴( .*a.*  => a가 포함된 것 해당 ), 정규식
            Criteria criteria = Criteria.where("title").regex(".*"+ text + ".*");            
            query.addCriteria(criteria);

            return mongoDB.count(query, Book.class);            
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }    

    @Override
    public long deleteBatchBook(List<Long> code) {
        try {
            // long[] => List<long>
            // code   => [2,5,1] =>  collection<long>
            Query query = new Query();
            query.addCriteria(Criteria.where("_id").in(code));

            DeleteResult result = mongoDB.remove(query, Book.class);
            if(result.getDeletedCount() == (long)code.size() ){
                return 1;
            }
            return 0;            
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    @Override
    public List<Book> selectListWhereIn(List<Long> code) {
        try {
            Query query = new Query();
            query.addCriteria(Criteria.where("_id").in(code));

            // DESC : 내림차순, ASC : 오름차순
            Sort sort = Sort.by(Direction.DESC,"_id");
            query.with(sort);

            return mongoDB.find(query, Book.class);                      
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public long updateBatchBook(List<Book> list) {
        try {
            long updateCount = 0;
            for(Book tmp : list ){
                Query query = new Query();
                query.addCriteria(Criteria.where("_id").is(tmp.getCode()));

                Update update = new Update();
                update.set("title", tmp.getTitle());
                update.set("price", tmp.getPrice());
                update.set("writer", tmp.getWriter());
                update.set("category", tmp.getCategory());

                UpdateResult result = mongoDB.updateFirst(query, update, Book.class);                
                updateCount += result.getMatchedCount(); 
            }
            if(updateCount == list.size()){
                return 1;
            }
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }
}

파일명 insertbatch.jsp

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{/member/header::headerFragment}"></head>
    <body>
        <div style="padding: 20px;">
            <h3>admin insert</h3>
            <hr />
        <form th:action="@{/admin/insertbatch}" method="post">
            <table class="table">
                <tr>
                    <th>제목</th>
                    <th>가격</th>
                    <th>저자</th>
                    <th>분류</th>
                </tr>

                <tr th:each="i : ${#numbers.sequence(1,2)}">
                    <td><input type="text" value="1" name="title"/></td>
                    <td><input type="text" value="2" name="price"/></td>
                    <td><input type="text" value="가나다" name="writer"/></td>
                    <td>
                        <select name="category">
                            <option>A</option>
                            <option>B</option>
                            <option>C</option>
                        </select>
                    </td>                    
                </tr>

            </table>
            <input type="submit" class="btn btn-primary" value="도서일괄등록"/>
        </form>
        
        <hr />
        <div th:replace="~{/member/footer ::footerFragment}"></div>
    </div>
</body>
</html>

파일명 selectlist.jsp

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<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>게시판</title>
    <link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.css}"/>
    <script type="text/javascript" src="@{/js/bootstrap.min.js}"></script>
</head>
<body>
    <div style="padding: 20px;">
        <h3>board list</h3>
        <hr />

        <a th:href="@{/board/insert}" class="btn btn-primary" >글쓰기</a>
        <form th:action="@{/board/action}" method="post">
            <input type="submit" name="btn" value="1개 삭제" class="btn btn-primary"/>
            <input type="submit" name="btn" value="1개 수정" class="btn btn-primary"/>
            <hr />
            <table class="table table-striped">
                <tr>             
                    <th>radio</th>   
                    <th>글번호</th>
                    <th>제목</th>                
                    <th>작성자</th>
                    <th>조회수</th>
                    <th>작성일</th>
                </tr>

                <tr th:each="tmp, idx : ${list}">
                    <td><input type="radio" name="rad" th:value="${tmp.no}" /></td>
                    <td th:text="${tmp.no}"></td>
                    <td th:text="${tmp.title}"></td>
                    <td th:text="${tmp.writer}"></td>
                    <td th:text="${tmp.hit}"></td>
                    <td th:text="${tmp.regdate}"></td>                
                </tr>
            </table>
        </form>
    </div>    
</body>
</html>

파일명 updatebatch.jsp

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{/member/header::headerFragment}"></head>
    <body>
        <div style="padding: 20px;">
            <h3>book update</h3>
            <hr />
        <form th:action="@{/admin/updatebatch}" method="post">
            <table class="table">
                <tr>
                    <th>코드</th>
                    <th>제목</th>
                    <th>가격</th>
                    <th>저자</th>
                    <th>분류</th>
                    <th>등록일</th>

                </tr>

                <tr th:each="tmp : ${list}">
                    <td ><input type="text" th:value="${tmp.code}" name="code" readonly></td>
                    <td><input type="text" th:value="${tmp.title}" name="title"></td>
                    <td><input type="text" th:value="${tmp.price}" name="price"></td>
                    <td><input type="text" th:value="${tmp.writer}" name="writer"></td>
                    <td>                        
                        <!-- <p th:text="${tmp.category}"></p> -->
                        <select name="category">
                            <option th:selected="${#strings.equals(tmp.category, 'A')}">A</option> 
                            <option th:selected="${tmp.category == 'B'}">B</option>
                            <option th:selected="${tmp.category == 'C'}">C</option>
                        </select>
                    </td>
                    <td th:text="${tmp.regdate}"></td>
                </tr>
            </table>
            <input type="submit" class="btn btn-primary" value="도서일괄수정"/>
        </form>
        
        <hr />
        <div th:replace="~{/member/footer ::footerFragment}"></div>
    </div>
</body>
</html>
profile
당신을 한 줄로 소개해보세요

0개의 댓글