20211212 게시판

DUUUPPAAN·2021년 12월 12일
0

Spring_Framework

목록 보기
5/19

·jsp에서 진행한 게시판

-기존에는 jsp에서 진행한 게시판을 다시 스프링에서 진행하려고 한다. 문제는 그때는 댓글과 첨부파일에 대한 부분을 진행하지 않고 넘어갔는데, (너무 복잡할 것 같아서) 이제는 해당 부분도 배우고 넘어가야 할 시점이었다. 우선 전에 게시판 관련 새로운 테이블을 만들었기 때문에 게시판의 정보를 불러와서 뿌려주는 SELECT문과 총 수에 대한 SELECT문을 두개 작성했다.

--페이징 처리를 위한 쿼리
--전체 게시글 수를 카운트 하고 알리아스는 CNT로 줌.
--COUNT(*)를 하지 않는 이유는, PK로 COUNT를 세는 것이 인덱스만 타서 훨씬 더 부하가 적어짐.
SELECT
    COUNT(A.HIBBS_SEQ) AS CNT
FROM
    TBL_HIBOARD A, TBL_USER B
WHERE 
    A.USER_ID = B.USER_ID
AND
    B.USER_NAME LIKE '%test%'
AND 
    A.HIBBS_TITLE LIKE '%test%'
AND 
    DBMS_LOB.INSTR(A.HIBBS_CONTENT, 'test') > 0
;

-사실 이 쿼리는 굳이 없어도 상관은 없는데, 검색 결과가 없을경우가 있을 수 있기 때문에 굳이 테이블 풀스캔을 하지 않고, 우선 결과가 있는지 없는지부터 찾은 후에 테이블 풀 스캔을 하겠다는 용도이다.

SELECT 
    HIBBS_SEQ,
    USER_ID,
    USER_NAME,
    USER_EMAIL,
    HIBBS_GROUP,
    HIBBS_ORDER,
    HIBBS_INDENT,
    HIBBS_TITLE,
    HIBBS_CONTENT,
    HIBBS_READ_CNT,
    REG_DATE
  FROM (SELECT 
            ROWNUM AS RNUM,
            HIBBS_SEQ,
            USER_ID,
            USER_NAME,
            USER_EMAIL,
            HIBBS_GROUP,
            HIBBS_ORDER,
            HIBBS_INDENT,
            HIBBS_TITLE,
            HIBBS_CONTENT,
            HIBBS_READ_CNT,
            REG_DATE
          FROM (SELECT
                    A.HIBBS_SEQ AS HIBBS_SEQ,
                    A.USER_ID AS USER_ID,
                    NVL(B.USER_NAME, '') AS USER_NAME,
                    NVL(B.USER_EMAIL, '') AS USER_EMAIL,
                    NVL(A.HIBBS_GROUP, 0) AS HIBBS_GROUP,
                    NVL(A.HIBBS_ORDER, 0) AS HIBBS_ORDER,
                    NVL(A.HIBBS_INDENT, 0) AS HIBBS_INDENT,
                    NVL(A.HIBBS_TITLE, '') AS HIBBS_TITLE,
                    NVL(A.HIBBS_CONTENT, '') AS HIBBS_CONTENT,
                    NVL(A.HIBBS_READ_CNT, 0) AS HIBBS_READ_CNT,
                    NVL(TO_CHAR(A.REG_DATE, 'YYYY.MM.DD HH24:MI:SS'), '') AS REG_DATE
                FROM
                    TBL_HIBOARD A, TBL_USER B
                WHERE 
                    A.USER_ID = B.USER_ID
                AND
                    B.USER_NAME LIKE '%test%'
                AND 
                    A.HIBBS_TITLE LIKE '%test%'
                AND 
                    DBMS_LOB.INSTR(A.HIBBS_CONTENT, 'test') > 0
                ORDER BY A.HIBBS_GROUP DESC, A.HIBBS_ORDER ASC))
WHERE 
    RNUM >= 1
