Spring 게시판 구현(답변글 달기)
1. 시작하기
- 이번에는 답변글 쓰기 기능을 추가하자.
- JSP쪽 /jsp/reply.jsp 파일이 추가된다.
- 답변글 쓰기 로직을 이해하려면 SpringBoardDAO.java에 설명되어 있는 reply, reply_level, reply_step의 의미에 대해 이해 하자.
2. DAO쪽 클래스를 작성하자.
BoardDAO.java 인터페이스, SpringBoardDAO.java 클래스에 답변 글 등록을 위한 replyBoard() 메소드를 추가하자.
소스 코드 중 빨강색 부분이 추가된 부분
[BoardDAO.java]
package onj.board.dao;
import java.util.List;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import org.springframework.dao.DataAccessException;
public interface BoardDAO {
//게시물 리스트 보기
public List<BoardDTO> boardList() throws DataAccessException;
//게시물 본문 미리보기
public String preView(String seq) throws DataAccessException;
//게시물 본문 읽기
public BoardDTO readContent(String seq) throws DataAccessException;
//읽은 글의 조회수 1증가
public int updateReadCount(String seq) throws DataAccessException;
//Comment저장
public int insertComment(CommentDTO commentDTO) throws DataAccessException ;
//Comment조회
public List<CommentDTO> commentList(String seq) throws DataAccessException;
//게시글 입력
public int insertBoard(BoardDTO board) throws DataAccessException;
//글 수정
public int updateBoard(BoardDTO board) throws DataAccessException;
//글 삭제
public int deleteBoard(String sid , String password) throws DataAccessException;
//답글 달기
public int replyBoard(BoardDTO board) throws DataAccessException;
}
[SpringBoardDAO.java]
게시판 리스트보기의 SQL문장이 수정 되었다. 확인 하자.
package onj.board.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class SpringBoardDAO implements BoardDAO {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
// /게시판 전체 리스트 보기(list.html)
public List<BoardDTO> boardList() throws DataAccessException {
List<BoardDTO> boardList = null;
//String sql = "select * from board";
/*
* reply : 답변인경우 어느글의 답변인지 상위글 번호
* 최상위글인 경우 reply는 자신의 글번호(seq)와 동일, 리스트보기에서정령시 우선 reply로 우선하게 된다.
* reply_level : 1차, 2차 답글인지 여부, 하나의 글에 답변이 두개면 그 두답변은 reply_level이 같다.
* list.jsp에서 글을 뿌릴 때 reply_level에 따라 들여쓰기를 한다.
* reply_step : 하나의 글 아래에 생기는 모든 답변들에 대해 순차적으로 1씩 증가, reply_level과 관계없이
*/
String sql = " select * from (select seq, name , passwd, "
+ " title, content, filename, regdate, "
+ " readcount, reply, reply_step, "
+ " reply_level , rownum r "
+ " from board "
+ " order by reply desc , reply_step asc)";
boardList = jdbcTemplate.query(sql, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
BoardDTO board = new BoardDTO();
board.setSeq(rs.getInt("seq"));
board.setName(rs.getString("name"));
board.setPasswd(rs.getString("passwd"));
board.setTitle(rs.getString("title"));
board.setContent(rs.getString("content"));
board.setFileName(rs.getString("filename"));
board.setRegDate(rs.getString("regdate"));
board.setReadCount(rs.getInt("readcount"));
board.setReply(rs.getInt("reply"));
board.setReply_step(rs.getInt("reply_step"));
board.setReply_level(rs.getInt("reply_level"));
return board;
}
});
return boardList;
}
// 게시물 본문내용 미리보기(/preView)
public String preView(String seq) throws DataAccessException {
String sql = "select * from board where seq = ?";
String preContent = (String) jdbcTemplate.queryForObject(sql,
new Object[] { seq }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
return rs.getString("content");
}
});
return preContent;
}
// 게시판 상세보기, 게시글 읽기
public BoardDTO readContent(String seq) throws DataAccessException {
String sql = "select * from board where seq = ?";
BoardDTO boardDTO = (BoardDTO) jdbcTemplate.queryForObject(sql,
new Object[] { seq }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
BoardDTO board = new BoardDTO();
board.setSeq(rs.getInt("seq"));
board.setName(rs.getString("name"));
board.setPasswd(rs.getString("passwd"));
board.setTitle(rs.getString("title"));
board.setContent(rs.getString("content")); board.setFileName(rs.getString("filename")); board.setRegDate(rs.getString("regdate")); board.setReadCount(rs.getInt("readcount"));
board.setReply(rs.getInt("reply"));
board.setReply_step(rs.getInt("reply_step")); board.setReply_level(rs.getInt("reply_level"));
return board;
}
});
// 글 조회수 1증가
this.updateReadCount(new Integer(boardDTO.getSeq()).toString());
return boardDTO;
}
// 읽은 글의 조회수를 1증가
public int updateReadCount(String seq) throws DataAccessException {
String sql = "update board set readcount = nvl(readcount,0) + 1 where seq = ?";
Object[] obj = { seq };
return jdbcTemplate.update(sql, obj);
}
// 커맨트 입력
public int insertComment(CommentDTO commentDTO) throws DataAccessException {
String sql = "insert into comment_t(seq, name, comm) values (?, ?, ?)";
Object[] obj = { commentDTO.getSeq(), // 게시글순번
commentDTO.getName(), // 작성자
commentDTO.getComment() }; // 커맨트
return jdbcTemplate.update(sql, obj);
}
// 커맨트 조회
public List<CommentDTO> commentList(String seq) throws DataAccessException {
String sql = "select * from comment_t where seq = ?";
List<CommentDTO> commentList = jdbcTemplate.query(sql,
new Object[] { seq }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
CommentDTO commentDTO = new CommentDTO();
commentDTO.setName(rs.getString("name"));
commentDTO.setComment(rs.getString("comm"));
return commentDTO;
}
});
return commentList;
}
// 글쓰기
public int insertBoard(BoardDTO board) throws DataAccessException {
String sql = "insert into board values(board_seq.nextval , ? , ? , ? , ? , ? , sysdate , 0 , board_seq.currval , 0 , 0)";
if (board.getFileName() == null) {
Object[] obj = { board.getName(), board.getPasswd(),
board.getTitle(), board.getContent(), "" };
return jdbcTemplate.update(sql, obj);
} else {
Object[] obj = { board.getName(), board.getPasswd(),
board.getTitle(), board.getContent(), board.getFileName() };
return jdbcTemplate.update(sql, obj);
}
}
// 게시글 수정
public int updateBoard(BoardDTO board) throws DataAccessException {
String sql = "update board set title = ? , content = ? where seq = ?";
Object[] obj = { board.getTitle(), board.getContent(), board.getSeq() };
return jdbcTemplate.update(sql, obj);
}
// 게시글 삭제
public int deleteBoard(String seq, String passwd)
throws DataAccessException {
int result = 0;
String sql = "delete from board where seq = ? and passwd = ?";
result = jdbcTemplate.update(sql, new Object[] { seq, passwd });
return result;
}
// 답글달기
public int replyBoard(BoardDTO boardDTO) throws DataAccessException {
int result = 0;
String name = boardDTO.getName();
String passwd = boardDTO.getPasswd();
String title = boardDTO.getTitle();
String content = boardDTO.getContent();
String fileName = boardDTO.getFileName();
int reply = boardDTO.getReply();
int reply_step = boardDTO.getReply_step();
int reply_level = boardDTO.getReply_level();
//현재 답변을 단 게시물 보다 더 높은 스텝의 게시물이 있다면 스텝을 하나씩 상승시킴
String sql1 = "update board set reply_step = reply_step + 1 "
+ "where reply = " + reply + " and reply_step > " + reply_step;
jdbcTemplate.update(sql1);
String sql2 = "insert into board values(board_seq.nextval , ? , ? , ? , ? , ? , sysdate , 0 , ? , ? , ?)";
// reply_step과 reply_level을 1씩 증가시킨 후 내용을 저장
Object[] obj2 = { name, passwd, title, content, fileName, reply, reply_step + 1, reply_level + 1 };
result = jdbcTemplate.update(sql2, obj2);
return 0;
}
}
3. service 쪽 클래스를 만들어 보자.
소스 코드 중 빨강색 부분이 추가된 부분
[BoardService.java]
package onj.board.service;
import java.util.List;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
/*
* 게시판에서 구현할 기능을 인터페이스로 정의
*/
public interface BoardService {
//게시판 리스트 보기
public List<BoardDTO> boardList();
//게시물 미리보기
public String preView(String seq);
//게시판 본문 내용보기, 게시글 읽기
public BoardDTO readContent(String seq);
//커맨트 입력
public int insertComment(CommentDTO commentDTO);
//커맨트 조회
public List<CommentDTO> commentList(String seq);
//게시글 입력
public int insertBoard(BoardDTO board);
//게시글 수정
public int updateBoard(BoardDTO board);
//게시글 삭제
public int deleteBoard(String seq , String passwd);
//답글 등록
public int replyBoard(BoardDTO board);
}
[BoardServiceImpl.java]
package onj.board.service;
import java.util.List;
import onj.board.dao.BoardDAO;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
public class BoardServiceImpl implements BoardService {
private BoardDAO boardDAO;
public void setBoardDAO(BoardDAO boardDAO) {
this.boardDAO = boardDAO;
}
//게시물 리스트 보기
public List<BoardDTO> boardList() {
return boardDAO.boardList();
}
//게시물 본문 내용 미리보기
public String preView(String seq) {
return boardDAO.preView(seq);
}
//게시글 읽기
public BoardDTO readContent(String seq) {
return boardDAO.readContent(seq);
}
//커맨트 입력
public int insertComment(CommentDTO commentDTO) {
return boardDAO.insertComment(commentDTO);
}
//커맨트 조회
public List<CommentDTO> commentList(String seq) {
return boardDAO.commentList(seq);
}
//게시글 입력
public int insertBoard(BoardDTO board) {
return boardDAO.insertBoard(board);
}
//게시글 수정
public int updateBoard(BoardDTO board) {
return boardDAO.updateBoard(board);
}
//게시글 삭제
public int deleteBoard(String seq, String passwd) {
return boardDAO.deleteBoard(seq, passwd);
}
//답글 등록
public int replyBoard(BoardDTO board){
return boardDAO.replyBoard(board);
}
}
4. 이번에는 컨트롤러를 수정하자.
컨트롤러에는 두 개의 메소드가 추가 되는데 reply(), replyok() 이다.
reply() : 게시글 상세보기(글 읽기) 페이지에서 답변 버튼을 클릭 시 호출되어 답변을 원하는 글(원본글)을 내용을 boardService.readContent() 메소드를 통해 얻은 후 /jsp/reply.jsp로 “reply” 라는 이름으로 addObject후 redirect 시킴
replyok() : reply.jsp에서 답변 글 저장을 클릭 시 호출되는 컨트롤러의 메소드
소스 코드 중 빨강색 부분이 추가된 부분
[BoardMultiController.java]
package onj.board.controller;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import onj.board.service.BoardService;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
/*
* MultiActionController는 비슷하거나 관련있는 로직을 수행하는
* 다수의 액션을 가지고 있을 때 사용하는 컨트롤러
* 연관된 요청(Request)를 묶을 때 용이함
*/
public class BoardMultiController extends MultiActionController {
private BoardService boardService;
public void setBoardService(BoardService boardService) {
this.boardService = boardService;
}
// 게시판 리스트 보기, 페이징 기능은 구현 안함
public ModelAndView list(HttpServletRequest req, HttpServletResponse res)
throws Exception {
ModelAndView mv = new ModelAndView("list", "list",
boardService.boardList());
return mv;
}
// 게시글 읽기
public ModelAndView read(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
ModelAndView mav = new ModelAndView("read", "read",
boardService.readContent(seq));
// 해당 글의 커맨트도 함께 내려 보내자.
mav.addObject("comments", boardService.commentList(seq));
return mav;
}
// 커맨트쓰기
public ModelAndView comment(HttpServletRequest req, HttpServletResponse res) {
String seq = req.getParameter("seq");
CommentDTO commentDTO = new CommentDTO();
commentDTO.setSeq(seq);
commentDTO.setName(req.getParameter("name"));
commentDTO.setComment(req.getParameter("comment"));
boardService.insertComment(commentDTO);
return new ModelAndView("redirect:/read.html?seq=" + seq);
}
// 새글(게시글) 입력
public ModelAndView write(HttpServletRequest req, HttpServletResponse res)
throws Exception {
MultipartRequest multi = new MultipartRequest(req,
"c:\\java\\project\\onjboard1\\upload", 5 * 1024 * 1024,
"euc-kr", new DefaultFileRenamePolicy());
Enumeration formNames = multi.getFileNames();
String formName = (String) formNames.nextElement();
String fileName = multi.getFilesystemName(formName);
String name = multi.getParameter("name");
String passwd = multi.getParameter("passwd");
String title = multi.getParameter("title");
String content = multi.getParameter("content");
BoardDTO board = new BoardDTO(name, passwd, title, content, fileName);
boardService.insertBoard(board);
return new ModelAndView("redirect:/list.html");
}
// 게시글 수정
public ModelAndView update(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
String name = req.getParameter("name");
String passwd = req.getParameter("passwd");
String title = req.getParameter("title");
String content = req.getParameter("content");
BoardDTO board = new BoardDTO(name, passwd, title, content, "");
board.setSeq(Integer.parseInt(seq));
boardService.updateBoard(board);
return new ModelAndView("redirect:/read.html?seq="
+ req.getParameter("seq"));
}
// 게시글 삭제
public ModelAndView delete(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
String passwd = req.getParameter("passwd");
int result = boardService.deleteBoard(seq, passwd);
if (result != 1) {
PrintWriter out = res.getWriter();
out.println("<script>alert('password not correct');</script>");
out.println("<script>history.go(-1);</script>");
return null;
} else {
return new ModelAndView("redirect:/list.html");
}
}
// 게시물상세보기에서 답변 클릭시 호출되어 답변을 달 reply.jsp로 연결
public ModelAndView reply(HttpServletRequest req, HttpServletResponse res) throws Exception {
String seq = req.getParameter("seq");
// 답변달 게시물 내용을 reply.jsp 넘긴다.
ModelAndView mav = new ModelAndView("reply", //view이름
"reply", //readContent가 넘기는 boardDTO의 이름, reply.jsp에서 사용
boardService.readContent(seq));
return mav;
}
// 답글 저장
public ModelAndView replyok(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
String name = req.getParameter("name");
String passwd = req.getParameter("passwd");
String title = req.getParameter("title");
String content = req.getParameter("content");
String fileName = "";
String reply = req.getParameter("reply");
String reply_step = req.getParameter("reply_step");
String reply_level = req.getParameter("reply_level");
BoardDTO boardDTO = new BoardDTO(name, passwd, title, content, fileName);
boardDTO.setSeq(Integer.parseInt(seq));
boardDTO.setReply(Integer.parseInt(reply));
boardDTO.setReply_level(Integer.parseInt(reply_level));
boardDTO.setReply_step(Integer.parseInt(reply_step));
boardService.replyBoard(boardDTO);
return new ModelAndView("redirect:/list.html");
}
}
5. read.jsp를 수정하자.
답변 버튼을 클릭 시 이동할 주소 확인!
[read.jsp]
<%@ page contentType="text/html; charset=euc-kr" language="java" errorPage="" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>게시물 읽기</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script>
function write_ok(){
writeform.submit();
}
function update_ok(){
document.viewform.action = '/onjboard1/update.html';
document.viewform.submit();
}
</script>
</head>
<body>
<div style="width:600px;">
<div style="float:enter;">
<table width="600" height="420" border="1" align="center">
<tr height="20"><h2>오엔제이프로그래밍실무교육센터 게시판</h2></tr>
<form name="viewform" method="post">
<input type="hidden" name="seq" value="${read.seq}">
<input type="hidden" name="reply" value="${read.reply}">
<input type="hidden" name="reply_step" value="${read.reply_step}">
<input type="hidden" name="reply_level" value="${read.reply_level}">
<tr>
<td width="100">* 이름</td>
<td width="500">: <input name="name" type="text" value="${read.name}" size="50" readonly>
</td>
</tr>
<tr>
<td>* 제목</td>
<td>:
<input name="title" type="text" value="${read.title}" size="50" ></td>
</tr>
<tr align="center">
<td colspan="2"><textarea name="content" cols="80" rows="12" >${read.content}</textarea></td>
</tr>
<tr>
<td>* 파일</td>
<td>: <c:choose>
<c:when test="${read.fileName != null}">
${read.fileName}
</c:when>
<c:when test="${read.fileName == null}">
파일 없음
</c:when>
</c:choose>
</td>
</tr>
<tr>
<td> </td>
<td><input name="button" type="button"on_click="location.href='/onjboard1/reply.html?seq=${read.seq}'" value="답변">
|
<input name="button" type="button" on_click="update_ok()" value="수정">
<input name="button" type="button"on_click="location.href='/onjboard1/jsp/delete.jsp?seq=${read.seq}'" value="삭제">
|
<input name="button" type="button" on_click="location.href='/onjboard1/list.html'" value="목록"></td>
</tr>
</form>
<tr>
<td height="99" colspan="2">
<!-- BoardMultiController의 comment() 메소드 호출 -->
<form method="post" action="comment.html">
<table border="1">
<tr>
<td>이름 : </td>
<td><input type="text" name="name"></td>
<td>코멘트:</td>
<td><input type="text" name="comment"></td>
<td><input type="submit" name="Button" value="쓰기"></td>
</tr>
</table>
<input type="hidden" name="seq" value="${read.seq}">
</form>
<!-- 달려있는 커맨트 보기 -->
<table width="789" border="1">
<c:forEach var="comment" items="${comments}">
<tr>
<td width="42" align="center">*</td>
<td width="86">${comment.name}</td>
<td width="639">${comment.comment}</td>
</tr>
</c:forEach>
</table>
</td>
</tr>
</table>
<br><br>
<table><tr><td><tr><b>http://www.onjprogramming.co.kr</tr></td></tr></table>
</div>
</div>
</body>
</html>
6. /jsp/reply.jsp 작성.
[reply.jsp]
<%@ page contentType="text/html; charset=euc-kr" language="java" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>답변 달기</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script>
function write_ok(){
if(document.form.name.value == ""){
alert("이름을 입력하세요.");
document.form.name.focus();
return false;
}
if(document.form.title.value == ""){
alert("제목을 입력하세요.");
document.form.title.focus();
return false;
}
if(document.form.content.value == ""){
alert("내용을 입력하세요.");
document.form.content.focus();
return false;
}
if(document.form.passwd.value == ""){
alert("비밀번호를 입력하세요.");
document.form.passwd.focus();
return false;
}
form.submit();
}
</script>
</head>
<body>
<div style="width:600px;">
<form method="post" name="form" action="/onjboard1/replyok.html">
<table><tr><td><h2>오엔제이프로그래밍실무교육센터 게시판(답글달기)</h2><tr><td></table>
<table width="600" height="277" border="1" align="center">
<tr>
<td width="120">* 이름</td>
<td width="480">: <input name="name" type="text" size="50"></td>
</tr>
<tr>
<td>* 제목</td>
<td>:
<input name="title" type="text" value="Re: ${reply.title}" size="50"></td>
</tr>
<tr align="center">
<td colspan="2"><textarea name="content" cols="80" rows="10">${reply.content}</textarea></td>
</tr>
<tr>
<td>* 비밀번호</td>
<td>:
<input type="password" name="passwd"></td>
</tr>
<tr>
<td> </td>
<td><input type="button" value="답변" on_click="write_ok();"> |
<input type="button" value="취소" on_click="history.back();"></td>
</tr>
</table>
<input type="hidden" name="seq" value="${reply.seq}">
<input type="hidden" name="reply" value="${reply.reply}">
<input type="hidden" name="reply_step" value="${reply.reply_step}">
<input type="hidden" name="reply_level" value="${reply.reply_level}">
</form>
</div>
<br><br>
<table><tr><td><tr><b>http://www.onjprogramming.co.kr</tr></td></tr></table>
</body>
</html>
7. action-servlet.xml을 수정하자.
소스 코드 중 빨강색 부분이 추가된 부분
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@127.0.0.1:1521:onj</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<!-- 넘어오는 URL에 따라 컨트롤러에서 실행될 메소드 매핑 -->
<!-- PropertiesMethodNameResolver는 prop key로 넘어오는 url에 대해 실행할 컨트롤러의 메소드
정의 -->
<bean id="userControllerMethodNameResolver"
class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<!-- list.html 요청이 오면 컨트롤러의 list 메소드 실행 -->
<prop key="/list.html">list</prop>
<!-- read.html 요청이 오면 컨트롤러의 read 메소드 실행 -->
<prop key="/read.html">read</prop>
<!-- comment.html 요청이 오면 컨트롤러의 comment 메소드 실행 -->
<prop key="/comment.html">comment</prop>
<!-- write.html 요청이 오면 컨트롤러의 write 메소드 실행 -->
<prop key="/write.html">write</prop>
<!-- update.html 요청이 오면 컨트롤러의 update 메소드 실행 -->
<prop key="/update.html">update</prop>
<!-- delete.html 요청이 오면 컨트롤러의 delete 메소드 실행 -->
<prop key="/delete.html">delete</prop>
<!-- reply.html 요청이 오면 컨트롤러의 reply 메소드 실행 -->
<prop key="/reply.html">reply</prop>
<!-- replyok.html 요청이 오면 컨트롤러의 replyok 메소드 실행 -->
<prop key="/replyok.html">replyok</prop>
</props>
</property>
</bean>
<!-- 뷰 리졸버 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!-- 컨트롤러 매핑 -->
<bean name="/list.html /read.html /comment.html /write.html
/update.html /delete.html /reply.html /replyok.html"
class="onj.board.controller.BoardMultiController">
<property name="methodNameResolver">
<ref local="userControllerMethodNameResolver" />
</property>
<property name="boardService">
<ref bean="boardService" />
</property>
</bean>
</beans>
실행결과
(게시판 리스트보기 + 게시물 본문내용 미리 보기 + 게시글 상세보기 + 커멘트기능 + 글쓰기 + 글 수정하기 + 글 삭제하기 + 답글달기)
[출처] 오라클자바커뮤니티 - http://www.oraclejavanew.kr/bbs/board.php?bo_table=LecSpring&wr_id=256
오라클자바커뮤니티
추천 개발 실무 강좌 - 개인80% 환급
Spring3.X, MyBatis, Hibernate실무과정
| 강좌명 | Spring3.X, MyBatis, Hibernate실무과정(평일야간) 오라클자바커뮤니티(www.oraclejavanew.kr) 추천 실전강좌 |
|---|---|
| 교재 | 자체교재 or PDF 파일 제공 |
| 강좌 일정 | 09월12일(목) ~ 10월04일(금)((평일야간) 19:00~22:00, 12일) 총 36시간 |
| 강의 장소 | [C강의장]구로디지털단지역2번 출구-> 미니스톱끼고 우회전 -> 100m 직진
후 골목길 끝에서 이마트방향 우회전 -> 50m 직진 후 우체국 옆골목으로 길건너서 직진 -> 150미터 직진 후 JnK 타워에서
우회전 -> 50미터 직진 후 우측에 코오롱빌란트2차 803호 (구로구 구로3동 222-8 코오롱디지털타워 빌란트2차 803호) [약도보기] |
| 수강절차 | - 강좌내용 확인 - 전화 또는 홈페이지(www.onjprogramming.co.kr)를 통한 수강지원 및 수강료 결제(무통장입금, 온라인 카드결제) - 고용보험 가입자(재직자)인 경우 고용보험환급 관련 서류 제출 - 수강전 : 커리큘럼 및 장소에 대해 다시 한번 공지 - 교육 전 설문 작성(간단한 개발 경력, 수강 목적, 강좌진행방식 등) - 강좌 수강 - 수강후 : 교육 후 설문 작성 |
| 수강료 | - 590,000원 [고용주환급]대기업:14만원 전후, 중소기업:187,047 원환급 [개인수강지원(개인환급)]정규직 472,000 ,비정규직:전액환급 대기업(상시근로자 300인 이상 대기업)은 개인환급 불가합니다. 재직자 내일배움카드 : 정부지원금 80% 자기부담금 20% (구 능력개발카드 명칭이 내일배움카드로 변경 / 연간 총한도 200만원) * 휴강 :법정공휴일 |
| 수강료 입금안내 |
- 온/오프라인 카드결제, 계좌이체(수강안내->입금안내 참조) |
| 문의사항 | 02-851-4790 번으로 연락 부탁 드립니다. |
| 교육개요 | 본과정은 자바 웹개발에서 가장 많이 사용되고 있는 자바기반 프레임워크인 Spring3.2를 학습하는데 스프링이 왜 도입되어야 하는지부터,
기본모듈구성, 아키텍처 DI, DL, IoC, 최근 개발모델의 핵심인 Spring AOP, AspectJ Annotation, 표현언어인
SpEL, Spring MVC, Spring MVC TEST Framework, Spring WebFlow, Spring JDBC, Spring
Transaction등 개발에 필요한 부분을 체계적으로 실습을 통해 학습하며 SQLMapper인 MyBatis, Hibernate 까지 학습하는
Spring 최고의 교육 입니다. [특징] - 실무/실습에 근거한 이론 취득 - 단기간에 스프링 개발자로 양성 - 문답씩 수업으로 수강 효과 극대화 - 이론/실습 과제로 인한 개발력 UP |
| 교육목표 | - Spring의 도입배경 및 아키텍처에 대해 이해한다. (자바빈의 태동부터 EJB, 그리고 현재까지) - Eclipse, Maven, STS 플러그인에 대한 이해 (개발환경 설정의 이해) - Spring IoC(DI, DL)의 이해 (실습을 통한 setter,getter,constructor injection의 이해) - Spring AOP의 이해 (실습을 통한 Spring AOP의 이해, AOP어렵지 않습니다) - AspectJ Annotation에 대한 이해 (Spring의 AspectJ 지원 및 Annotation 대한 이해 by 실습) - Spring Web MVC, JDBC의 이해 (실습을 통한 Spring MVC, JDBC의 이해) - Spring Controller에 대한 이해 (간단한 Controller의 구현을 통한 MVC Font Contrller의 이해) - Spring Web Flow에 대한 이해 (실습을 통한 Spring Web Flow 및 JSF에 대한 이해) - SpEL에 대한 이해 (실습을 통한 Spring SpEL의 이해) - Servlet3 비동기 요청에 대해 이해한다. (실습을 통한 비동기 서블릿에 대한 이해) - MyBatis Mapper에 대해 이해한다. (실습을 통한 MyBatis 구성, 작동원리 이해) - Hibernate Mapper에 대해 이해한다. (실습을 통한 Hibernate 구성, 작동원리 이해) - 실무 개발 환경에 적응력 UP (Spring, MyBATIS 기반 게시판 작성) |
| 교육대상 | - JAVA, JSP 개발자 - 자바개발은 오래 했지만 프레임워크에 대해 자신이 없는 개발자 - 단기간에 스프링을 박살 내고 싶은 개발자. (스프링 혼자 공부하기는 어렵습니다!!) |
| 선수학습 | - JAVA, JSP |
| Spring3.2 | J2EE Framework에 대한 흐름과 Spring Framework에 대한 이해 개발 환경 설정(Eclipse4.3 KEPLER, Tomcat7, Spring3.2 다운로드 및 설치) Maven, STS 플러그인 설치 Spring IoC DL(Dependency LookUp) &DI(Dependency Injection) Dependency Pull, CDL(Contaxtualized Lookup) Setter/Constructor/Mathod Injection Spring 설정 Spring AOP 란 ?Code, Advice, JoinPoint, PointCut, Aspect, WeavingProxyFactoryBean Annotation기반 AOP(AspectJ) 기타 Spring의 선언적 AOP 선언 Spring JDBC Spring MVC Spring Controller Spring Webflow, JSF Spring 표현언어 SpEL Servlet3 비동기 요청처리 Spring3.2 Transaction 관리 Spring MVC TEST Framework |
|---|---|
| MyBatis/hibernate | [MyBatis] 개요 및 소개 개발환경 설정 및 설치 Data Mapper란 sqlMapConfig 이해 및 환경설정 Spring, MyBatis 연동 SQL Map XML File 이해 SqlMapClient 이해 SQL의 실행(Insert/update/delete) 이해와 실습 고급 쿼리 사용방법의 이해와 실습 Spring MyBatis 응용예제 작성 [Hibernate] Hibernate 소개 SessionFactory 설정 1:1, 1:다 매핑 Session Interface Hibernate DML Spring, Hibernate 예제 프로그램 작성 |
댓글 없음:
댓글 쓰기