스프링 오라클 게시판 - seupeuling olakeul gesipan

🌈게시판 목록 만들기

이전까지는 기본적인 환경설정 작업을 해주었습니다. 이제 게시판 목록을 먼저 만들어보도록 하겠습니다.#### DB에 테이블을 먼저 설정해 줍니다.

🌻 DB 테이블 설정

스프링 오라클 게시판 - seupeuling olakeul gesipan

🌷BOARD 테이블을 생성해줍니다.

BOARD_CODE : 게시판 번호
BOARD_TITLE : 게시판 제목
BOARD_CONTENT : 게시판 내용
BOARD_WRITER : 게시판 작성자
BOARD_REGDATE : 게시판 날짜

PRIMARY KEY 는 기본키라고 하는데 기본키를 BOARD_CODE로 설정해줬습니다. 이 기본키는 나중에 수정이나 삭제 작업을 위해 쓰일겁니다.

CREATE SEQUENCE BOARD_SEQ; CREATE SEQUENCE BOARD_CODE_SEQ;는 시퀀스를 생성해 주겠다는 의미입니다. 오타가 있네요;; BOARD_CODE_SEQ로 해야합니다.

🌷SEQUENCE는 순서를 뜻하는 것으로 몇가지 작동을 어떤 기준에 따라 공간적 또는 시간적으로 순서를 정해 놓는 것을 말합니다. 오라클에서 행을 구분하기 위해 기본 키를 두는데 그 기본 키는 중복된 값을 가질 수 있기때문에 항상 유일한 값을 가져야합니다. 그런 기본 키가 유일한 값을 갖도록 사용자가 직접 생성하는 것이 아닌 숫자를 자동으로 생성해주는 명령어를 의미합니다.

시퀀스까지 만들어 주고 난 뒤에 SELECT*FROM 테이블명으로 테이블을 조회해봅니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

지금은 데이터를 추가 하지 않았기 때문에 조회를 해도 데이터가 없는 것을 알 수 있습니다.

🌷Spring에서 package와 게시판 제작에 필요한 Controller Service , ServiceImpl , DaoImpl , dto를 만들어 줍니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

스프링 오라클 게시판 - seupeuling olakeul gesipan

--> dto를 만들어 주고 난 뒤에 getter & setter도 같이 만들어줍니다.

🌷Controller Service Dao에도 각자에 맞는 설정들을 해줍니다.

*private static final Logger log 부분은 Console 창에서 값들이 잘 넘어가는지 보여주기 위해서 작성했습니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan
스프링 오라클 게시판 - seupeuling olakeul gesipan
스프링 오라클 게시판 - seupeuling olakeul gesipan
스프링 오라클 게시판 - seupeuling olakeul gesipan

🌷DB와 연결해주는 Mapper도 만들어줍니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

🌻 역할들 소개

지금까지 Controller Service Dao Mapper등등 제작에 필요한 것들을 만들었습니다.
그럼 이제 이 아이들이 무슨 역할을 하는 지 알아보도록 하겠습니다.

Controller는 웹에서 처리해야 할 데이터를 받습니다.
그리고 이 데이터를 담당할 Service를 선택해 호출합니다.
처리한 데이터를 다음 페이지에서 볼 수 있도록 셋팅해 이동할 페이지를 리턴합니다.
Service는 데이터를 Dao를 통해 넘겨주고 받으면서 비즈니스 로직을 수행해주는 역할을 합니다.
Dao는 DB를 통해 데이터를 조회하거나 수정 삭제 해주는 역할을 합니다
Dto는 DB에 있는 테이블 컬럼 값을 java에서 객체로 다루기 위해 사용합니다.

🌻 로직 작성

*Mapper

-Mapper에 로직을 추가해줍니다. parameterType 은 board에서 가져오는 거기 떄문에 board로 작성해주고 쿼리는 select를 이용하여 작성해주면 됩니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

*DaoImpl

