th:selected / modal

์ด๋™์–ธยท2024๋…„ 9์›” 11์ผ

new world

๋ชฉ๋ก ๋ณด๊ธฐ
43/62
post-thumbnail

9.11 (์ˆ˜)

1. BoardController.java ๋ถ„์„

package org.demo.springdemo.board.controller;

@Controller
@RequestMapping("/board")
@Log4j2
@RequiredArgsConstructor
public class BoardController {

    private final UploadUtil uploadUtil;

    @GetMapping("/register")
    public void register(){

    }

    @PostMapping("/register")
    public String register(BoardRegisterDTO boardRegisterDTO, RedirectAttributes rttr){

        log.info("register: "+ boardRegisterDTO);

        List<String> uploadedFileNames = uploadUtil.upload(boardRegisterDTO.getImges());
        //uuid์™€ ๊ธฐ์กดํŒŒ์ผ์ด ๊ฒฐํ•ฉ๋œ ํŒŒ์ผ์ด uploadedFileNames์— ๋‹ด๊น€
        boardRegisterDTO.setFileNames(uploadedFileNames);
        // Service์—์„œ DTO์— FileNames๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ƒํƒœ๋ณ€ํ™”์‹œํ‚ด

        rttr.addFlashAttribute("bno", boardRegisterDTO.getBno());
        // ๊ฒŒ์‹œ๊ธ€์ด ๋“ฑ๋ก๋œ ์ดํ›„ bno๊ฐ€ ์ƒ์„ฑ๋˜๋Š”๋ฐ, ํ•ด๋‹น bno๋ฅผ DTO์˜ ์— ์ฃผ์ž…์‹œ์ผœ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๊ณ , addFlashAttribute์— ์ €์žฅ๋œ๋‹ค.

        return "redirect:/board/list";
    }

    @GetMapping("/list")
    public void list(Model model){

    }

}

๐Ÿ‘‰ ์šฐ์„ , PostMapping์€ ๊ฒŒ์‹œ๊ธ€์„ ๋“ฑ๋กํ•œ ์ดํ›„์— ๋ฐœ์ƒ์ด ๋˜๋Š”๋ฐ ์ฒจ๋ถ€ํŒŒ์ผ์„ ๋„ฃ์–ด ๊ฒŒ์‹œ๊ธ€์— ๋“ฑ๋กํ•˜๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น DTO์— ๊ฒฐํ•ฉ๋œ Imges๋ฅผ uploadUtil์˜ upload๋ฉ”์†Œ๋“œ์— ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋“ค์–ด๊ฐ€์„œ, List<.String>๋ฐ์ดํ„ฐํƒ€์ž…์ธ uploadedFileNames๋ณ€์ˆ˜์— ๋‹ด๊ธฐ๊ฒŒ๋œ๋‹ค. ์ด ๊ฐ’์€ UUID๊ฐ€ ํฌํ•จ๋˜์–ด ๋งŒ๋“ค์–ด์ง„ ์ƒˆ๋กœ์šด FileName์ด๊ณ , ์ด FileName๋“ค์ด DTO์— ์žˆ๋Š” setFileNames์— ๋„ฃ์–ด์ ธ DTO์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ™”๋œ๋‹ค. ์ด ๋ณ€ํ™”๋Š” ํ˜„์žฌ DTO์˜ FileNames๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด ๋‚˜์ค‘์— Service์—์„œ ์‚ฌ์šฉ์ด ๋œ๋‹ค.

๐Ÿ‘‰ Serivce์—์„œ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์–ด, ๊ฒŒ์‹œ๊ธ€์ด ๋“ฑ๋ก์ด ๋œ ์ดํ›„์— bno๊ฐ€ ์ƒ์„ฑ์ด ๋˜๊ณ  ํ•ด๋‹น bno๋ฅผ ์ด์šฉํ•˜์—ฌ addFlashAttribute๋ฅผ ํ†ตํ•ด ์ผํšŒ์„ฑ์œผ๋กœ ์ €์žฅ์ด ๋˜์–ด modal์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.




2. list์—์„œ type๊ฐ’์˜ ์ „๋‹ฌ๊ณผ์ •

2-1. list.html

