organize/스프링

스프링 웹 프로젝트 14

001cloudid 2025. 1. 13. 17:27
728x90

※ 외부 라이브러리는 footer에 작성하는 이유? 성능과 로딩 최적화 때문

  1. 페이지 로딩 우선순위
    head에 스크립트를 넣으면 페이지 로딩이 완료되기 전에 자바스크립트가 먼저 로드되고 실행될 수 있음. 이는 스크립트가 다른 DOM 요소의 렌더링을 차단할 수 있기 때문에 페이지 로딩 속도를 늦출 수 있음. footer에 스크립트를 넣으면 HTML 문서의 주요 콘텐츠가 먼저 로드되고 표시된 후, 그 다음에 자바스크립트가 로드되기 때문에 사용자에게 빠른 콘텐츠 표시를 제공할 수 있음
  2. 비동기적 로딩
    footer에 스크립트를 추가하면서 async나 defer 속성을 사용하면, 스크립트가 비동기적으로 로드되거나 DOM이 완전히 로드된 후 실행될 수 있음. 이로 인해 페이지 로딩 시간이 개선
  3. 최소한의 차단적 렌더링

페이지 번호 이벤트 처리

  • 페이지 번호의 링크는 페이지 번호만 가지도록 하고 별도의 form 태그와 이벤트 처리를 통해서 이동
  • 검색 조건이 많이 붙을 수 있는데, 관련된 모든 링크를 다 수정해줘야하기 때문에 form태그를 사용
    단점 → 자바스크립트가 정상하지 않으면 동작하지 않음
                            <form action="actionForm" action="/board/list" method="get">
                            	<input type="hidden" name="pageNum" value="${page.criteria.pageNum}">
                            	<input type="hidden" name="amount" value="${page.criteria.amount}">
                            </form>

list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@include file="../include/header.jsp" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">Tables</h1>
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            DataTables Advanced Tables
                            <button id="regBtn" type="button" class="btn btn-xs pull-right">Register New Board</button>
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                            <table width="100%" class="table table-striped table-bordered table-hover">
                                <thead>
                                    <tr>
                                        <th>#번호</th>
                                        <th>제목</th>
                                        <th>작성자</th>
                                        <th>작성일</th>
                                        <th>수정일</th>
                                    </tr>
                                </thead>
                                <tbody>
                                <c:forEach items="${list}" var="boardVO">
                                    <tr class="odd gradeX">
                                        <td><c:out value="${boardVO.bno}" /></td>
                                        <td><a href="/board/get?bno=<c:out value='${boardVO.bno}' />"><c:out value="${boardVO.title}" /></a></td>
                                        <td><c:out value="${boardVO.writer}" /></td>
                                        <td><fmt:formatDate value="${boardVO.regdate }" pattern="yyyy-MM-dd"/> </td>
                                        <td><fmt:formatDate value="${boardVO.updateDate }" pattern="yyyy-MM-dd" /></td>
                                    </tr>
                                </c:forEach>
                                </tbody>
                            </table>
                            <!-- /.table-responsive -->
                            
                            <h4>${page}</h4>
                            <div class="pull-right">
                            	<ul class="pagination">
                            		<c:if test="${page.prev}"> 
								    	<li class="page-item"><a class="page-link" href="${page.startPage - 1}" tabindex="-1">Previous</a></li>
									</c:if>
									<c:forEach begin="${page.startPage}" end="${page.endPage}" var="num">
										<li class="page-item ${page.criteria.pageNum == num? 'active' :''}"><a class="page-link" href="${num}">${num}</a></li>
									</c:forEach>                
									<c:if test="${page.next}">            	
								    	<li class="page-item"><a class="page-link" href="${page.endPage + 1}">Next</a></li>
                            		</c:if>
                            	</ul>
                            </div>
                            <form id="actionForm" action="/board/list" method="get">
                            	<input type="hidden" name="pageNum" value="${page.criteria.pageNum}">
                            	<input type="hidden" name="amount" value="${page.criteria.amount}">
                            </form>
                            
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-12 -->
            </div>

<div id="myModal" class="modal" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <p></p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-primary" data-dismiss="modal">Save changes</button>
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