-return값에 BoardList는 Mapper의 id값과 동일하게 하기 위해서 작성한것이고 board의 객체들을 boardList라는 이름에 담아주어 selectList로 보여주기 위함이라 생각하면 됩니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

*ServiceImpl

-bd.list(board)는 bd(BoardDaoImpl)에 있는 list(board)함수를 호출해서 반환하겠다는 뜻입니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

*Service

-BoardDaoImpl와 연결되는 부분입니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

*Controller

-BoardController에 URL은 /list로 정해주고 Oracle -> Dao -> Service -> Controller로 가져온 데이터들을 jsp에 뿌려주는 작업을 해야합니다.
model은 데이터를 담은 그릇이고 addAttribute("boardlist",list)부분은 위에 service에 담긴 list를 boardlist라는 이름으로 model에 담는걸로 해석하시면 될거같습니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

*jsp

-list.jsp파일을 만들어 준뒤 코드를 입력해줍니다.
<c:forEach items="${boardlist}" var="boardlist"> 에서 forEach는 받은 ${boardlist}값 만큼 반복해주는건데 자바에서 for문과 비슷한 역할을 합니다. 여기서 boardlist는 controller에서 이름을 boardlist로 정한 bs.list(board)를 가져온 것입니다. 그리고 var는 ${boardlist}를 boardlist라는 이름으로 선언해준것입니다.
그리고 forEach 와 jstl을 쓸려면 상단에 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 를 꼭 써줘야합니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

🌻실행

이제 실행을 하게 되면 목록 화면이 뜨게 됩니다. 아직 데이터가 없기 때문에 이렇게 화면이
보여지게 되고 다음에 게시판 작성부분으로 넘어가겠습니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

'(구버전) 스프링 게시판 만들기'는 내용이 부족하다고 판단하여
스프링 게시판 만들기를 새로 작성하였습니다.

링크 및 참조용으로 현재 게시물은 남겨두겠지만,
가급적이면 새로운 스프링 게시판 만들기를 참조해주시기 바랍니다.

웹 프로젝트의 기본기인 게시판 만들기입니다. '게시판'이라고 말했지만 응용력에 따라 블로그, 갤러리, 쇼핑몰이 될 수 있습니다.

새로운 프로젝트를 생성하고, 기본설정을 끝낸 상태에서 진행합니다.

오라클과 마이바티스 연동
톰캣 서버 추가
한글 설정

오라클로 게시판에 필요한 테이블과 시퀀스를 생성합니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

테이블은 글 번호, 제목, 내용, 작성자, 작성일자, 조회수로 구성되어있고 시퀀스는 테이블의 글 번호를 자동으로 1씩 증가시켜주는 기능입니다.

create table myBoard (
    bno       number            not null,
    title     varchar2(30)      not null,
    content   varchar2(2000)    not null,
    writer    varchar2(30)      not null,
    regDate   date              default sysdate,
    viewCnt   number            default 0,
    primary key(bno)
);
create sequence myBoard_seq;

스프링 오라클 게시판 - seupeuling olakeul gesipan

또, 주요 쿼리를 먼저 작성해서 직접 실행해봅니다.
게시판에서 기본적이지만 가장 중요한 기능인 작성-조회-수정-삭제입니다.

디벨로퍼에서 작성하고 이상없이 실행되는 쿼리들은 그대로 스프링에 옮겨서 사용합니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

작업한 내용은 꼭 커밋(commit)시켜서 적용시킵니다. 커밋을 하지 않으면, 지금까지 작업한 모든 내용은 적용되지 않습니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

쿼리가 정상적으로 작동되면 매퍼에 옮깁니다.
각 기능의 아이디(ID)는 한눈에 알기 쉽고 겹치지 않도록 합니다.