<form id="actionForm" action="/board/list" method="get" >
            <select name="type"> <!--์•„๋ž˜์—์„œ ์„ ํƒ๋œ ํƒ€์ž…์ด ํ•ด๋‹น select Type์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด xmlํŒŒ์ผ์˜ type๊ฐ’๊ณผ ์ด์–ด์ง„๋‹ค -->
                <option value="">---</option>
                <option value="T" th:selected="${pageRequest.type == 'T'}">์ œ๋ชฉ</option>
                <option value="C" th:selected="${pageRequest.type == 'C'}">๋‚ด์šฉ</option>
                <option value="W" th:selected="${pageRequest.type == 'W'}">์ž‘์„ฑ์ž</option>
                <option value="TC" th:selected="${pageRequest.type == 'TC'}">์ œ๋ชฉ / ๋‚ด์šฉ</option>
                <option value="TW" th:selected="${pageRequest.type == 'TW'}">์ œ๋ชฉ / ์ž‘์„ฑ์ž</option>
                <option value="TCW" th:selected="${pageRequest.type == 'TCW'}">์ œ๋ชฉ / ๋‚ด์šฉ / ์ž‘์„ฑ์ž</option>
            </select>
            <input type="text" name="keyword" th:value="${pageRequest.keyword}">
            <input type="hidden" name="page" value="1"> <!--๊ฒ€์ƒ‰์กฐ๊ฑด์„ ๋ˆ„๋ฅด๋ฉด ๋ฌด์กฐ๊ฑด 1ํŽ˜์ด์ง€ ์ด๋ฏ€๋กœ-->

                <button class="btn btn-secondary searchBtn">Search</button>
                <button class="btn btn-primary clearBtn">Clear</button>



            </form>

๐Ÿ‘‰ Option์—์„œ ์„ ํƒ๋œ value๊ฐ’์œผ๋กœ์ธํ•ด name="type"์ด ๋ณ€๊ฒฝ๋˜์–ด type="T" ์ƒํƒœ๋กœ action์ธ /board/list์˜ ๊ฒฝ๋กœ๋กœ ์ „๋‹ฌ์ด ๋œ๋‹ค.




2-2. Controller

package org.zerock.b2.board.controller;

@Controller
@RequestMapping("/board")
@Log4j2
@RequiredArgsConstructor
public class BoardController {

    private final UploadUtil uploadUtil;

    private final BoardService boardService;

    @GetMapping("/register")
    public void register(){

    }

    @PostMapping("/register")
    public String register(BoardRegisterDTO boardRegisterDTO, RedirectAttributes rttr){

        log.info("Register board: " + boardRegisterDTO);

        List<String> uploadedFileNames = uploadUtil.upload(boardRegisterDTO.getImages());

        boardRegisterDTO.setFileNames(uploadedFileNames);

        boardService.register(boardRegisterDTO);

        rttr.addFlashAttribute("bno", boardRegisterDTO.getBno());
        // ๋ช‡๋ฒˆ๊ฒŒ์‹œ๋ฌผ์ด ๋“ฑ๋ก/์‚ญ์ œ๋˜์—ˆ๋‹ค๋Š” ๋ชจ๋‹ฌ์„ ์œ„ํ•ด

        return "redirect:/board/list";
    }


    @GetMapping("/list")
    public void list(PageRequest pageRequest, Model model){

        model.addAttribute("result", boardService.list(pageRequest));

    }

}

๐Ÿ‘‰ ํผ๋ฐ์ดํ„ฐ๋กœ ์ „๋‹ฌ๋ฐ›์€ type=T๊ฐ’์ด ์ฟผ๋ฆฌ์ŠคํŠธ๋ง์˜ ํ˜•ํƒœ๋กœ action์˜ controller๋กœ ์ „๋‹ฌ๋˜๊ณ , "/list"์—์„œ PageRequest๋ฅผ ํ†ตํ•ด boardService.list์— type=T๊ฐ’์„ ์ „๋‹ฌํ•œ๋‹ค.



2-3. Service

package org.zerock.b2.board.service;

@Service
@Log4j2
@Transactional
@RequiredArgsConstructor
public class BoardService {

    private final BoardMapper boardMapper;