AND 
    RNUM <=5
;

--원래는 유저 아이디 상태가 Y인 사람만 가져오는 게 맞는데, 문제가 생기는 부분이 있음 그래서 이 부분은 java에서 걸러주기.
--메인글이 10번일 때, 그룹 10, 오더 0 인덴트 0
--댓글1은 10 1 1, 댓글2는 10 1 1 이러면 댓글1이 ORDER가 2가 됨. 순서대로 댓글이 달려야 하기 때문에. 
--SORTING을 할 때 GROUP번호와 ORDER를 사용할 것.
--우선 그룹으로 DESC를 해서 그 다음 오더 번호에 따라서 ASC함 11번 1,2,3부터 그 다음 10 1,2,3 이런 순서로 나오게.
--오더바이가 앞에 DESC를 하고 나서 그 값을 기준으로 고정하고 다음 값인 오더값을 기준으로 다시 ASC하는 것, 처음부터 다시 ASC하는게 아님

-전에 게시판을 진행하면서 정말 이해하기 어려웠던 쿼리문도 작성했다. 크게 달라진 점은 없는데, 댓글이 생겨서 ORDER BY의 요소가 하나 추가되었다. 게시판 숫자를 기준으로 정렬하고 해당 게시판 숫자에서는 댓글 순으로 또 다시 정렬하게 해놨다.

·게시판의 테이블을 받을 .JAVA작성

-HiBoard.java 객체로 해당 테이블과 매칭되는 .java를 작성했다.

package com.icia.web.model;

import java.io.Serializable;

public class HiBoard implements Serializable 
{
	private static final long serialVersionUID = 1L;
	
	private long hiBbsSeq;		//게시물 번호
	private String userId;		//사용자 아이디
	private long hiBbsGroup;	//게시물 그룹번호
	private int hiBbsOrder; 	//게시물 그룹 내 순서
	private int hiBbsIndent;	//게시물 들여쓰기
	private String hiBbsTitle;	//게시물 제목
	private String hiBbsContent;//게시물 내용
	private int hiBbsReadCnt;	//게시물 조회수
	private String regDate; 	//등록일
	
	//유저 테이블의 이름과 이메일을 가져오기 위해서 값을 담을 변수가 필요함
	private String userName; 	//사용자 이름
	private String userEmail; 	//사용자 이메일
	
	//사용자가 검색한 값을 가져와야 하기 때문에
	private String searchType;	//검색 타입 - 1:이름,  2:제목,  3:내용
	private String searchValue; //검색 값 - 인풋박스에 검색한 값.
	
	//페이징을 위한 추가 변수가 필요하지만 지금은 여기까지만
	private long startRow;		//시작 ROWNUM
	private long endRow;		//끝 ROWNUM
	
	//생성자
	public HiBoard()
	{
		hiBbsSeq = 0;
		userId = "";
		hiBbsGroup = 0;
		hiBbsOrder = 0;
		hiBbsIndent = 0;
		hiBbsTitle = "";
		hiBbsContent = "";
		hiBbsReadCnt = 0;
		regDate = "";
		userName = "";
		userEmail = "";
		searchType = "";
		searchValue = "";
		startRow = 0;
		endRow = 0;
	}

	public long getHiBbsSeq() {
		return hiBbsSeq;
	}