<script>
$(document).ready(function(){
	var result = '<c:out value="${result}"/>';
	
	
	checkModal(result);
	
	history.replaceState({},null,null); // 히스토리 클리어
	
	function checkModal(result){
		
		if(result ==='' || history.state){
			return;
		}
		
		if(result === 'success'){
			$('.modal-body').html("정상적으로 처리됨.");
		} else if(parseInt(result)>0){
			$('.modal-body').html("게시글 " + parseInt(result) + " 번이 등록됨.");
		}
		
		$("#myModal").modal("show");
	}
	
	$("#regBtn").click(function(){
		self.location = "/board/register";
	});
	
	var actionForm = $("#actionForm");
	
	$(".page-link").on("click", function(e){
		e.preventDefault(); // a태그는 기능은 이동 → 이동이 되지 않음(기본 동작 제어)
		
		console.log('click');
		
		//form 태그의 내용 변경 후 submit
		actionForm.find("input[name='pageNum']").val($(this).attr("href"));
		actionForm.submit();
		
	});
	
	
	
});
</script>

<%@include file="../include/footer.jsp" %>

 

3페이지에서  1376376의 글을 조회 → List 버튼을 누르면 list의 1페이지로 넘어감

list.jsp

 <c:forEach items="${list}" var="boardVO">
                                    <tr class="odd gradeX">
                                        <td><c:out value="${boardVO.bno}" /></td>
                                        <td><a href="/board/get?bno=<c:out value='${boardVO.bno}' />"><c:out value="${boardVO.title}" /></a></td>
                                        <td><c:out value="${boardVO.writer}" /></td>
                                        <td><fmt:formatDate value="${boardVO.regdate }" pattern="yyyy-MM-dd"/> </td>
                                        <td><fmt:formatDate value="${boardVO.updateDate }" pattern="yyyy-MM-dd" /></td>
                                    </tr>
                                </c:forEach>

                                <c:forEach items="${list}" var="boardVO">
                                    <tr class="odd gradeX">
                                        <td><c:out value="${boardVO.bno}" /></td>
                                        <td><a href="<c:out value='${boardVO.bno}' />"><c:out value="${boardVO.title}" /></a></td>
                                        <td><c:out value="${boardVO.writer}" /></td>
                                        <td><fmt:formatDate value="${boardVO.regdate }" pattern="yyyy-MM-dd"/> </td>
                                        <td><fmt:formatDate value="${boardVO.updateDate }" pattern="yyyy-MM-dd" /></td>
                                    </tr>
                                </c:forEach>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@include file="../include/header.jsp" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">Tables</h1>
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            DataTables Advanced Tables
                            <button id="regBtn" type="button" class="btn btn-xs pull-right">Register New Board</button>
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                            <table width="100%" class="table table-striped table-bordered table-hover">
                                <thead>
                                    <tr>
                                        <th>#번호</th>
                                        <th>제목</th>
                                        <th>작성자</th>
                                        <th>작성일</th>
                                        <th>수정일</th>
                                    </tr>
                                </thead>
                                <tbody>
                                <c:forEach items="${list}" var="boardVO">
                                    <tr class="odd gradeX">
                                        <td><c:out value="${boardVO.bno}" /></td>
                                        <td><a class="move" href="<c:out value='${boardVO.bno}' />"><c:out value="${boardVO.title}" /></a></td>
                                        <td><c:out value="${boardVO.writer}" /></td>
                                        <td><fmt:formatDate value="${boardVO.regdate }" pattern="yyyy-MM-dd"/> </td>
                                        <td><fmt:formatDate value="${boardVO.updateDate }" pattern="yyyy-MM-dd" /></td>
                                    </tr>
                                </c:forEach>
                                </tbody>
                            </table>
                            <!-- /.table-responsive -->
                            
                            <h4>${page}</h4>
                            <div class="pull-right">
                            	<ul class="pagination">
                            		<c:if test="${page.prev}"> 
								    	<li class="page-item"><a class="page-link" href="${page.startPage - 1}" tabindex="-1">Previous</a></li>
									</c:if>
									<c:forEach begin="${page.startPage}" end="${page.endPage}" var="num">
										<li class="page-item ${page.criteria.pageNum == num? 'active' :''}"><a class="page-link" href="${num}">${num}</a></li>
									</c:forEach>                
									<c:if test="${page.next}">            	
								    	<li class="page-item"><a class="page-link" href="${page.endPage + 1}">Next</a></li>
                            		</c:if>
                            	</ul>
                            </div>
                            <form id="actionForm" action="/board/list" method="get">
                            	<input type="hidden" name="pageNum" value="${page.criteria.pageNum}">
                            	<input type="hidden" name="amount" value="${page.criteria.amount}">
                            </form>
                            
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-12 -->
            </div>

<div id="myModal" class="modal" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <p></p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-primary" data-dismiss="modal">Save changes</button>
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