<?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.kuzuro.mappers.boardMapper">
   
    <!-- 작성 -->
 <insert id="write">
  insert into myBoard(bno, title, content, writer)
      values (myBoard_seq.nextval, #{title}, #{content}, #{writer})
 </insert>
 
 <!-- 조회 -->
 <select id="read" resultType="com.kuzuro.domain.BoardVO">
  select bno, title, content, writer, regDate, viewCnt
   from myBoard
    where bno = #{bno}
 </select>

 <!-- 수정 --> 
 <update id="update">
  update myBoard
   set
    title = #{title},
    content = #{content}
   where bno = #{bno}  
 </update>
 
 <!-- 삭제 -->
 <delete id="delete">
  delete from
   myBoard
  where bno = #{bno}
 </delete>
 
</mapper>

스프링 오라클 게시판 - seupeuling olakeul gesipan

자바 코드를 작성하기 전, src/main/java 하위에 용도별로 패키지를 생성합니다.

controller : 프로젝트 생성시 작성한 메인 패키지
domain : VO(Value Object) 패키지
persistence : DAO(Data Access Object) 패키지
service : 서비스 패키지

controller는 프로젝트 생성시 작성한 패키지로, 뷰(사용자가 보는 화면)에서 모든 정보를 받아 자바로 넘겨줍니다.

VO는 값을 가지고있는 객체로서, 데이터 베이스의 테이블과 같은 역할입니다. DTO(Data Transfer Object)와 조금 다르지만 구분없이 사용합니다.

DAO는 이름 그대로 데이터에 접속하는 객체입니다. VO를 기반의 값을 DAO를 통하여 실제 데이터 베이스에 전달합니다.

service는 controller에서 받은 정보를 가공하는 역할입니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

domain에 BoardVO 클래스를 생성합니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

테이블을 만들 때 사용했던 쿼리문을 가져와서 주석을 걸어둡니다. 필수는 아니지만, 작업할 때 실수하는 일이 줄어듭니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

단축키 Alt + Shift + S 또는 상단 메뉴의 Source에서 Generate Getters and Setters를 선택합니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

모두 선택(Select All)을 누르고 확인(OK)버튼을 클릭합니다.

모든 VO는 이런 방법으로 작성합니다.

package com.kuzuro.domain;

import java.util.Date;

public class BoardVO {
/* 
    bno       number            not null,
    title     varchar2(30)      not null,
    content   varchar2(200)     not null,
    writer    varchar2(30)      not null,
    regDate   date              default sysdate,
    viewCnt   number            default 0,
*/
 private int bno;
 private String title;
 private String content;
 private String writer;
 private Date regDate;
 private int viewCnt;
 
 
 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;
 }
 
 
}

스프링 오라클 게시판 - seupeuling olakeul gesipan

Persistence에 인터페이스(BoardDAO)와 구현부(BoardDAOImpl)를 작성합니다. 아직은 기본적인 기능만 있기 때문에 그렇게 복잡하진 않습니다.

package com.kuzuro.persistence;

import com.kuzuro.domain.BoardVO;

public interface BoardDAO {
 
 // 작성
 public void write(BoardVO vo) throws Exception;
 
 // 조회
 public BoardVO read(int bno) throws Exception;
 
 // 수정
 public void update(BoardVO vo) throws Exception;
 
 // 삭제
 public void delete(int bno) throws Exception;
 
}
package com.kuzuro.persistence;

import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import com.kuzuro.domain.BoardVO;

@Repository
public class BoardDAOImpl implements BoardDAO {

 // 마이바티스 
 @Inject
 private SqlSession sql;
 
 // 매퍼
 private static String namespace = "com.kuzuro.mappers.boardMapper";
  
 // 작성
 @Override
 public void write(BoardVO vo) throws Exception {
  sql.insert(namespace + ".write", vo);
 }
 // 조회

 @Override
 public BoardVO read(int bno) throws Exception {
  return sql.selectOne(namespace + ".read", bno);
 }

 // 수정
 @Override
 public void update(BoardVO vo) throws Exception {
  sql.update(namespace + ".update", vo);
 }