	public void setHiBbsSeq(long hiBbsSeq) {
		this.hiBbsSeq = hiBbsSeq;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public long getHiBbsGroup() {
		return hiBbsGroup;
	}

	public void setHiBbsGroup(long hiBbsGroup) {
		this.hiBbsGroup = hiBbsGroup;
	}

	public int getHiBbsOrder() {
		return hiBbsOrder;
	}

	public void setHiBbsOrder(int hiBbsOrder) {
		this.hiBbsOrder = hiBbsOrder;
	}

	public int getHiBbsIndent() {
		return hiBbsIndent;
	}

	public void setHiBbsIndent(int hiBbsIndent) {
		this.hiBbsIndent = hiBbsIndent;
	}

	public String getHiBbsTitle() {
		return hiBbsTitle;
	}

	public void setHiBbsTitle(String hiBbsTitle) {
		this.hiBbsTitle = hiBbsTitle;
	}

	public String getHiBbsContent() {
		return hiBbsContent;
	}

	public void setHiBbsContent(String hiBbsContent) {
		this.hiBbsContent = hiBbsContent;
	}

	public int getHiBbsReadCnt() {
		return hiBbsReadCnt;
	}

	public void setHiBbsReadCnt(int hiBbsReadCnt) {
		this.hiBbsReadCnt = hiBbsReadCnt;
	}

	public String getRegDate() {
		return regDate;
	}

	public void setRegDate(String regDate) {
		this.regDate = regDate;
	}
	
	//유저 이름과 이메일에 대한 getter setter 정의 필요.
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserEmail() {
		return userEmail;
	}

	public void setUserEmail(String userEmail) {
		this.userEmail = userEmail;
	}

	public String getSearchType() {
		return searchType;
	}

	public void setSearchType(String searchType) {
		this.searchType = searchType;
	}

	public String getSearchValue() {
		return searchValue;
	}

	public void setSearchValue(String searchValue) {
		this.searchValue = searchValue;
	}

	public long getStartRow() {
		return startRow;
	}

	public void setStartRow(long startRow) {
		this.startRow = startRow;
	}

	public long getEndRow() {
		return endRow;
	}

	public void setEndRow(long endRow) {
		this.endRow = endRow;
	}
	
	
}

-주의할 점은, 테이블에서 받을 변수들 외에도 user테이블에서 가져올 유저 이름과 유저 이메일에 대한 변수, 또 검색한 searchType과 searchValue에 대한 값 그리고 페이징처리를 위한 startRow와 endRow를 추가해서 정의해줬다.

·DAO와 XML

-쿼리를 진행하려면 추상메소드가 정의되어 있는 DAO와 해당 메소드를 id로 갖고 있는 .xml을 작성해야 한다. 그래서 해당 템플릿이 WAS가 올라갈 때 정의되기 때문이다.

	//게시물 리스트
	//가져오는 게시물의 수가 하나가 아님, 게시판이기 때문에, 즉, 리스트 객체로 만들어야 함.
	public List<HiBoard> boardList(HiBoard hiBoard);
	
	//게시물 총 수
	public long boardListCount(HiBoard hiBoard);

-위는 HiBoardDao.java의 추상메소드를 정의한 부분이다. 당연히 게시물 총 수는 long타입으로 검색한 결과 수만 리턴해주면 된다. 다만 리스트는 하나의 HiBoard 객체가 아니라 한개 이상의 HiBoard 객체가 리턴되기 때문에 List객체를 통해서 값을 담아 리턴해야 한다.

<!-- 게시물에 대한 resultMap 시작 -->
<resultMap id="hiBoardResultMap" type="com.icia.web.model.HiBoard" >
   <id column="HIBBS_SEQ" property="hiBbsSeq" />
   <result column="USER_ID" property="userId" />
   <result column="HIBBS_GROUP" property="hiBbsGroup" />
   <result column="HIBBS_ORDER" property="hiBbsOrder" />
   <result column="HIBBS_INDENT" property="hiBbsIndent" />
   <result column="HIBBS_TITLE" property="hiBbsTitle" />
   <result column="HIBBS_CONTENT" property="hiBbsContent" />
   <result column="HIBBS_READ_CNT" property="hiBbsReadCnt" />
   <result column="REG_DATE" property="regDate" />
   
