오늘이라도
[MyBatis] 18. 게시판 만들기 ① : MyBatis 준비 / DTO, DAO 작성 / MVC2 서블렛 구성 본문
[MyBatis] 18. 게시판 만들기 ① : MyBatis 준비 / DTO, DAO 작성 / MVC2 서블렛 구성
upcake_ 2020. 6. 2. 10:34https://github.com/upcake/Class_Examples
교육 중에 작성한 예제들은 깃허브에 올려두고 있습니다.
gif 파일은 클릭해서 보는 것이 정확합니다.
- 게시판 만들기 ① : MyBatis 준비 / DTO, DAO 작성 / MVC2 서블렛 구성 -
□ 진행 상황(※ 볼드체 : 오늘 다룬 파일들)
○ JAVA
- com.hanul.mybatis : board.sql, db.properties, SqlMapConfig.xml, boardMapper.xml
- com.hanul.dto : BoardDTO.java, SearchDTO.java
- com.hanul.dao : BoardDAO.java
- com.hanul.controller : BoardFrontController.java ▶ Servlet : web.xml에서 Mapping
- com.hanul.action : Action.java(Interface), ActionForward.java, Boardxxx.java(BoardListAction.java)
-----------------------------------------------------------------------------------------------------
○ WebContent
- boardMain.html
- board\ : *.jsp (boardList.jsp)
- css\ : *.css
- js\ : *.js
- images\ : *.png, *.gif, *.jpg
-----------------------------------------------------------------------------------------------------
boardMain.html → boardList.do(*.do) → web.xml → BoardFrontController.java(Servlet)
→ BoardListAction.java → BoardDAO.java → boardMapper.xml → BoardDAO.java
→ BoardListAction.java → BoardFrontController.java → ActionForward.java
→ boardList.jsp
□ 작동 화면 및 코드
▼board.sql : board 테이블 생성
--Eclipse와 DB 연동 오류 발생 시 해결 방법
--1. Eclipse 종료
--2. workspace\.metadata\.plugins\org.eclipse.datatools.sqltools.result
--3. 해당 폴더의 파일을 삭제 시킨 후 Eclipse 실행
--테이블 생성
CREATE TABLE tblBoard(
b_num NUMBER PRIMARY KEY NOT NULL,
b_subject VARCHAR2(50),
b_pwd VARCHAR2(20),
b_content VARCHAR2(2000),
b_writer VARCHAR2(20),
b_date VARCHAR2(20),
b_readcount NUMBER
);
--전체 레코드 검색
SELECT * FROM tblBoard ORDER BY b_num DESC;
--자동 증가값 설정 : b_num → b_num_seq 변수
CREATE SEQUENCE b_num_seq START WITH 1;
--시퀀스는 기본적으로 20개 단위로 주어진다.
--1, 2, 3을 삭제해도 4, 5부터 시작하는 문제가 있다.
--테이블을 삭제해도 시퀀스는 살아있고, 새 테이블을 만들면 다음 20번을 줘서 21번부터 시작한다.
--임의의 레코드 삽입
INSERT INTO tblBoard VALUES(b_num_seq.nextval, 'subject', 'pwd', 'content', 'writer', sysdate, 0);
--전체 레코드 삭제
DELETE FROM tblBoard;
--테이블 삭제
DROP TABLE tblBoard;
--자동 증가 값 삭제
DROP SEQUENCE b_num_seq;
▼db.properties : DB 접속 정보
driver = oracle.jdbc.driver.OracleDriver
url = jdbc:oracle:thin:@127.0.0.1:1521:XE
username = hanul
password = 0000
▼SqlMapConfig.xml : MyBatis 설정
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="com/hanul/mybatis/db.properties" />
<typeAliases>
<typeAlias type="com.hanul.dto.BoardDTO" alias="BoardDTO"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/hanul/mybatis/boardMapper.xml" />
</mappers>
</configuration>
▼boardMapper.xml : 매핑, SQL문 작성
<?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 namespace="com.hanul.mybatis.boardMapper.xml">
<select id="boardSearchAll" resultType="BoardDTO">
SELECT * FROM tblBoard ORDER BY b_num DESC
</select>
</mapper>
▼BoardDTO.java : 게시글 정보 양식 클래스
package com.hanul.dto;
import java.io.Serializable;
public class BoardDTO implements Serializable {
private int b_num;
private String b_subject;
private String b_pwd;
private String b_content;
private String b_writer;
private String b_date;
private int b_readcount;
public BoardDTO() {}
public BoardDTO(int b_num, String b_subject, String b_pwd, String b_content, String b_writer, String b_date,
int b_readcount) {
super();
this.b_num = b_num;
this.b_subject = b_subject;
this.b_pwd = b_pwd;
this.b_content = b_content;
this.b_writer = b_writer;
this.b_date = b_date;
this.b_readcount = b_readcount;
}
public int getB_num() {
return b_num;
}
public void setB_num(int b_num) {
this.b_num = b_num;
}
public String getB_subject() {
return b_subject;
}
public void setB_subject(String b_subject) {
this.b_subject = b_subject;
}
public String getB_pwd() {
return b_pwd;
}
public void setB_pwd(String b_pwd) {
this.b_pwd = b_pwd;
}
public String getB_content() {
return b_content;
}
public void setB_content(String b_content) {
this.b_content = b_content;
}
public String getB_writer() {
return b_writer;
}
public void setB_writer(String b_writer) {
this.b_writer = b_writer;
}
public String getB_date() {
return b_date;
}
public void setB_date(String b_date) {
this.b_date = b_date;
}
public int getB_readcount() {
return b_readcount;
}
public void setB_readcount(int b_readcount) {
this.b_readcount = b_readcount;
}
}
▼BoardDAO.java : 기능 담당 클래스
package com.hanul.dao;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.hanul.dto.BoardDTO;
public class BoardDAO {
//①SqlSessionFactory 설정
private static SqlSessionFactory sqlMapper;
static {
String resource = "com/hanul/mybatis/SqlMapConfig.xml";
try {
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlMapper = new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
e.printStackTrace();
System.out.println("SqlSessionFactory Exception");
}
} //static
//전체 목록 검색
public List<BoardDTO> boardSearchAll() {
SqlSession session = sqlMapper.openSession();
List<BoardDTO> list = null;
list = session.selectList("boardSearchAll");
session.close();
return list;
} //boardSearchAll()
} //class
▼boardMain.html : 메인 화면
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>BoardMain</title>
</head>
<body>
<script type="text/javascript">
location.href = "boardList.do";
//MVC 패턴 1에서는 동작 하나 당 서블렛 하나였고, JSP에서 대부분의 기능을 맡았다.
//MVC 패턴 2에서는 서블렛 하나로 여러 경로를 담당하고, View파트를 JSP에서 처리한다.
</script>
</body>
</html>
▼BoardFrontController.java : 클라이언트의 요청을 해당하는 비즈니스 로직으로 연결해주는 서블렛
package com.hanul.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.hanul.action.Action;
import com.hanul.action.ActionForward;
import com.hanul.action.BoardListAction;
@WebServlet("/BoardFrontController.do")
public class BoardFrontController extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0. 불필요한 코드를 지우고 서비스 메서드만 남겨둔다.
//1. 클라이언트가 어떤 요청을 했는지를 파악한다.
request.setCharacterEncoding("utf-8");
//localhost:8080/mbb/boardList.do
//mbb : context root
//mbb/boardList.do : uri-pattern
//uri-pattern에서 context root를 잘라내서 boardList.do만 남긴다.
String uri = request.getRequestURI(); //uri-pattern 값 : /mbb/XXX.do
String ctx = request.getContextPath(); //Context root 값 : /mbb
String command = uri.substring(ctx.length()); //실제 요청한 페이지 : /XXX.do
//System.out.println("uri : " + uri);
//System.out.println("ctx : " + ctx);
//System.out.println("command : " + command);
//2. 클라이언트의 요청(*.do → command)과 실제 처리할 비즈니스 로직(Action Class) 연결
Action action = null;
ActionForward forward = null;
if(command.equals("/boardList.do")) {
action = new BoardListAction(); //상위 객체(부모)쪽으로 업캐스팅 (다형성)
forward = action.execute(request, response);
}
//3. 페이지 전환(프레젠테이션 로직) : sendRedirect(), forward()
if(forward != null) {
if(forward.isRedirect()) { //true : sendRedirect() 페이지 전환
response.sendRedirect(forward.getPath());
} else { //false : forward() 페이지 전환
RequestDispatcher rd = request.getRequestDispatcher(forward.getPath());
rd.forward(request, response);
}
}
}
}
▼web.xml : 위의 서블렛이 모든 do를 대응하게끔 매핑
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>06.MyBatisBoard</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<display-name>BoardFrontController</display-name>
<servlet-name>BoardFrontController</servlet-name>
<servlet-class>com.hanul.controller.BoardFrontController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BoardFrontController</servlet-name>
<url-pattern>*.do</url-pattern>
<!-- BoardFrontController 하나로 모든 *.do 대응 -->
</servlet-mapping>
</web-app>
▼Action.java : servlet과 비슷한 역할을 하게 만든 인터페이스
package com.hanul.action;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
//추상 메서드(abstract를 안걸어도 인터페이스에서는 어짜피 추상메서드라 상관이 없다)
public abstract ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
▼ActionForward.java : 페이지 전환을 담당할 클래스
package com.hanul.action;
public class ActionForward {
private String path; //View Page(*.jsp)의 경로와 파일명을 저장할 변수
private boolean isRedirect; //페이지 전환 방식 ▶ true : sendRedirect()
// ▶ false : forward()
//Getter & Setter 만든다
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isRedirect() {
return isRedirect;
}
public void setRedirect(boolean isRedirect) {
this.isRedirect = isRedirect;
}
}
▼BoardListAction.java : boardList.jsp로의 페이지 연결을 담당하는 액션 클래스
package com.hanul.action;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.hanul.dao.BoardDAO;
import com.hanul.dto.BoardDTO;
public class BoardListAction implements Action {
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//DAO 연동하여 게시판 테이블의 전체 목록을 가져오는 작업을 수행 : 비즈니스 로직
BoardDAO dao = new BoardDAO();
List<BoardDTO> list = dao.boardSearchAll();
request.setAttribute("list", list);
//BoardListAction 작업을 마무리 했다 → 프레젠테이션 로직(페이지 전환) : ActionForward.java
//① View Page(path) : board/boardList.jsp
//② 페이지 전환 방식(isRedirect) : forward()
ActionForward forward = new ActionForward();
forward.setPath("board/boardList.jsp");
forward.setRedirect(false); // true : sendRedirect() / false : forward()
return forward;
}
}
▼boardList.jsp : 게시판 목록을 보여줄 화면
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>BoardList JSP</title>
</head>
<body>
<div align="center">
<h3>게시판 전체 목록 보기</h3>
</div>
</body>
</html>
'취업성공패키지 SW 개발자 교육 > Web' 카테고리의 다른 글
[MyBatis] 20. 게시판 만들기 ③ : 게시글 조회, 조회수 증가, 게시글 삭제, 게시글 수정 (0) | 2020.06.04 |
---|---|
[MyBatis] 19. 게시판 만들기 ② : 게시글 작성 (0) | 2020.06.03 |
[MyBatis] 17. 조건 검색 (0) | 2020.06.01 |
[Web] 16. MyBatis로 회원 정보 관리 구현 (0) | 2020.05.29 |
[Servlet & JSP] 15. JSTL : functions / MyBatis 개발 환경 구축 (0) | 2020.05.28 |