Spring [03] 게시판 만들기(2)

totwo·2024년 8월 29일

Spring/JPA

목록 보기
3/17
post-thumbnail

💡 interface를 Controller에서 객체처럼 사용할 수 있는 이유

root-context.xml

SqlSessionFactoryBean이 JDBC 기능의 대부분은 한다!

Controller와 SqlSessionFactoryBean는 Mapper를 통해 연결한다.

SqlSessionFactoryBean이 @Mapper 어노테이션을 찾아서 그 아래의 기능을 구현한다.

BoardMapper (interface)

필드명과 DB의 컬럼명이 똑같아야 알아서 연결한다!
@Autowired 어노테이션은 Memory(IocContainer)에 있는 SqlSessionFactoryBean을 받아온 것
Controller에서 @Autowired 통해 BoardMapper(부모) 형태로 사용할 수 있도록 Upcasting 된 것임.

//    // @Mapper어노테이션 넣자마자 자동 생성되는 클래스
//    // SSFB는 BoardMapper를 상속받고 있고
// public class SqlSessionFactoryBean implements BoardMapper{
//
//	@Override
//	public ArrayList<Board> boardList() {
//		// JDBC 코드 구현
//		return null;
//	}
//}

게시판 입력 페이지

BoardController.java (class)

  • 게시판 입력페이지 이동 기능
	// 게시판 입력페이지 이동 기능 - boardForm.do
	@RequestMapping("/boardForm.do")
	public String boardForm() {
		System.out.println("게시판 입력페이지 이동 기능");		
		return "boardForm"; 
	}

boardForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> 
<title>boardForm.jsp</title>
</head>
<body> 
	<div class="container">
	  <h2>Spring MVC01</h2>
	  <div class="panel panel-default">
	    <div class="panel-heading">Board</div>
	    <div class="panel-body">
	    	<form action="boardInsert.do" method="post">
	    		<table class="table">
	    			<tr>
	    				<td>제목</td>
	    				<td><input class="form-control" name="title" type="text"></td> <!-- board 안에 있는 필드값과 동일하게 한다. -->
	    			</tr>
	    			<tr>
	    				<td>내용</td>
	    				<td><textarea class="form-control" name="contents" rows="7" cols=""></textarea></td>
	    			</tr>
	    			<tr>
	    				<td>작성자</td>
	    				<td><input class="form-control" name="writer" type="text"></td> <!-- board 안에 있는 필드값과 동일하게 한다. -->
	    			</tr>
	    			<tr>
	    				<td colspan="2" align="center">
	    					<button class="btn btn-info" type="submit">등록</button> <!-- form태그 안에 버튼에 type 주지 않으면 submit이긴 함 -->
	    					<button class="btn btn-warning" type="reset">취소</button> 
	    				</td>  
	    			</tr>
	    		</table>
	    	</form>
	    </div>
	    <div class="panel-footer">AISCHOOL2024 - Fighting :]</div>
	  </div>
	</div>
</body>
</html>

한글 인코딩

web.xml

  • 한글 인코딩
	<!-- 한글 인코딩 -->
	<filter>
		<filter-name>encodingFilter</filter-name>
			<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
			<init-param>
				<param-name>encoding</param-name>
				<param-value>UTF-8</param-value>
			</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

게시판 입력 기능

BoardController.java (class)

  • 게시판 입력 기능
	// 게시판 입력 기능
	@RequestMapping("/boardInsert.do")
	public String boardInsert(Board vo) {
		// input 값이 두 개 이상이고 name값이 vo의 필드명과 같다면 `Board`로 받으면 된다
		// 기본생성자가 필요한 이유이다. 
		System.out.println("게시판 입력 기능"); 
		mapper.boardInsert(vo);
		return "redirect:boardList.do";
		// Spring은 forward 이동 방식을 사용하고 있기 때문에 여기선 redirect가 필요하다
	}

BoardMapper (interface)

  • INSERT 기능
@Mapper // Mapper로 인식하기 위한 어노테이션
public interface BoardMapper {
	 