<script>
$(document).ready(function(){
	var result = '<c:out value="${result}"/>';
	
	
	checkModal(result);
	
	history.replaceState({},null,null); // 히스토리 클리어
	
	function checkModal(result){
		
		if(result ==='' || history.state){
			return;
		}
		
		if(result === 'success'){
			$('.modal-body').html("정상적으로 처리됨.");
		} else if(parseInt(result)>0){
			$('.modal-body').html("게시글 " + parseInt(result) + " 번이 등록됨.");
		}
		
		$("#myModal").modal("show");
	}
	
	$("#regBtn").click(function(){
		self.location = "/board/register";
	});
	
	var actionForm = $("#actionForm");
	
	$(".page-link").on("click", function(e){
		e.preventDefault(); // a태그는 기능은 이동 → 이동이 되지 않음(기본 동작 제어)
		
		console.log('click');
		
		//form 태그의 내용 변경 후 submit
		actionForm.find("input[name='pageNum']").val($(this).attr("href"));
		actionForm.submit();
		
	});
	
	$(".move").on("click", function(e){
		e.preventDefault();
		
		console.log($(this).attr("href"));
		
		actionForm.append("<input type='hidden' name='bno' value='"+$(this).attr("href")+"'>");
		actionForm.attr("action","/board/get").submit();
		
	})
	
});
</script>

<%@include file="../include/footer.jsp" %>

주소줄에 bno도 추가됨 추가적으로 수정 삭제 조회에도 이런 작업이 필요함

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.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.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j;

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

	private final BoardService boardService;
	
(...생략...)

	@GetMapping({"/get", "/modify"})
	public void get(@RequestParam("bno") Long bno,Model model, Criteria criteria) {
		model.addAttribute("boardVO", boardService.get(bno));
	}
	
}

get.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@include file="../include/header.jsp" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">Board Read</h1>
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            Board Read
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
								<div class="form-group">
									<label>BNO</label> <input name="title" class="form-control" readonly="readonly" value="<c:out value='${boardVO.bno}'/>">
								</div>
								<div class="form-group">
									<label>Title</label> <input name="title" class="form-control" readonly="readonly" value="<c:out value='${boardVO.title}'/>">
								</div>
								<div class="form-group">
									<label>Content</label> <textarea rows="5" cols="50" class="form-control" name="content"><c:out value='${boardVO.content}'/></textarea>
								</div>
								<div class="form-group">
									<label>Writer</label> <input name="writer" class="form-control" value="<c:out value='${boardVO.writer}'/>">
								</div>
	                            <form id="actionForm" action="/board/list" method="get">
	                            	<input type="hidden" name="pageNum" value="${criteria.pageNum}">
	                            	<input type="hidden" name="amount" value="${criteria.amount}">
	                            	<input type="hidden" name="bno" value="${boardVO.bno}">
                            	</form>
							 	<button type="button" class="btn btn-default listBtn"><a href="/board/list">List</a></button>
                                <button type="button" class="btn btn-default modiBtn"><a href="/board/modify?bno=<c:out value='${boardVO.bno }'/>">Modify</a></button>
								<script>
									
								var actionForm = $("#actionForm");
								
								$('.listBtn').click(function(e){
									e.preventDefault();
									actionForm.find("input[name='bno']").remove();
									actionForm.submit();
								});
								
								$('.modiBtn').click(function(e){
									e.preventDefault();
									actionForm.attr("action","/board/modify");
									actionForm.submit();
								});
								
								</script>

                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-12 -->
            </div>
<%@include file="../include/footer.jsp" %>

 

수정

BoardController

	@PostMapping("/modify")
	public String modify(BoardVO boardVO, RedirectAttributes redirectAttributes, Criteria criteria) {
		log.info("BoardController modify()......................");
		
		int count = boardService.modify(boardVO);
		
		if(count == 1) {
			redirectAttributes.addFlashAttribute("result", "success");
		}
		
		redirectAttributes.addAttribute("pageNum",criteria.getPageNum());
		redirectAttributes.addAttribute("amount",criteria.getAmount());
		
		return "redirect:/board/list";
	}