 // 삭제
 @Override
 public void delete(int bno) throws Exception {
  sql.delete(namespace + ".delete", bno);
 }

}

스프링 오라클 게시판 - seupeuling olakeul gesipan

Service에 Persistence와 마찬가지로 인터페이스(BoardService)와 구현부(BoardServiceImpl)를 작성합니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

이미 HomeController가 이미 있지만, 게시판만을 위한 전용 컨트롤러를 생성합니다.

package com.kuzuro.controller;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.kuzuro.domain.BoardVO;
import com.kuzuro.service.BoardService;

@Controller
@RequestMapping("/board/*")
public class BoardController {

private static final Logger logger = LoggerFactory.getLogger(BoardController.class);
 
 @Inject
 BoardService service;
 
 // 글 작성 get
 @RequestMapping(value = "/write", method = RequestMethod.GET)
 public void getWrite() throws Exception {
  logger.info("get write");
 }

 // 글 작성 post
 @RequestMapping(value = "/write", method = RequestMethod.POST)
 public String postWrite(BoardVO vo) throws Exception {
  logger.info("post write");
  
  service.write(vo);
  
  return "redirect:/";
 }
 
  
}

@RequestMapping의 값(value)을 통하여 브라우저로 접속할 수 있습니다.
GET은 해당 페이지에 접속, POST는 해당 페이지에서 값을 전송하는 것입니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

스프링이 추가한 패키지를 인식할 수 있도록, root-context.xml파일에 위 코드를 추가합니다.

 <!-- 패키지 -->

 <context:component-scan base-package="com.kuzuro.domain" />
 <context:component-scan base-package="com.kuzuro.persistence" />
 <context:component-scan base-package="com.kuzuro.service" />

스프링 오라클 게시판 - seupeuling olakeul gesipan

src → main → webapp → WEB-INF → views 하위에 board 폴더를 생성하고, 그 하위에 write.jsp파일을 생성하여 코드를 작성합니다.

이름대로, 이 파일은 게시물을 작성하는 용도입니다.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
 <title>kuzuro 게시판</title>
</head>
<body>

<div id="root">
 <header>
  <h2>kuzuro 게시판</h2>
 </header>

<hr />
 
 <nav>
  처음화면 - 글쓰기 - 로그인
 </nav>

<hr />

 <section id="container">
 
  <form role="form" method="post" autocomplete="off">
   <p>
    <label for="title">글 제목</label><input type="text" id="title" name="title" />
   </p>
   <p>
    <label for="content">글 내용</label><textarea id="content" name="content"></textarea>
   </p>
   <p>
    <label for="writer">작성자</label><input type="text" id="writer" name="writer" />
   </p>
   <p>
    <button type="submit">작성</button>
   </p>  
  </form>

 </section>

<hr />

 <footer>
  <p>만든이 : kuzuro</p>  
 </footer>

</div>

</body>
</html>

스프링 오라클 게시판 - seupeuling olakeul gesipan

home.jsp파일을 수정합니다. 불필요한 코드를 지우고, 첫화면에서 글쓰기 화면으로 바로 이동할 수 있도록 링크를 추가했습니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

프로젝트를 실행하면, 링크만 하나 덩그러니있는 심심한 화면이 보입니다.
링크를 클릭하면 게시물 작성 화면으로 이동할 수 있습니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

입력한 값이 제대로 잘 저장되는지 확인하도록, 아무 글이나 적고 작성 버튼을 클릭합니다.

스프링 오라클 게시판 - seupeuling olakeul gesipan

작성 버튼을 누르면, 처음 화면으로 돌아옵니다. 컨트롤러에서 리턴값을 처음 화면으로 했기 때문입니다.

글이 제대로 저장되었는지 확인하려면, 디벨로퍼에서 확인해야합니다. 왜냐하면 아직 조회용 jsp파일을 생성하지 않았으니 말이죠.

스프링 오라클 게시판 - seupeuling olakeul gesipan

입력했던 글이 잘 저장되어있습니다.