   <result column="USER_NAME" property="userName" />
   <result column="USER_EMAIL" property="userEmail" />
</resultMap>
<!-- 게시물에 대한 resultMap 종료-->

<!-- 게시물 리스트 시작 -->
<select id="boardList" parameterType="com.icia.web.model.HiBoard" resultMap="hiBoardResultMap">
SELECT
    HIBBS_SEQ,
    USER_ID,
    USER_NAME,
    USER_EMAIL,
    HIBBS_GROUP,
    HIBBS_ORDER,
    HIBBS_INDENT,
    HIBBS_TITLE,
    HIBBS_CONTENT,
    HIBBS_READ_CNT,
    REG_DATE
FROM (SELECT 
            ROWNUM AS RNUM,
            HIBBS_SEQ,
            USER_ID,
            USER_NAME,
            USER_EMAIL,
            HIBBS_GROUP,
            HIBBS_ORDER,
            HIBBS_INDENT,
            HIBBS_TITLE,
            HIBBS_CONTENT,
            HIBBS_READ_CNT,
            REG_DATE
        FROM (SELECT
                    A.HIBBS_SEQ AS HIBBS_SEQ,
                    A.USER_ID AS USER_ID,
                    NVL(B.USER_NAME, '') AS USER_NAME,
                    NVL(B.USER_EMAIL, '') AS USER_EMAIL,
                    NVL(A.HIBBS_GROUP, 0) AS HIBBS_GROUP,
                    NVL(A.HIBBS_ORDER, 0) AS HIBBS_ORDER,
                    NVL(A.HIBBS_INDENT, 0) AS HIBBS_INDENT,
                    NVL(A.HIBBS_TITLE, '') AS HIBBS_TITLE,
                    NVL(A.HIBBS_CONTENT, '') AS HIBBS_CONTENT,
                    NVL(A.HIBBS_READ_CNT, 0) AS HIBBS_READ_CNT,
                    NVL(TO_CHAR(A.REG_DATE, 'YYYY.MM.DD HH24:MI:SS'), '') AS REG_DATE
                FROM
                    TBL_HIBOARD A, TBL_USER B
                WHERE
                    A.USER_ID = B.USER_ID
<if test='searchType != null and searchType != "" and searchValue != null and searchValue != ""'>
   <choose>                
      <when test='searchType == "1"'> 
                AND
                    B.USER_NAME LIKE '%' || #{searchValue} || '%'
      </when>
      <when test='searchType == "2"'>                    
                AND
                    A.HIBBS_TITLE LIKE '%' || #{searchValue} || '%'
      </when>
      <when test='searchType == "3"'>                
                AND
                    DBMS_LOB.INSTR(A.HIBBS_CONTENT, #{searchValue}) > 0
      </when>
   </choose>                 
</if>                   
                ORDER BY A.HIBBS_GROUP DESC, A.HIBBS_ORDER ASC))
WHERE
    RNUM <![CDATA[>=]]> #{startRow}
AND
    RNUM <![CDATA[<=]]> #{endRow}
</select>
<!-- 게시물 리스트 끝 -->

<!-- 게시물 총 수 시작 public long boardListCount(HiBoard hiboard) { long cnt = 0;  return cnt; } -->
<select id="boardListCount" parameterType="com.icia.web.model.HiBoard" resultType="long">
   SELECT
       COUNT(A.HIBBS_SEQ) AS CNT
   FROM
       TBL_HIBOARD A, TBL_USER B
   WHERE
       A.USER_ID = B.USER_ID
<if test='searchType != null and searchType != "" and searchValue != null and searchValue != ""'>
   <choose>
      <when test='searchType == "1"'>
   AND
       B.USER_NAME LIKE '%' || #{searchValue} || '%'
       </when>
       <when test='searchType == "2"'>
   AND
       A.HIBBS_TITLE LIKE '%' || #{searchValue} ||'%'
       </when>
       <when test='searchType == "3"'>
   AND
       DBMS_LOB.INSTR(A.HIBBS_CONTENT, #{searchValue}) > 0
      </when>
   </choose>
</if>
</select>
<!-- 게시물 총 수 끝 -->

-select문이기 때문에 받는 resultMap이 필요하다. 아직 페이징에 대한 부분은 처리하지 않았기 때문에 해당 부분은 하드코딩해줄 것이라서 따로 맵핑해주지 않았다. 그 외에 주의할 점은 '%' || #{searchValue} || '%'쿼리문에서 사용하는 %는 ||연산자로 이어줘야 하고, 또 >=의 부분에 >는 태그의 열고 닫는 기능을 하기 때문에 비교연산자로 쓰인다는 것을 알려줘야 한다. <![CDATA[>=]]>이처럼 해당 부분을 비교연산자라고 알려준다. 또한 조건에 부합함에 따라 쿼리의 조건부가 바뀌어야 하기 때문에 where 다음에 <if>태그와 <choose>태그 그리고 <when>태그를 통해 상황에 맞게 쿼리문이 진행되도록 해준다.

service 정의하기

-dao를 사용할 서비스에 대한 부분을 정의해줘야 한다.

@Service("HiBoardService")
public class HiBoardService 
{
   private static Logger logger = LoggerFactory.getLogger(HiBoardService.class);
   
   //파일저장 디렉토리
   @Value("#{env['upload.save.dir']}")
   private String UPLOAD_SAVE_DIR;
   
   @Autowired
   private HiBoardDao hiBoardDao;
   
   //총 게시물 수
   public long boardListCount(HiBoard hiBoard)
   {
      long count = 0;
      
      try
      {
         count = hiBoardDao.boardListCount(hiBoard);
      }
      catch(Exception e)
      {
         logger.error("[HiBoardService] boardListCount Exception", e);
      }
      
      return count;
   }
   
   //게시물 리스트
   public List<HiBoard> boardList(HiBoard hiBoard)
   {
      List<HiBoard> list = null;
      
      try
      {
         list = hiBoardDao.boardList(hiBoard);
      }
      catch(Exception e)
      {
         logger.error("[HiBoardService] boardList Exception", e);
      }
      
      return list;
   }
   
   
}

-반드시 서비스에 대한 어노테이션을 정의해줘야 한다. 또 나중을 위해서 첨부파일을 업로드할 경로를 미리 선언해준다. 사실 이 서비스 부분은 전과 비슷하기 때문에 따로 특별하게 신경쓸 부분이 있지는 않다.

·다음은 컨트롤러에 대한 정의

-이제 서비스를 통해 쿼리문의 결과를 가져올 컨트롤러를 정의해준다.

package com.icia.web.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.icia.common.util.StringUtil;
import com.icia.web.model.HiBoard;
import com.icia.web.service.HiBoardService;
import com.icia.web.util.HttpUtil;

@Controller("hiBoardController")
public class HiBoardController 
{
	private static Logger logger = LoggerFactory.getLogger(HiBoardController.class);
	
	//쿠키명
	@Value("#{env['auth.cookie.name']}")
	private String AUTH_COOKIE_NAME;
	
	//파일 저장경로
	@Value("#{env['upload.save.dir']}")
	private String UPLOAD_SAVE_DIR;
	
	@Autowired
	private HiBoardService hiBoardService;
	
	//클래스 변수로 페이징을 위한 것들을 정의할 것임
	//전에는 추상 클래스로 해놓은 것 근데 어차피 게시판에만 쓰이기 때문에 여기서 정의
	//프로그램 내에서는 얘를 변경할 수 없는 것. 내가 직접 여기서 변경하지 않는 이상.
	private static final int LIST_COUNT = 5;	//한 페이지에 게시물 수
	private static final int PAGE_COUNT = 5;	//페이징 수
	
	//메소드 방식이 없으면 디폴트로 GET방식이 옴.
	@RequestMapping(value="/board/list")
	public String list(ModelMap model, HttpServletRequest request, HttpServletResponse response) 
	{
		//자기가 자기를 부를 수 있으니까 확인하기
		//조회 항목(1:작성자, 2:제목, 3:내용)
		String searchType = HttpUtil.get(request, "searchType", "");
		//조회값
		String searchValue = HttpUtil.get(request, "searchValue", "");
		//현재 페이지
		long curPage = HttpUtil.get(request, "curPage",(long)0);
		
		long totalCount = 0;
		List<HiBoard> list = null;
		
		//페이징 객체
		//Paging paging = null;
		
		//조회 객체
		//넘길 파라미터 값이 많으니까, 객체로 넘기는 것임.
		HiBoard search = new HiBoard();
		
		if(!StringUtil.isEmpty(searchType) && !StringUtil.isEmpty(searchValue)) 
		{
			//받아온 값이 있음.
			search.setSearchType(searchType);
			search.setSearchValue(searchValue);
		}
		else 
		{
			searchType = "";
			searchValue = "";
		}
		
		//두개의 값만 넘기면 전체 건수를 알 수 있음.
		//먼저 토탈 카운트를 하는 이유는 인덱스부터 빠르게 찾아서 값이 있냐를 보고 진행하겠다는 뜻임.
		//+로 페이징 처리를 위해서 토탈 카운트를 하는 것도 있음.
		totalCount = hiBoardService.boardListCount(search);
		
		logger.debug("[totalCount] = "+totalCount);
		
		if(totalCount > 0 ) 
		{
			//검색 결과가 있음
			//페이징 처리 추가해야 함.
			search.setStartRow(1);
			search.setEndRow(5);
			
			list = hiBoardService.boardList(search);
		}
		
		//앞에 ""는 list.jsp에서 쓸 변수임. 내 메소드 내에 있는 변수가 뒤의 파라미터임.
		model.addAttribute("list", list);
		model.addAttribute("searchType", searchType);
		model.addAttribute("searchValue", searchValue);
		model.addAttribute("curPage", curPage);
		
		
		return "/board/list";
	}
}

-전과 비슷하긴 하지만, 한가지, ModelMap을 통해서 .jsp에 보여줄 것이기 때문에 해당 부분도 정의해준다.

·list.jsp 작성

-정확하게 전부 작성하지는 않았지만, db에서 가져온 값을 뿌려주는 부분에 대한 것만 작성했다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/include/taglib.jsp" %>
<!DOCTYPE html>
<html>
<head>
<%@ include file="/WEB-INF/views/include/head.jsp" %>

<script>

</script>
</head>
<body>
<%@ include file="/WEB-INF/views/include/navigation.jsp" %>
<div class="container">
   
   <div class="d-flex">
      <div style="width:50%;">
         <h2>게시판</h2>
      </div>
      <div class="ml-auto input-group" style="width:50%;">
         <select name="_searchType" id="_searchType" class="custom-select" style="width:auto;">
            <option value="">조회항목</option>
            <option value="1" <c:if test="${searchType eq '1'}"> selected </c:if> >작성자</option>
            <option value="2" <c:if test="${searchType eq '2'}"> selected </c:if> >제목   </option>
            <option value="3" <c:if test="${searchType eq '3'}"> selected </c:if> >내용  </option>
         </select>
         <input type="text" name="_searchValue" id="_searchValue" value="${searchValue}" class="form-control mx-1" maxlength="20" style="width:auto;ime-mode:active;" placeholder="조회값을 입력하세요." />
         <button type="button" id="btnSearch" class="btn btn-secondary mb-3 mx-1">조회</button>
      </div>
    </div>
    
   <table class="table table-hover">
      <thead>
      <tr style="background-color: #dee2e6;">
         <th scope="col" class="text-center" style="width:10%">번호</th>
         <th scope="col" class="text-center" style="width:55%">제목</th>
         <th scope="col" class="text-center" style="width:10%">작성자</th>
         <th scope="col" class="text-center" style="width:15%">날짜</th>
         <th scope="col" class="text-center" style="width:10%">조회수</th>
      </tr>
      </thead>
      
      
      <tbody>
      
<!-- list 객체가 비어있지 않으면 -->
<c:if test="${!empty list}">
	<!-- 리스트에서 각각의 값을 hiBoard에 담는다는 뜻  -->
	<c:forEach var="hiBoard" items="${list}" varStatus="status">
      <tr>
         <td class="text-center">${hiBoard.hiBbsSeq}</td>
         <td>
            <a href="javascript:void(0)" onclick="fn_view()">
				<c:out value="${hiBoard.hiBbsTitle}" />
            </a>
         </td>
         <td class="text-center"><c:out value="${hiBoard.userName}" /></td>
         <td class="text-center">${hiBoard.regDate}</td>
         <!-- fmt 태그는 숫자 3자리마다 콤마 해주는 기능을 지원하는 태그임. -->
         <td class="text-center"><fmt:formatNumber type="number" maxFractionDigits="3" value="${hiBoard.hiBbsReadCnt}" /></td>
      </tr>
	</c:forEach>
</c:if>      


      </tbody>

      
      <tfoot>
      <tr>
            <td colspan="5"></td>
        </tr>
      </tfoot>
   </table>
   <nav>
      <ul class="pagination justify-content-center">

         <li class="page-item"><a class="page-link" href="javascript:void(0)" onclick="fn_list()">이전블럭</a></li>

   
         <li class="page-item"><a class="page-link" href="javascript:void(0)" onclick="fn_list()">1</a></li>

         
         <li class="page-item"><a class="page-link" href="javascript:void(0)" onclick="fn_list()">다음블럭</a></li>
      </ul>
   </nav>
   
   <button type="button" id="btnWrite" class="btn btn-secondary mb-3">글쓰기</button>
   
   <form name="bbsForm" id="bbsForm" method="post">
      <input type="hidden" name="hiBbsSeq" value="" />
      <input type="hidden" name="searchType" value="${searchType}" />
      <input type="hidden" name="searchValue" value="${searchValue}" />
      <input type="hidden" name="curPage" value="${curPage}" />
   </form>
</div>
</body>
</html>

-JSTL+EL문법을 사용하고, ModelMap을 이용해서 해당 값들을 넣어줄 수 있도록 전과 다르게 처리한 부분들이 있다. 예를 들면, value="${searchType}"이 부분, 그리고 <c:if test="${searchType eq '1'}"> selected </c:if>이 부분을 통해 조건에 대한 값을 선택되게 해놓는 것, 그리고

      <tbody>
      
<!-- list 객체가 비어있지 않으면 -->
<c:if test="${!empty list}">
	<!-- 리스트에서 각각의 값을 hiBoard에 담는다는 뜻  -->
	<c:forEach var="hiBoard" items="${list}" varStatus="status">
      <tr>
         <td class="text-center">${hiBoard.hiBbsSeq}</td>
         <td>
            <a href="javascript:void(0)" onclick="fn_view()">
				<c:out value="${hiBoard.hiBbsTitle}" />
            </a>
         </td>
         <td class="text-center"><c:out value="${hiBoard.userName}" /></td>
         <td class="text-center">${hiBoard.regDate}</td>
         <!-- fmt 태그는 숫자 3자리마다 콤마 해주는 기능을 지원하는 태그임. -->
         <td class="text-center"><fmt:formatNumber type="number" maxFractionDigits="3" value="${hiBoard.hiBbsReadCnt}" /></td>
      </tr>
	</c:forEach>
</c:if>      


      </tbody>

-리스트 객체의 각각 HiBoard 객체를 나타내는 반복문까지 주의해야 할 부분이다. 전과는 다르게 반복문을 사용한 부분이라서 조금 많이 살펴봐야 하는 부분이다.

·주말 과제

-프로젝트를 위한 메인 페이지를 부트스트랩으로 만들어오라는 것이 교수님의 숙제였다. 전에도 부트스트랩을 많이 봤지만, 갑작스럽게 페이지 하나를 만들어 오라니 사실 조금 부담되는 양이었지만 그래도 아침부터 일어나서 지금까지 계속 하고 있다. 빨리 작성해서 저녁에는 잘 수 있으면 좋겠다.

profile
비전공자란 이름으로 새로운 길을 가려 하는 신입

0개의 댓글