본문으로 바로가기

Spring 개발 - 게시판 만들기 #목록

category 공부/Spring 2018. 9. 17. 16:40

가장 기초적이고 기본적인 게시판을 만들어보자. 제일 먼저 단순히 불러오기만 하면 되는 게시판 목록을 만들어 보자!


1. DB 생성

1
2
3
4
5
6
7
8
9
10
CREATE TABLE `one_board` (
  `IDX` int(11NOT NULL AUTO_INCREMENT,
  `PRE_IDX` int(11DEFAULT NULL,
  `TITLE` varchar(100NOT NULL,
  `CONTENTS` varchar(4000NOT NULL,
  `HIT_CNT` int(11NOT NULL,
  `DEL_CHK` varchar(1NOT NULL DEFAULT 'N',
  `CREA_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `CREA_ID` varchar(30NOT NULL,  PRIMARY KEY (`IDX`)
ENGINE=InnoDB DEFAULT CHARSET=utf8
cs

MySQL을 사용하여 DB를 생성한 것이다. 



2. 파일 및 패키지 생성

Controller는 웹 클라이언트에서 들어온 요청을 해당 비즈니스 로직을 호출하고, 수행결과와 함께 응답을 해주는 Dispatcher 역할을 한다.

Service 영역은 두 개의 파일로 구성된다. Service 인터페이스와 이것을 실제로 구현한 ServiceImpl 클래스로 구현된다. 이렇게 사용하는 이유는 Spring의 IoC/D 기능을 이용한 Bean 관리 기능을 사용하기 위해서 이다. Service 인터페이스는 비즈니스 로직을 수행하기 위한 메서드를 정의하고, ServiceImp 클래스는 Service 인터페이스를 통해 정의된 메서드를 실제로 구현하는 클래스이다.

DAO는 실제로 데이터베이스에 접근하여 데이터를 가져오거나 입력하는 역할을 수행한다.


파일과 패키지들을 먼저 만들어 놓고 시작하자. 만들면서 하나하나 만들어도 된다!


2-1. BoardController.java

1
2
3
4
5
6
7
8
package tody.prj.controller;
 
import org.springframework.stereotype.Controller;
 
@Controller
public class BoardController {
 
}
cs

- 5행 : @Controller 어노테이션(Annotation)을 이용하여 Controller 객체임을 선언한다.


2-2. BoardService.java

1
2
3
4
5
package tody.prj.service;
 
public interface BoardService {
 
}
cs

** class가 아니라 interface이다.


2-3. BoardServiceImpl.java

1
2
3
4
5
package tody.prj.service;
 
public class BoardServiceImpl implements BoardService {
 
}
cs

** BoardService.java를 implements 받는다. Service 인터페이스에서 정의된 메서드들을 실제로 구현한다.


2-3. BoardDAO.java

1
2
3
4
5
6
7
8
9
10
package tody.prj.dao;
 
import org.springframework.stereotype.Repository;
 
import tody.common.dao.AbstractDAO;
 
@Repository("boardDAO")
public class BoardDAO extends AbstractDAO{
 
}
cs
** AbstractDAO는 직접 만든 클래스를 상속받은 것이다. AbstarctDAO를 상속받지 않아도 된다.
상속 받지 않고 싶으면 AbstractDAO에 구현된 기능들을 바로 여기 DAO에 구현하면 된다.
AbstarctDAO에 관한 내용은 https://to-dy.tistory.com/27?category=700248 여기를 참고하자!

2-4. board_SQL.xml
1
2
3
4
5
<?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="board">
 
</mapper>
cs
호출할 쿼리가 저장되는 곳이다. 프로젝트에는 기본적으로 여러개의 <mapper>를 가지기 때문에 중복된 이름의 SQL이 존재 할 수 있다. 그래서 각 <mapper>마다 namespace 속성을 이용해서 <mapper>간의 유일성을 보장해야 한다.
- 03행 : board라는 이름의 namespace로 유일성을 보장한다.



3. BoardController.java ("/board/boardList")

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package tody.prj.controller;
 
import java.util.List;
import java.util.Map;
 
import javax.annotation.Resource;
 
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
 
import tody.common.common.CommandMap;
import tody.prj.service.BoardService;
 
@Controller
public class BoardController {
    
    Logger log = Logger.getLogger(this.getClass());
    
    @Resource(name="boardService")
    private BoardService boardService;
    
    @RequestMapping(value="/board/boardList")
    public ModelAndView openBoardList(CommandMap commandMap) throws Exception {
        
        ModelAndView mav = new ModelAndView("/board/boardList");
        
        List<Map<String,Object>> list = boardService.selectBoardList(commandMap);
        mav.addObject("list", list);
        
        return mav;
        
    }
 
}
cs

- 21~22행 : @Resource 어노테이션(Annotation)을 통해서 빈(bean)을 수동으로 등록하고, 그 빈의 이름을 "boardService"라 정한다. Controller에서 Service에 접근하기 위한 선언이다.

- 24행 : 요청 URL를 알려준다. ("/board/boardList") 

- 27행 : 우리가 화면에 보여줄 jsp 파일을 의미한다. 파일의 경로를 써주면 된다.

- 29행 : 게시판 목록을 저장하는 List를 선언한다. List 형식은 Map<String, Object>이다. Key와 Value의 형태로 각 게시글의 정보들이 저장된다. boardService.selectBoardList(commandMap)은 게시글 목록을 조회하는 비즈니스 로직을 호출한다. 이 메서드를 통해 얻어온 결과를 "list"라는 이름에 저장한다.

- 30행 : 서비스 로직의 결과(29행의 list에 담긴 정보)를 ModelAndView 객체에 담아서 jsp에 그 결과를 전송하여 사용하게 한다.


** selectBoardList에 빨간줄이 그어져있더라도 당황하지 말자. 아직 Service에 해당 메서드가 정의되지 않았기 때문이다.

boardService 인터페이스를 만들었다면, selectBoardList에 마우스를 가져다대서 BoardService에 selectBoardList() 메서드를 만들어주자.

(마우스를 가져다 대면, Create method 'selectBoardList(Map<String,Object>)' in type 'BoardService'가 뜰것이다.)



4. BoardService.java

1
2
3
4
5
6
7
8
9
10
11
12
package tody.prj.service;
 
import java.util.List;
import java.util.Map;
 
import tody.common.common.CommandMap;
 
public interface BoardService {
 
    List<Map<String, Object>> selectBoardList(CommandMap commandMap);
 
}
cs

- 10행 : throws Exception을 추가하였다. 



5. BoardServiceImple.java

이제 그러면 BoardServiceImpl.java에서 에러표시가 뜰 것이다. 당황하지 말자.

BoardServiceImpl 클래스는 BoardService 인테페이스를 상속받았기 때문에 BoardService 인터페이스에 있는 selectBoardList 메서드를 구현하라고 알려주는 것이다. 마찬가지로 BoardServiceImpl에 마우스를 가져다대서 selectBoardList 메서드를 구현하자.

(마우스를 가져다 대면, Add unimplemented methods가 뜰 것이다.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package tody.prj.service;
 
import java.util.List;
import java.util.Map;
 
import org.springframework.stereotype.Service;
 
import tody.common.common.CommandMap;
 
@Service("boardService")
public class BoardServiceImpl implements BoardService {
 
    @Override
    public List<Map<String, Object>> selectBoardList(CommandMap commandMap) {
        // TODO Auto-generated method stub
        return null;
    }
 
}
cs

BoardService 인터페이스에서 정의된 메서드를 실제로 구현할 수 있도록 만들어진다. 


BoardSeviceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package tody.prj.service;
 
import java.util.List;
import java.util.Map;
 
import javax.annotation.Resource;
 
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
 
import tody.common.common.CommandMap;
import tody.prj.dao.BoardDAO;
 
@Service("boardService")
public class BoardServiceImpl implements BoardService {
    
    Logger log = Logger.getLogger(this.getClass());
    
    @Resource(name="boardDAO")
    private BoardDAO boardDAO;
 
    @Override
    public List<Map<String, Object>> selectBoardList(CommandMap commandMap) {
        // TODO Auto-generated method stub
        return boardDAO.selectBoardList(commandMap);
    }
 
}
cs

- 19행 : @Resource 어노테이션으로 "boardDAO"이름으로 bean을 수동으로 등록한다. 마찬가지로 Service에서 데이터 접근을 위해 DAO의 객체를 선언한다.

- 25행 : boardDAO클래스의 selectBoardList메서드를 호출하여 그 결과값을 return(반환) 한다.


** 여기도 마찬가지로 selectBoardList에 빨간줄이 그일 것이다. BoardDAO에서 selectBoardList메서드가 구현되지 않았기 때문이다.

똑같이 마우스를 가져다 대서 BoardDAO에 selectBoardList 메서드를 만들어 주자,



6. BoardDAO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package tody.prj.dao;
 
import java.util.List;
import java.util.Map;
 
import org.springframework.stereotype.Repository;
 
import tody.common.common.CommandMap;
import tody.common.dao.AbstractDAO;
 
@Repository("boardDAO")
public class BoardDAO extends AbstractDAO{
 
    @SuppressWarnings("unchecked")
    public List<Map<String, Object>> selectBoardList(CommandMap commandMap) {
        // TODO Auto-generated method stub
        return (List<Map<String,Object>>)selectList("board.selectBoardList", commandMap);
    }
 
}
cs

- 15행 : AbstractDAO를 상속받았기 때문에 selectList를 사용할 수 있다. selectList 메서드의 인자는 쿼리 이름, 쿼리가 실행되는데 필요한 변수로 2가지이다. 

여기서는 'board.selectBoardList' 가 쿼리 이름이고, commandMap이 쿼리 실행 시 필요한 변수들이다. 쿼리 이름은 무엇에 따라 결정 되는 지는 SQL 을 작성할 때 알 수 있다.

- 14행 : 컴파일 시 컴파일 경고를 사용하지 않도록 설정해 주는 것이다. unchecked는 미화인 오퍼레이션과 관련된 경고를 억제한다.



7. board_sql.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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="board">
 
    <select id="selectBoardList" resultType="hashmap" parameterType="hashmap">
        <![CDATA[
            SELECT
                IDX,
                TITLE,
                HIT_CNT,
                CREA_DATE,
                CREA_ID
            FROM
                TB_BOARD
            WHERE
                DEL_CHK = 'N'
            ORDER BY IDX DESC
        ]]>
    </select>
 
</mapper>
cs

- 05행 : <select> 태그를 이용해서 쿼리문이 select문이라는 것을 명시한다. id를 selectBoardList라고 정의하였는데, BoardDAO에서 쿼리 이름을 나타낸다.

- resultType="hashmap" : 쿼리의 결과값이 HashMap 담겨서 반환된다는 것을 의미한다.

- parameterType="hashmap" : 쿼리가 실행될 때 필요한 변수가 HashMap 형태라는 것을 의미한다.

- 6~18행 : 글번호, 제목, 조회수, 작성일자, 작성자를 가져오기 위한 쿼리문이다.



8. BoardList.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
...
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
</head>
<body>
        ...
 
        <div class="container">
              <table class="table">
                  ...
              </thead>
              <tbody>
                  <c:choose>
                      <c:when test="${fn:length(list) > 0 }">
                          <c:forEach items="${list }" var="bList">
                              <tr>
                              <th scope="row">${bList.IDX }</th>
                              <td>${bList.TITLE }</td>
                              <td>${bList.CREA_ID }</td>
                              <td>${bList.CREA_DATE }</td>
                              <td>${bList.HIT_CNT }</td>
                            </tr>
                          </c:forEach>
                      </c:when>
                      <c:otherwise>
                          <tr>
                              <td colspan="5">조회된 결과가 없습니다.</td>
                          </tr>
                      </c:otherwise>
                  </c:choose>
                
              </tbody>
            </table>
            ...           
        </div>
 
</body>
</html>
cs

*** 중요한 부분만 잘랐다.

- 9~10행 : jstl문법을 사용하기위해 정의(?) 한 것이다.

- 22행 : Controller에서 결과를 저장한 list를 mv.addObject를 이용해서 "list"라는 이름으로 mv에 저장한 적이 있다. (mv.addObject("list",list)) 여기서 테이블에 사용할 아이템이 ${list }라고 되어있는데, 이것 바로 우리가 mv에 추가한 그 list 이다. 그 list에 담긴 데이터를 var에 있는 bList라는 변수에 저장한다. forEach문을 통해 반복수행한다.

- 24~28행 : bList 변수에 저장되 데이터를 가져온다. 여기선 쿼리를 실행시켰을 때 나온 데이터의 이름이다.(** 대소문자 구분)



9. 실행

9-1. 톰캣 실행

첫 화면 페이지가 나온다!


9-2. board/boardList

주소창에 board/boardList를 치자. 해당 주소는 Controller에 Mapping URL이다.

이렇게 게시판이 나오면 성공한 것이다! 난 각종 에러와의 싸움끝에 드디어 나왔다ㅠㅠ 흑

지금은 DB에 데이터가 없기때문에 조회된 결과가 없다고 나오는 게 당연하다. 그럼 이제 데이터를 넣고 게시판 목록에 가보자.


9-3. DB 데이터 입력

각자 알아서 데이터를 넣어주자


9-4. 실행

아까처럼 board/boardList 호출하자.

이렇게 입력한 데이터들이 나오면 성공한 것이다! 오예!



댓글을 달아 주세요

  1. 스니 2018.10.11 11:57

    안녕하세요~ 덕분에 로그인 로그아웃 기능도 구현하고 css도 입혔답니다 ㅎㅎ
    이제 목록 만들기를 하고 있는데 전에 올려주신 글에 연결하여 게시판 목록 기능을 구현 중인데
    Type Exception Report
    Message Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
    Description The server encountered an unexpected condition that prevented it from fulfilling the request.
    Exception
    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
    ### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for board.selectBoardList
    ### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for board.selectBoardList
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    Root Cause
    org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
    ### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for board.selectBoardList
    ### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for board.selectBoardList
    org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
    org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371)
    com.sun.proxy.$Proxy4.selectList(Unknown Source)
    org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:198)
    zest.web.common.dao.AbstractDAO.selectList(AbstractDAO.java:57)
    zest.web.dao.BoardDAO.selectBoardList(BoardDAO.java:17)
    zest.web.service.BoardServiceImpl.selectBoardList(BoardServiceImpl.java:25)
    zest.web.controller.BoardController.openBoardList(BoardController.java:29)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    이런 에러가 뜨네요,, 구글링으로 1. mapper id가 다를경우
    - mapper파일(MyBatis의 쿼리문을 등록한 XML파일)에 <select id=''.. 에 id와
    mapper파일에 직접 접근하는 java파일(DAO나 service)에 적어놓은 id값이 다른 경우
    2. Parameter와 bean의 필드명이 틀린 경우
    3. mapper파일(MyBatis의 쿼리문을 등록한 XML파일)에 정의된 네임스페이스(namespace)와
    - mapper파일에 직접 접근하는 java파일(DAO나 service)에서 호출하는 네임스페이스(namespace)가
    다를 경우
    4. MyBatis config파일에 mapper가 정의가 되어 있지 않거나 Spelling이 틀린 경우
    5. mapper에 정의된 namespace 명칭이 같은 Application 내에 중복 될 경우

    확인하라 해서 board_sql.xml이랑 스펠링도 확인했고 namespace 도 확인했는데 자꾸
    board.selectBoardList라는 쿼리가 없다고 에러가 나오네요,, 최대한 해결해보고
    여쭈어보려고 했는데 매번 죄송합니다.. ㅠㅠ

    • BlogIcon #에게 2018.10.11 13:23 신고

      음 이런거는 오타 확률이 높은데 구글링 한거도 다 확인 했는데도 이러는 거면.. board_sql.xml 파일이 context-datasorce에 설정한 경로에 있는 지 확인 해 보시고.. 어노테이션(@Service같은거)도 확인해보셔야... 아 혹시.. db는 one_board 로 되어있는데 sql문엔 tb_board 로 되어 있어서 그런거 같... 이렇게 물어보는 건 환영이랍니당!

    • 스니 2018.10.11 13:57

      SQL에 TB_BOARD로 생성했어요! board_sql.xml파일을 context-datasource에 설정한 경로에 있는 지 확인하라는 말씀을 잘 모르겠습니다 ㅠㅠ 게시판 만들때 context-datasource 는 건드리지 않았어요! 전에 했던 context-datasource db연동 한 것 그대로 있습니다!

    • 스니 2018.10.11 14:03

      <property name="mapperLocations" value="classpath*:/mapper/**/*_sql.xml" />

      매퍼 로케이션은 이렇게 잡았습니다!!

    • 스니 2018.10.11 14:10

      package tody.prj.dao;

      import java.util.List;
      import java.util.Map;

      import org.springframework.stereotype.Repository;

      import tody.common.common.CommandMap;
      import tody.common.dao.AbstractDAO;

      @Repository("boardDAO";)
      public class BoardDAO extends AbstractDAO{

      @SuppressWarnings("unchecked";)
      public List<Map<String, Object>> selectBoardList(CommandMap commandMap) {
      // TODO Auto-generated method stub
      return (List<Map<String,Object>>;)selectList("board.selectBoardList", commandMap);
      }

      }

      혹시 여기서 selectList("board.selectBoardList"
      이 부분을 boardDAO.selectBoardList 이렇게 바꿔야 하나요?

  2. 익명 2018.10.11 14:16

    비밀댓글입니다

    • BlogIcon #에게 2018.10.11 14:18 신고

      앗...?! 이런 몹쓸 스프링ㅋㅋㅋㅋㅋ 저랑 버전이 달라서 그런걸까요..? pom.xml 가보시면 버전 볼 수 있는데 저는 지금 java-verson 을 1.7이고 springframework버전도 3.2.3.release 이에요.!

    • 2018.10.11 14:37

      비밀댓글입니다

    • BlogIcon #에게 2018.10.11 14:57 신고

      에고!! 아니에요!!! 저도 공부하는 거 정리하는 개념으로 올리는 거라서!!!!! 괜찮아요!!! 실수도 많은 몹쓸 글에 잘 따라와 주신것만으로도 너무너무 감사드려요( ´ ▽ ` ).。o♡

    • 2018.10.11 15:00

      비밀댓글입니다

    • BlogIcon #에게 2018.10.11 15:09 신고

      허억!!! 그러쿤요...ㅋㅋㅋㅋㅋㅋㅋㅋ

  3. 스니 2018.10.12 11:45

    글 수정 기능을 구현하려고 하는데 그 흔한 개발자의 개발노트? 이 블로그는 jquery를 사용하는 것 같아서..
    http://gangnam-americano.tistory.com/3?category=976794 이분 글을 보고 따라하려고 하는데,
    이분의 vo가 (❁´▽`❁) #에게 님 RegisterRequest.java 비슷한 것 같아서.. 저 분 글을 보고 따라하려면
    (❁´▽`❁) #에게 회원가입 글에서 처럼 VO 따로, util에 command 객체 담을거 따로따로 구현하면 될까요?

    • BlogIcon #에게 2018.10.12 11:48 신고

      넵~! 그분(흔한 개발자의 개발노트) 글 좋아요! 저도 참고 많이 해요ㅎㅎ 스프링 중에 인정하는 글!!! 제이쿼리 쓰시면 나중에 편해서 쓰는 걸꺼에요! 본인 선택!! 제이쿼리가 아닌 방법도 써보시고, 제이쿼리도 써보시길 추천할게요~! 그리고 지금 쓰는.. 게시판 목록에서 쓴 BoardVO, service 전부 그대로 써서 올리신 링크블로그꺼 따라하시면 될거 같아요~! 스프링 공부 쭉쭉 재밌게 이어가시길 기원할게용!! 저도 얼른 공부하고 정리를.....ㅋㅋ

    • 스니 2018.10.12 12:01

      칼댓글 ㅠㅠ 감사합미당 ♥

      비교하면서 구현하고 있는데 한 가지 궁금한게 있어서요! 저 분 글에서 처럼 boardVO 하나로 하고 싶은데 (❁´▽`❁) #에게님이 리스트에서 만드신 db로 적용을 한다치면 저기에 선언을 idx, pre_idx, title, contents, hit_cnt, del_chk, cre_date, cre_id 다 넣어주면 되나요?

    • BlogIcon #에게 2018.10.12 12:03 신고

      네! VO에는 본인이 만든 DB의 컬럼들을 써주시면 됩니당!!