modify.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@include file="../include/header.jsp" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">Board Modify/Delete</h1>
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            Board Modify/Delete
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                        <form>
                        	<input type="hidden" name="pageNum" value="${criteria.pageNum}">
                        	<input type="hidden" name="amount" value="${criteria.amount}">
								<div class="form-group">
									<label>BNO</label> <input name="bno" class="form-control" readonly="readonly" value="<c:out value='${boardVO.bno}'/>">
								</div>
								<div class="form-group">
									<label>Title</label> <input name="title" class="form-control" value="<c:out value='${boardVO.title}'/>">
								</div>
								<div class="form-group">
									<label>Content</label> <textarea rows="5" cols="50" class="form-control" name="content"><c:out value='${boardVO.content}'/></textarea>
								</div>
								<div class="form-group">
									<label>Writer</label> <input name="writer" class="form-control" value="<c:out value='${boardVO.writer}'/>">
								</div>
							 	<button class="btn btn-default" data-oper='modify'>Modify</button>
                                <button class="btn btn-danger" data-oper='remove'>Remove</button>
                                <button class="btn btn-info" data-oper='list'>List</button>
                        </form>
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-12 -->
            </div>
<script>
	$(document).ready(function(){
		
		var formObj = $('form');
		
		$('.btn').click(function(e){
			
			e.preventDefault();
			
			var operation = $(this).data("oper");
			
			console.log(operation);
			
			if(operation === 'list'){
				self.location = "/board/list";
			}else if(operation === 'remove'){
				formObj.attr("action", "/board/remove").attr("method","post");
				formObj.submit();
			}else if(operation === 'modify'){
				formObj.attr("action", "/board/modify").attr("method","post");
				formObj.submit();
			}
		})
		
		
	})
</script>

<%@include file="../include/footer.jsp" %>

 

삭제 → 삭제는 따로 할 필요는 없으나 이런 방법이 있다는 것을 알아두면 좋음

BoardController

	@PostMapping("/remove")
	public String remove(@RequestParam("bno") Long bno, RedirectAttributes redirectAttributes, Criteria criteria) {
		log.info("BoardController remove()......................");
		
		int count = boardService.remove(bno);
		
		if(count == 1) {
			redirectAttributes.addFlashAttribute("result", "success");
		}
		
		redirectAttributes.addAttribute("pageNum",criteria.getPageNum());
		redirectAttributes.addAttribute("amount",criteria.getAmount());
		
		return "redirect:/board/list";
	}

 

total

BoardMapper

	int getTotalCount(Criteria criteria); // 검색 조건을 Criteria로 넣기 위해서 파라미터로 Criteria를 넣어줌

BoardMapper.XML

	<select id="getTotalCount" resultType="int">
		select count(bno) from tbl_board 
	</select>

BoardService

	public int getTotal(Criteria criteria);

BoardServiceImpl

	@Override
	public int getTotal(Criteria criteria) {
		return boardMapper.getTotalCount(criteria);
	}

BoardController

	@GetMapping("/list")
	public void list(Model model, Criteria criteria) { 
		log.info("BoardController list()................");
		log.info("criteria : " + criteria);
		model.addAttribute("list", boardService.getList(criteria));
		model.addAttribute("page", new PageDTO(criteria, boardService.getTotal(criteria)));
	}

 

검색의 처리

  • 제목, 내용, 작성자와 같은 단일 항목
  • 제목 + 내용, 제목 + 작성자와 같은 복합 항목
  • 검색 항목에 따라서 매번 다른 SQL이 처리될 필요가 있는 상황
    → MyBatis의 동적 쿼리 기능을 이용해서 처리
    https://mybatis.org/mybatis-3/dynamic-sql.html

Mybatis 동적 태그

  • if
    test라는 속성과 함께 특정한 조건이 true가 되었을 때 포함된 SQL을 사용하고자 할 때 작성
  • choose(when, otherwise)
    if와 달리 여러 상황들 중 하나의 상황에서만 동작
  • trim(where, set)
    단독으로 사용되지 않고, if, choose와 같은 태그들을 내포하고 있어 SQL들을 연결해주고, 앞 뒤에 필요한 구문들(and, or, where 등)을 추가하거나 생략하는 역할
  • foreach
    List, Array, Map 등을 이용해서 루프를 처리

BoardMapper

package org.zerock.mapper;

import java.util.List;
import java.util.Map;

import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;

public interface BoardMapper {

(...생략...)

	List<BoardVO> searchTest(Map<String, Map<String, String>> map);
}

BoardMapper.xml

	<select id="getTotalCount" resultType="int">
		select count(bno) from tbl_board 
	</select>
	
	<select id="searchTest" resultType="org.zerock.domain.BoardVO">
		<![CDATA[
		select * from tbl_board
		where
		]]>
		<foreach collection="map" index="key" item="value">
			#{key} #{value}
		</foreach>
		<![CDATA[
			rownum < 10
		]]>
	</select>