    public void register(BoardRegisterDTO boardRegisterDTO) {

        boardMapper.insert(boardRegisterDTO);

        List<String> fileNames = boardRegisterDTO.getFileNames();

        for (int i = 0; i < fileNames.size(); i++) {
            boardMapper.insertAttach(boardRegisterDTO.getBno(), fileNames.get(i), i);
        }

    }

    @Transactional(readOnly = true)
    public PageResponse<BoardListDTO> list(PageRequest pageRequest) {

        List<BoardListDTO> dtoList = boardMapper.listImage(pageRequest);

        int total = boardMapper.count(pageRequest);

        return PageResponse.<BoardListDTO>with()
                .list(dtoList)
                .total(total)
                .pageRequest(pageRequest)
                .build();
    }

}

๐Ÿ‘‰ service์˜ list์—์„œ PageRequest๋กœ ๋ฐ›์€ ๊ฐ’์„ Mapper.listImage๋กœ ์ „๋‹ฌํ•˜๋Š”๋ฐ,



2-4. xml

 <sql id="search">
        <foreach item="type" collection="arr" open="AND (" close=")" separator="OR">
            <if test='type.equals("T")'>
                title like concat('%', #{keyword}, '%')
            </if>
            <if test='type.equals("C")'>
                content like concat('%', #{keyword}, '%')
            </if>
            <if test='type.equals("W")'>
                writer like concat('%', #{keyword}, '%')
            </if>
        </foreach>
    </sql>


    <select id="listImage" resultType="BoardListDTO">
        select
        board.bno, title, writer, regDate, modDate,
        replyCnt, fileName
        from
        tbl_board board left join tbl_board_attach attach on attach.bno = board.bno
        where (attach.ord = 0 or attach.ord is null)

        <include refid="search"></include>

        order by board.bno desc
        limit #{skip}, #{size}
    </select>

๐Ÿ‘‰ xml์—์„œ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์€ PageRequest์ธ

private int page = 1;
	
	private int size = 10;

	private String type;
	private String keyword;

์ด๋Ÿฌํ•œ ์ •๋ณด๋“ค์„ ์‚ฌ์šฉํ•˜๊ฒŒ๋œ๋‹ค. ๊ทธ ์ดํ›„ list.html์˜
th:selected="${pageRequest.type == 'T'}" ๊ฐ’์„ ๋งŒ๋‚˜๊ฒŒ ๋˜๋Š”๊ฒƒ์ด๋‹ค.



3. th:block

<div class="float-end">
                <ul class="pagination flex-wrap">

                    <li class="page-item"><a class="page-link" href="#">PREV</a></li>

                    <th:block th:each="i : ${#numbers.sequence(result.startPage,result.endPage)}"> <!--th:block์„ ์‚ฌ์šฉํ•˜์—ฌ liํƒœ๊ทธ์˜ ๋ฐ˜๋ณต์— ๋Œ€ํ•ด ์‰ฝ๊ฒŒ ํ‘œํ˜„๊ฐ€๋Šฅ / startPage๋ถ€ํ„ฐ endPage๊นŒ์ง€์˜ ์ˆซ์ž์ƒ์„ฑ -->
                        <li class="page-item" th:if="${i > 0}"><a class="page-link" th:href="${i}">[[${i}]]</a></li>
                    </th:block>

                    <li class="page-item"><a class="page-link" href="#">NEXT</a></li>
                </ul>
            </div>

๐Ÿ‘‰ th:block์„ ์ด์šฉํ•˜๊ฒŒ ๋˜๋ฉด liํƒœ๊ทธ์˜ ๋ฐ˜๋ณต์„ ๋ณด๊ธฐ์ข‹๊ฒŒ ๋งŒ๋“ค์ˆ˜์žˆ๋‹ค.

๐Ÿ‘‰ ํ•ด๋‹น ์ฝ”๋“œ๋Š” th:each๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, result.startPage๋ถ€ํ„ฐ endPage๊นŒ์ง€์˜ ๊ฐ’์„ ์ˆซ์ž๋กœ ํ‘œํ˜„ํ•˜๋Š”๊ฒƒ.

0๊ฐœ์˜ ๋Œ“๊ธ€