
SqlSessionFactoryBean이 JDBC 기능의 대부분은 한다!
Controller와 SqlSessionFactoryBean는 Mapper를 통해 연결한다.

SqlSessionFactoryBean이 @Mapper 어노테이션을 찾아서 그 아래의 기능을 구현한다.
필드명과 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;
// }
//}
// 게시판 입력페이지 이동 기능 - boardForm.do
@RequestMapping("/boardForm.do")
public String boardForm() {
System.out.println("게시판 입력페이지 이동 기능");
return "boardForm";
}
<%@ 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>


<!-- 한글 인코딩 -->
<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>
// 게시판 입력 기능
@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가 필요하다
}
@Mapper // Mapper로 인식하기 위한 어노테이션
public interface BoardMapper {
@Insert("INSERT INTO BOARD (TITLE, CONTENTS, WRITER) VALUES(#{title}, #{contents}, #{writer})") // vo안의 필드명 써야함
public void boardInsert(Board vo);
}
varStatus 이용하여 글번호 보기varStatus : 반복문의 상태를 기억하는 속성 <!-- 게시글 내용 출력 -->
<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>

// 게시글 상세 보기 기능
@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: 하나의 파라미터값 가져올 때 사용함
@Mapper
public interface BoardMapper {
@Select("SELECT * FROM BOARD WHERE IDX = #{idx}")
public Board boardContents(int idx);
}

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

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>
