스프링에서 제공하는 MVC 프레임워크를 이용해 게시판을 만들어 보자.
* 서비스 되는 게시판이 아닌 학습용 예제에 맞는 게시판이다.
보통 필자는 게시판을 만드는 프로세스는 다음과 같이 진행한다.
- DB에 게시판 테이블 생성하기
- 테이블 컬럼 값들을 DTO(VO) 객체 클래스에 매핑
- CRUD 만들기 SQL문 쿼리 작성하기
- MyBatis Mapper 작성(xml)
- DAO 인터페이스 만들기
- DAO implements 메서드 구현
- Service 인터페이스 만들기
- Service implements 메서드 구현
- Controller 클래스 만들기
- View 역할의 게시판 페이지 board_list.jsp 코드 작성
그러나 이번 포스팅에서 진행할 프로세스는 게시판 목록 페이지 구현을 위해서
'최소한'의 작업만 진행할 것이기에 저 프로세스에서 간략화 된 작업만 진행 할 것이다.
예제 소스 파일 다운로드
1. DB에 게시판 테이블 생성하기 (오라클 11g)
-- 게시판 테이블 만들기
CREATE TABLE board (
bno number not null primary key --게시물번호
,title varchar2(200) not null --게시물제목
,content varchar2(4000) --게시물내용
,writer varchar2(50) not null --게시물작성자
,regdate date default sysdate --게시물작성일자
,viewcnt number default 0 --게시물조회수
);
-- 테이블 데이터 삭제
DELETE FROM board;
-- 게시물 레코드 1000개 삽입하기
declare
i number := 1; begin
while i<=1000 loop
insert into board (bno,title,content,writer) values
((select nvl(max(bno)+1,1) from board) ,'제목'||i,'내용'||i,'kim');
i := i+1;
end loop; end;
/
select count(*) from board; select * from board;
-- commit
commit;
2. 테이블 컬럼 값들을 DTO(VO) 객체 클래스에 매핑
package com.example.spring01.model.dto;
import java.util.Date;
public class BoardDTO {
//Field
private int bno; //게시물번호
private String title; //게시물제목
private String content; //게시물내용
private String writer; //게시물작성자
private Date regdate; //게시물작성일자
private int viewcnt; //게시물조회수
//Constructor
public BoardDTO() {}
public BoardDTO(int bno, String title, String content, String writer, Date regdate, int viewcnt) {
super();
this.bno = bno;
this.title = title;
this.content = content;
this.writer = writer;
this.regdate = regdate;
this.viewcnt = viewcnt;
}
//getter & setter
public int getBno() {
return bno;
}
public void setBno(int bno) {
this.bno = bno;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public Date getRegdate() {
return regdate;
}
public void setRegdate(Date regdate) {
this.regdate = regdate;
}
public int getViewcnt() {
return viewcnt;
}
public void setViewcnt(int viewcnt) {
this.viewcnt = viewcnt;
}
//toString
@Override
public String toString() {
return "BoardDTO [bno=" + bno + ", title=" + title + ", content=" + content + ", writer=" + writer
+ ", regdate=" + regdate + ", viewcnt=" + viewcnt + "]";
}
}
3. CRUD 만들기 - SQL문 쿼리 작성하기 (여기선 게시판 목록 불러오는 쿼리만 작성하겠다.)
select bno,title,writer,regdate,viewcnt
from board order by bno desc
4. boardMapper.xml 작성하기
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="board">
<!-- 게시물 목록 데이터 불러오기 -->
<select id="boardList" resultType="com.board.example.dto.BoardDTO">
select bno,title,writer,regdate,viewcnt
from board order by bno desc
</select>
</mapper>
5. DAO 인터페이스 만들기
package com.board.example.dao;
import java.util.List;
import com.board.example.dto.BoardDTO;
public interface BoardDAO {
// 게시물 목록 보기
public List<BoardDTO> boardList() throws Exception;
}
6. DAO implements 메서드 구현하기
package com.board.example.dao;
import java.util.List;
import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import com.board.example.dto.BoardDTO;
@Repository
public class BoardDAOImpl implements BoardDAO {
@Inject
SqlSession sqlSession;
@Override
public List<BoardDTO> boardList() throws Exception {
return sqlSession.selectList("board.boardList");
}
}
7. Service 인터페이스 만들기
package com.board.example.service;
import java.util.List;
import com.board.example.dto.BoardDTO;
public interface BoardService {
// 게시물 목록 조회
public List<BoardDTO> boardList() throws Exception;
}
8. Service implements 메서드 구현
package com.board.example.service;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import com.board.example.dao.BoardDAO;
import com.board.example.dto.BoardDTO;
@Service
public class BoardServiceImpl implements BoardService {
@Inject
BoardDAO boardDao;
@Override
public List<BoardDTO> boardList() throws Exception {
return boardDao.boardList();
}
}
9. Controller 클래스 만들기
package com.board.example.controller;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.board.example.dto.BoardDTO;
import com.board.example.service.BoardService;
@Controller
@RequestMapping("/board/*")
public class BoardController {
@Inject
BoardService boardService;
// 과거 ModelAndView를 활용한 방법
// @RequestMapping("list.do")
// public ModelAndView boardMenu() throws Exception {
// List<BoardDTO> list = boardService.boardList();
// ModelAndView mav = new ModelAndView();
// mav.setViewName("board/board_list");
// mav.addObject("list", list);
// return mav; // board/board_list.jsp로 이동
// }
// 현재 자주 쓰는 Model 클래스를 DI 하는 방법
@RequestMapping("list.do")
public String boardList(Model model) throws Exception {
List<BoardDTO> list = boardService.boardList(); // list 변수에 결과 값을 담는다
model.addAttribute("list", list); // model에 데이터 값을 담는다
return "board/board_list"; // board/board_list.jsp로 이동
}
}
위 Controller에서 두가지 구현 방법을 명시해놨는데
ModelAndView는 @RequestMapping 나오기 전의 방법이고 아래 코드보다 많은 코드를 필요로 하는 것을 볼 수 있다.
그 과정에서 메서드 안에서 ModelAndView 클래스를 new 하는 과정도 있고 아래 코드보다 조금 번거로운 면이 있다.
필자는 아래 소스코드를 선호하며 파라미터로 Model 클래스를 주입하는 것이 스프링과 좀 더 어울리지 않나 생각한다.
* String으로 jsp 파일 이름을 리턴하고 Model 클래스를 의존주입하며 모델 안에 데이터를 담아 값을 넘기는 방식
10. View 역할의 게시판 페이지 board_list.jsp 코드 작성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- fmt를 사용하기위한 태그 라이브러리 -->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>board_list 페이지입니다.</h2>
<table border="1">
<tr>
<th>번호</th>
<th>제목</th>
<th>글쓴이</th>
<th>작성일자</th>
<th>조회수</th>
</tr>
<!-- forEach 문은 리스트 객체 타입을 꺼낼때 많이 활용된다. -->
<c:forEach var="row" items="${list}">
<tr>
<!-- 컨트롤러에서 넘겨준 list 모델 객체를 쓰는 방법을 잘 익혀두자 -->
<td>${row.bno}</td>
<td>${row.title}</td>
<td>${row.writer}</td>
<td>
<!-- 데이터 타입을 사용하는 방법 -->
<fmt:formatDate value="${row.regdate}" pattern="yyyy-MM-dd HH:mm:ss" />
</td>
<td>${row.viewcnt}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
* 별첨 (home.jsp와 menu.jsp 파일 소스코드 첨부)
home.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<%@ include file="include/menu.jsp" %>
<h1>Hello world!</h1>
<P> The time on the server is ${serverTime}. </P>
</body>
</html>
menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c"
uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="path"
value="${pageContext.request.contextPath}" />
<div style="text-align: center;">
<a href="${path}/">main</a>
<a href="${path}/board/list.do">게시판</a>
</div>
<hr>
View 출력 화면 (메뉴에 게시판을 클릭했을때 모습)
이렇게 게시판 리스트 값을 DB에서 가져와 테이블 형태로 뷰 화면에 출력하는 것을 완료하였다.
지금은 아주 기본적으로 DB에서 정보를 가져와 테이블로 출력하는 아주아주 기본적인 작업만 진행한 상태다.
게시판이라고 할 수 있는 상태가 아니다.
이외에 목록을 클릭했을때 해당 게시물에 대한 컨텐츠 내용을 출력할 수 있게 구현해야 하며
게시글 작성, 게시글 삭제, 게시글 수정, 게시글 목록 페이징 처리 등.....
앞으로 작업해야 할 일들이 많다.
이제 그 기능들을 차츰차츰 구현해 나가보자.
다양한 예제가 많은 블로그입니다.
스프링 입문하시는 경우에 아래 블로그 참고하시면 좋습니다.
출처 : https://lhoris.tistory.com/33
'Back-End > Spring' 카테고리의 다른 글
[Spring Boot] Spring Security 적용하기 (0) | 2023.02.09 |
---|---|
[Spring]Spring MVC 활용 (0) | 2023.02.09 |
[Spring]Log4j 와 slf4j (maven 설정, commons-logging, appender, logger, layout) (0) | 2023.02.09 |
[Spring] Spring 설정 Xml Config에서 Java Config로 바꾸는 방법 (요령) (0) | 2023.02.06 |
[Spring] Spring 설정을 XML에서 Java Config로 바꾸기 (0) | 2023.02.06 |