	@Insert("INSERT INTO BOARD (TITLE, CONTENTS, WRITER) VALUES(#{title}, #{contents}, #{writer})") // vo안의 필드명 써야함 
	public void boardInsert(Board vo); 
} 

boardList.jsp

  • varStatus 이용하여 글번호 보기
  • varStatus : 반복문의 상태를 기억하는 속성
  • 글제목 눌렀을 때 글 상세보기 할 수 있도록 링크 연결하기 (IDX를 통해)
		    		<!-- 게시글 내용 출력 -->
	    			<c:forEach varStatus="i" items="${list}" var="list"> <!-- 반복문의 상태를 기억하는 속성 -->
	    				<tr>
		    				<td><c:out value="${i.count}"/></td>	<!--  index : 0부터 나옴, count : 1부터 나옴 -->
		    				<td>
		    				<a href="boardContents.do?idx=${list.idx}">
		    				<c:out value="${list.title}"/>
		    				</a>
		    				</td>		    				
		    				<td><c:out value="${list.writer}"/></td>		    				
		    				<td><c:out value="${list.indate}"/></td>			    							
		    				<td><c:out value="${list.count}"/></td>			
	    				</tr>    							
	    			</c:forEach> 

boardForm.jsp

  • 목록 버튼 추가

게시글 상세 보기

BoardController.java

  • 게시글 상세 보기 기능
	// 게시글 상세 보기 기능
	@RequestMapping("/boardContents.do")
	public String boardContents(@RequestParam("idx") int idx, Model model) {
		// @RequestParam : 하나의 파라미터를 가져올 때 사용하는 어노테이션
		System.out.println("게시글 상세보기 기능");
		Board vo = mapper.boardContents(idx);
		model.addAttribute("vo", vo);
		return "boardContents";
	}
  • @RequestParam : 하나의 파라미터값 가져올 때 사용함

BoardMapper (interface)

@Mapper  
public interface BoardMapper {
 
	@Select("SELECT * FROM BOARD WHERE IDX = #{idx}")
	public Board boardContents(int idx);
}


제목을 클릭하였을 때 제대로 SELECT 해오는지 확인하기 위해
예시로 vo.tostring() console창에 출력해보니 잘 나온다!

boardContents.jsp

1) 글 작성시 개행을 하면 개행된 채로 글을 보고 싶다
2) 날짜를 년/월/일만 보고 싶다.

  • ✅ 함수 기능이 들어가 있는 taglib
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!-- 함수 기능이 들어가 있는 taglib -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> 
<title>boardContents.jsp</title>
</head>
<body> 

	<% pageContext.setAttribute("nl", "\n"); %>
	<div class="container">
	  <h2>Spring MVC01</h2>
	  <div class="panel panel-default">
	    <div class="panel-heading">Board</div>
	    <div class="panel-body">
    		<table class="table"> 
    			<tr>
    				<td>제목</td>
    				<td><c:out value="${vo.title}"/></td> 
    			</tr>
    			<tr>
    				<td>내용</td>
    				<td>${fn:replace(vo.contents, nl, "<br>")}</td>
    				<!-- 개행시 개행 되어 출력될 수 있도록  -->
    				<!-- c:out 안에 넣으면 안 된다 -->
    			</tr>
    			<tr>
    				<td>작성자</td>
    				<td><c:out value="${vo.writer}"/></td> 
    			</tr>
    			<tr>
    				<td>작성일</td>
    				<td>${fn:split(vo.indate, " ")[0]}</td> 
                    <!-- 날짜가 2024-08-29 12:29:23.0 이렇게 뜸--> 
    				<!-- 띄어쓰기 기준으로 날짜를 나누자 -->
    			</tr>
    			<tr>
    				<td colspan="2" align="center"> 
    				</td>  
    			</tr>
    		</table>
	    </div>
	    <div class="panel-footer">AISCHOOL2024 - Fighting :]</div>
	  </div>
	</div>
</body>
</html>

profile
Hello, World!

0개의 댓글