Key만 출력

package org.zerock.mapper;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;
import org.zerock.domain.PageDTO;

import lombok.extern.log4j.Log4j;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class BoardMapperTests {

(...생략...)

	@Test
	public void testSearch() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("T", "TTT");
		map.put("C", "CCC");
		
		Map<String, Map<String, String>> outer = new HashMap<String, Map<String,String>>();
		outer.put("map", map);
		
		List<BoardVO> list = boardMapper.searchTest(outer);
		
		log.info("list.................. : " + list);
	}
	
}

BoardMapper.xml

	<select id="searchTest" resultType="org.zerock.domain.BoardVO">
		<![CDATA[
		select * from tbl_board
		where
		]]>
		<foreach collection="map" index="key" item="value">
			<if test="key == 'T'.toString()">
				title like #{value}
			</if>
		</foreach>
		<![CDATA[
			rownum < 10
		]]>
	</select>

	<select id="searchTest" resultType="org.zerock.domain.BoardVO">
		<![CDATA[
		select * from tbl_board
		where
		]]>
		<trim suffix="and">
		<foreach collection="map" index="key" item="value">
			<if test="key == 'T'.toString()">
				title like #{value}
			</if>
		</foreach>
		</trim>
		<![CDATA[
			rownum < 10
		]]>
	</select>

 

	<select id="searchTest" resultType="org.zerock.domain.BoardVO">
		<![CDATA[
		select * from tbl_board
		where
		]]>
		<trim suffix="and">
		<foreach collection="map" index="key" item="value">
			<if test="key == 'T'.toString()">
				title like #{value}
			</if>
			<if test="key == 'C'.toString()">
				content like #{value}
			</if>
			<if test="key == 'W'.toString()">
				writer like #{value}
			</if>
		</foreach>
		</trim>
		<![CDATA[
			rownum < 10
		]]>
	</select>
	@Test
	public void testSearch() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("T", "TTT");
		map.put("C", "CCC");
		map.put("W", "WWW");
		
		Map<String, Map<String, String>> outer = new HashMap<String, Map<String,String>>();
		outer.put("map", map);
		
		List<BoardVO> list = boardMapper.searchTest(outer);
		
		log.info("list.................. : " + list);
	}

	<select id="searchTest" resultType="org.zerock.domain.BoardVO">
		<![CDATA[
		select * from tbl_board
		where
		]]>
		<trim suffix="and">
		<foreach collection="map" index="key" item="value" separator="OR">
			<if test="key == 'T'.toString()">
				title like #{value}
			</if>
			<if test="key == 'C'.toString()">
				content like #{value}
			</if>
			<if test="key == 'W'.toString()">
				writer like #{value}
			</if>
		</foreach>
		</trim>
		<![CDATA[
			rownum < 10
		]]>
	</select>

select * from tbl_board where content like 'CCC' OR title like 'TTT' OR writer like 'WWW'

우선순위 때문에 or 조건은 괄호로 묶어줘야함

	<select id="searchTest" resultType="org.zerock.domain.BoardVO">
		<![CDATA[
		select * from tbl_board
		where
		]]>
		<trim suffix="and">
		<foreach collection="map" index="key" item="value" separator="OR" open="(" close=")">
			<if test="key == 'T'.toString()">
				title like #{value}
			</if>
			<if test="key == 'C'.toString()">
				content like #{value}
			</if>
			<if test="key == 'W'.toString()">
				writer like #{value}
			</if>
		</foreach>
		</trim>
		<![CDATA[
			rownum < 10
		]]>
	</select>

검색 조건이 없을 때

	@Test
	public void testSearch() {
		Map<String, String> map = new HashMap<String, String>();
		
		Map<String, Map<String, String>> outer = new HashMap<String, Map<String,String>>();
		outer.put("map", map);
		
		List<BoardVO> list = boardMapper.searchTest(outer);
		
		log.info("list.................. : " + list);
	}

select * from tbl_board where rownum < 10

 

동적 SQL → 확인 할 수 있는 것이 중요

728x90

'organize > 스프링' 카테고리의 다른 글

스프링 웹 프로젝트 15  (0) 2025.01.14
스프링 웹 프로젝트 13  (0) 2025.01.12
스프링 웹 프로젝트 12  (0) 2025.01.11
스프링 웹 프로젝트 11  (0) 2025.01.09
스프링 웹 프로젝트 10  (0) 2025.01.08