1. 시작하기
이번
강좌부터는 Spring Framework3.2 게시판 작성 2단계로서 스프링 주입(DI)을
애노테이션으로 변경해 보자. Spring Framework XML설정 파일이 깔끔해 진다.
2. BoardDAOImple.java
package com.board.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import com.board.model.BoardDTO;
import com.board.model.CommentDTO;
@Component("boardDAO")
public class BoardDAOImple implements BoardDAO {
@Autowired
private DataSource
dataSource;
public JdbcTemplate
getTemplate(){return new JdbcTemplate(dataSource);}
// 게시글 수
public int
boardCount(Map<String, Object>searchMap)throws DataAccessException{
int count =
0;
String sql =
"";
if(searchMap.get("boardListSearchText") == null ||
searchMap.get("boardListSearchText").equals("")){
sql = "select
count(*) from board02";
count = getTemplate().queryForObject(sql,
Integer.class
);
}else{
String
boardListSelect = (String) searchMap.get("boardListSelect");
String
boardListSearchText = (String) searchMap.get("boardListSearchText");
sql = "select
count(*) from board02 where "+boardListSelect+" like
'%"+boardListSearchText+"%'";
count =
getTemplate().queryForObject(sql,Integer.class);
}
return
count;
}
// 게시판 리스트
public
List<BoardDTO> boardList(Map<String, Object>searchMap) throws
DataAccessException {
List<BoardDTO> boardList = null;
String sql =
"";
Object[]
obj;
if(searchMap.get("boardListSearchText") == null ||
searchMap.get("boardListSearchText").equals("")){
sql = "select *
from ("
+ " select ROWNUM r,seq
,name,title ,TO_CHAR(regdate,'YYYY/MM/DD')as regdate, readcount,"
+ " reply, reply_step,
reply_level "
+ " from "
+ " (select * from board02
"
+ " order by reply desc,
reply_step asc"
+ " )"
+ " )"
+ " where r BETWEEN ? AND
?";
obj = new
Object[] {searchMap.get("startRow"),searchMap.get("endRow")};
}else{
String
boardListSelect = (String) searchMap.get("boardListSelect");
String
boardListSearchText = (String) searchMap.get("boardListSearchText");
sql = "select *
from ("
+ " select ROWNUM r,seq
,name,title ,TO_CHAR(regdate,'YYYY/MM/DD')as regdate, readcount, "
+ " reply, reply_step,
reply_level "
+ " from "
+ " (select * from board02
"
+ " where "
+ " "+boardListSelect+" like
'%"+boardListSearchText+"%'"
+ " order by reply desc,
reply_step asc"
+ " )"
+ " )"
+ " where r BETWEEN ? AND
?";
obj = new
Object[] {searchMap.get("startRow"),searchMap.get("endRow")};
}
boardList
= getTemplate().query(sql,
obj,
new
RowMapper<BoardDTO>(){
public BoardDTO
mapRow(ResultSet rs, int rowNum)throws SQLException{
BoardDTO boardDTO = new
BoardDTO(rs.getString("seq"),
rs.getString("name"),
rs.getString("title"),
rs.getString("regdate"),
rs.getInt("readcount"),
rs.getInt("reply_step"),
rs.getInt("reply_level")
);
return boardDTO;
}
});
return
boardList;
}
// 게시물 본문내용 미리보기
public String
preView(String seq) throws DataAccessException{
String sql =
"select content from board02 where seq = ?";
String
preContent = "";
Object obj[] =
{seq};
preContent
= getTemplate().queryForObject(sql,obj,String.class);
return
preContent;
}
// 게시글 조회수 1씩증가
public int
updateReadCount(String seq)throws DataAccessException{
String sql = "
update board02 set readcount = nvl(readcount,0)+1 where seq = ?";
Object[] obj =
{seq};
return getTemplate().update(sql,obj);
}
// 게시글 상세보기
public BoardDTO
readContent(String seq)throws DataAccessException{
// 조회수 1증가 메소드 호출
this.updateReadCount(seq);
String sql =
"select * from board02 where seq = ?";
Object[] obj =
{seq};
BoardDTO
boardDTO = getTemplate().queryForObject(sql,
obj,
new
RowMapper<BoardDTO>() {
public BoardDTO
mapRow(ResultSet rs,int rowNum)throws SQLException {
BoardDTO
boardDTO = new BoardDTO();
boardDTO.setSeq(rs.getString("seq"));
boardDTO.setName(rs.getString("name"));
boardDTO.setPasswd(rs.getString("passwd"));
boardDTO.setTitle(rs.getString("title"));
boardDTO.setContent(rs.getString("content"));
boardDTO.setFilename(rs.getString("filename"));
boardDTO.setRegdate(rs.getString("regdate"));
boardDTO.setReadcount(rs.getInt("readcount"));
boardDTO.setReply(rs.getString("reply"));
boardDTO.setReply_step(rs.getInt("reply_step"));
boardDTO.setReply_level(rs.getInt("reply_level"));
return
boardDTO;
}
});
return
boardDTO;
}
// 코멘트 저장
public int
insertComment(CommentDTO commentDTO) throws DataAccessException {
String sql =
"insert into comment_t02 values(sequence_comment_seq.nextval,?,?,?)";
Object[] obj =
{commentDTO.getComment_name(),commentDTO.getComment_comm(),commentDTO.getSeq()};
return getTemplate().update(sql,
obj);
}
// 코멘트 조회
public
List<CommentDTO> ListComment(String seq) throws DataAccessException
{
String sql =
"select * from comment_t02 where seq = ? order by comment_seq desc";
Object[] obj =
{seq};
List<CommentDTO> list = getTemplate().query(sql,
obj,
new
RowMapper<CommentDTO>(){
public
CommentDTO mapRow(ResultSet rs,int rowNum)throws SQLException {
CommentDTO
commentDTO = new CommentDTO();
commentDTO.setComment_seq(rs.getString("comment_seq"));
commentDTO.setComment_name(rs.getString("comment_name"));
commentDTO.setComment_comm(rs.getString("comment_comm"));
commentDTO.setSeq(rs.getString("seq"));
return
commentDTO;
}
});
return
list;
}
// 게시글 입력
public int
insertBoard(BoardDTO boardDTO)throws DataAccessException{
String sql =
"insert into board02
values(sequence_board_seq.nextval,?,?,?,?,?,sysdate,0,sequence_board_seq.currval,0,0)";
Object[] obj =
{boardDTO.getName(), boardDTO.getPasswd(),
boardDTO.getTitle(),boardDTO.getContent(), boardDTO.getFilename()};
return getTemplate().update(sql,
obj);
}
// 글 수정
public int
updateBoard(BoardDTO boardDTO)throws DataAccessException{
String sql =
"update board02 set name = ? ,title = ?,content = ? where seq = ?";
Object[] obj =
{
boardDTO.getName(),
boardDTO.getTitle(),
boardDTO.getContent(),
boardDTO.getSeq()
};
return getTemplate().update(sql,obj);
}
// 게시글 삭제
public int
deleteBoard(BoardDTO boardDTO)throws DataAccessException{
String sql =
"";
// reply_revel이 0이면 본글 이고, 1이상이면 답변글
if(boardDTO.getReply_level() == 0){
sql = "delete
from board02 where reply = ?";
}else{
sql = "delete
from board02 where seq = ?";
}
Object[] obj =
{boardDTO.getSeq()};
// 코멘트 전체 삭제
this.AllDeleteComment(boardDTO.getSeq());
return getTemplate().update(sql,obj);
}
// 코멘트 전체 삭제
public int
AllDeleteComment(String seq)throws DataAccessException{
String sql =
"delete from comment_t02 where seq = ?";
Object[] obj =
{seq};
return getTemplate().update(sql,obj);
}
// 답글 달기
public int
replyBoard(BoardDTO boardDTO)throws DataAccessException{
// 현재 답변을 단 게시물 보다 더 높은 스텝의 게시물이 잇다면 스텝을 하나씩
상승시킴.
String sql1
="update board02 set reply_step = reply_step + 1 "
+ "where
reply = ? and reply_step > ?";
Object[] obj1
={boardDTO.getReply(),boardDTO.getReply_step()};
getTemplate().update(sql1, obj1);
// reply_step과 reply_level을 1씩 증가시킨 후 내용을 저장
String sql2 =
"insert into board02
values(sequence_board_seq.nextval,?,?,?,?,?,sysdate,0,?,?,?)";
Object[] obj2
={boardDTO.getName(),boardDTO.getPasswd(),boardDTO.getTitle(),boardDTO.getContent(),boardDTO.getFilename(),
boardDTO.getReply(),boardDTO.getReply_step()+1,boardDTO.getReply_level()+1};
return getTemplate().update(sql2,
obj2);
}
}
3. BoardServiceImple.java
package com.board.service;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.board.dao.BoardDAO;
import com.board.model.BoardDTO;
import com.board.model.CommentDTO;
@Component("boardService")
public class BoardServiceImple implements BoardService {
@Autowired
private BoardDAO
boardDAO;
// 게시글 수
public int
boardCount(Map<String, Object> searchMap) throws Exception {
return
boardDAO.boardCount(searchMap);
}
// 게시판 리스트
public
List<BoardDTO> boardList(Map<String, Object> searchMap) throws
Exception {
return
boardDAO.boardList(searchMap);
}
// 게시물
미리보기
public String
preView(String seq){
return
boardDAO.preView(seq);
}
// 게시글
상세보기
public BoardDTO
readContent(String seq)throws Exception{
return
boardDAO.readContent(seq);
}
// 코멘트 저장
public int
insertComment(CommentDTO commentDTO) throws Exception {
return
boardDAO.insertComment(commentDTO);
}
// 코멘트 조회
public
List<CommentDTO> ListComment(String seq) throws Exception {
return
boardDAO.ListComment(seq);
}
// 게시글 입력
public int
insertBoard(BoardDTO boardDTO)throws Exception{
return
boardDAO.insertBoard(boardDTO);
}
// 게시글 수정
public int
updateBoard(BoardDTO boardDTO)throws Exception{
return
boardDAO.updateBoard(boardDTO);
}
// 게시글 삭제
public int
deleteBoard(BoardDTO boardDTO)throws Exception{
return
boardDAO.deleteBoard(boardDTO);
}
// 답글 등록
public int
replyBoard(BoardDTO boardDTO)throws Exception{
return
boardDAO.replyBoard(boardDTO);
}
}
4. PageHandler.java
package com.board.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.board.dao.BoardDAO;
@Component("pageHandler")
public class PageHandler {
@Autowired
private BoardDAO
boardDAO;
// 페이지 사이즈, 페이지
그룹
private final
int PAGESIZE = 3;
private final
int PAGEGROUP = 5;
// 전체 게시글
수
public int
boardAllNumber(Map<String, Object>searchMap)throws Exception{
int count =
boardDAO.boardCount(searchMap);
return
count;
}
// 페이지 갯수
public int
boardPageCount(Map<String, Object>searchMap)throws Exception{
int pageCount =
boardAllNumber(searchMap) / PAGESIZE;
if(boardAllNumber(searchMap) % PAGESIZE
!=0){pageCount++;}
return
pageCount;
}
//
startPage
public int
boardStartPage(int pageNum)throws Exception{
int startPage =
(pageNum - 1) / PAGEGROUP * PAGEGROUP +1;
return
startPage;
}
// endPage
public int
boardEndPage(int pageNum, Map<String, Object>searchMap)throws
Exception{
int endPage =
boardStartPage(pageNum)+ (PAGEGROUP-1);
if(endPage >
boardPageCount(searchMap)){ endPage = boardPageCount(searchMap); }
return
endPage;
}
// 처음, 마지막
rowNumber
public
List<Object> boardSetPageNumber(int pageNum)throws Exception{
List<Object> list = new
ArrayList<Object>();
int endRow =
PAGESIZE*pageNum;
int startRow =
endRow - PAGESIZE+1;
list.add(startRow);
list.add(endRow);
return
list;
}
}
5. BoardMultiController.java
package com.onj.board;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import
org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.board.model.BoardDTO;
import com.board.model.CommentDTO;
import com.board.service.BoardService;
import com.board.util.EncodingHandler;
import com.board.util.PageHandler;
@Controller
@SessionAttributes("boardDTO")
public class BoardMultiController extends MultiActionController{
@Autowired
private BoardService
boardService;
@Autowired
private PageHandler
pageHandler;
ModelAndView mav
= null;
// 게시판 리스트
@RequestMapping("/list.html")
public
ModelAndView list(SessionStatus
sessionStatus,String pageNumber ,String boardListSelect, String
boardListSearchText)throws Exception{
mav = new
ModelAndView();
// 상세보기에서 사용한 session 지운다.
sessionStatus.isComplete();
List<BoardDTO> list = null;
Map<String,
Object> searchMap = new HashMap<String, Object>();
if(boardListSearchText != null){
searchMap.put("boardListSearchText",
EncodingHandler.toKor(boardListSearchText));
searchMap.put("boardListSelect",
boardListSelect);
mav.addObject("boardListSearchText",
EncodingHandler.toKor(boardListSearchText));
mav.addObject("boardListSelect",
boardListSelect);
}
int pageNum =
1;
if(pageNumber !=
null){pageNum = Integer.parseInt(pageNumber);}
// 게시글 수
int totalCount =
pageHandler.boardAllNumber(searchMap);
// 페이지 갯수
int
totalPageCount = pageHandler.boardPageCount(searchMap);
// startPage ,
endPage
int startPage =
pageHandler.boardStartPage(pageNum);
int endPage =
pageHandler.boardEndPage(pageNum,searchMap);
// 처음, 마지막
rowNumber
List<Object> rowNumberList = new
ArrayList<Object>();
rowNumberList =
pageHandler.boardSetPageNumber(pageNum);
searchMap.put("startRow",
rowNumberList.get(0));
searchMap.put("endRow", rowNumberList.get(1));
// 글 전체 출력
list =
boardService.boardList(searchMap);
mav.addObject("pageNumber",pageNum);
mav.addObject("boardCount",totalCount);
mav.addObject("totalPageCount",
totalPageCount);
mav.addObject("startPage", startPage);
mav.addObject("endPage", endPage);
mav.addObject("list", list);
mav.setViewName("list");
return
mav;
}
// 게시글
상세보기
@RequestMapping("/read.html")
public
ModelAndView read(String
seq,String mas)throws Exception{
mav = new
ModelAndView();
BoardDTO
boardDTO = boardService.readContent(seq);
if(mas !=
null){
mav.addObject("mas",mas);
}
// 상세글 내용
session에 담음
mav.addObject("boardDTO",boardDTO);
mav.addObject("comment",
boardService.ListComment(seq));
mav.setViewName("read");
return
mav;
}
// 코멘트 저장
@RequestMapping("/comment.html")
public
ModelAndView comment(CommentDTO
commentDTO, @ModelAttribute("boardDTO")BoardDTO boardDTO)throws
Exception{
mav = new
ModelAndView("redirect:/read.html?seq="+boardDTO.getSeq());
commentDTO.setSeq(boardDTO.getSeq());
boardService.insertComment(commentDTO);
return
mav;
}
// 게시글 입력 화면
@RequestMapping("/write.html")
public
ModelAndView write()throws Exception{
mav = new
ModelAndView("write");
return
mav;
}
// 입력된 글 저장
@RequestMapping("/writeOk.html")
public
ModelAndView writeOk(BoardDTO
boardDTO, MultipartFile file)throws Exception{
mav = new
ModelAndView("redirect:/list.html");
// 파일이름
String fileName =
file.getOriginalFilename();
// 파일 저장
위치
String fileDir
="D:/upload/";
byte[]
fileData;
FileOutputStream
output = null;
if(!fileName.equals("")){
// 파일 저장
try{
fileData =
file.getBytes();
output = new
FileOutputStream(fileDir+fileName);
output.write(fileData);
}catch(IOException e){
e.printStackTrace();
}finally{output.close();
}
}else{fileName =
" ";}
boardDTO.setFilename(fileName);
boardService.insertBoard(boardDTO);
return
mav;
}
// 게시글 수정페이지 이동
@RequestMapping("/updatePage.html")
public
ModelAndView updatePageGo(@ModelAttribute("boardDTO")BoardDTO
boardDTO)throws Exception{
mav = new
ModelAndView("update", "boardDto",boardDTO);
return
mav;
}
// 게시글 수정
@RequestMapping("/update.html")
public
ModelAndView update(@ModelAttribute("boardDTO")BoardDTO
dto, BoardDTO boardDTO)throws Exception{
boardDTO.setSeq(dto.getSeq());
boardService.updateBoard(boardDTO);
mav = new
ModelAndView("redirect:/read.html?seq="+boardDTO.getSeq());
return
mav;
}
// 게시글 삭제
@RequestMapping("/delete.html")
public
ModelAndView delete(@ModelAttribute("boardDTO")BoardDTO
boardDTO, String deletePasswd)throws Exception{
mav = new
ModelAndView();
if(boardDTO.getPasswd().equals(deletePasswd)){
boardService.deleteBoard(boardDTO);
mav.setViewName("redirect:/list.html");
}else{
String mas="비밀번호가 일치하지
않습니다.";
mav.setViewName("forward:/read.html?
seq="+boardDTO.getSeq()+"&mas="+mas);
}
return
mav;
}
// 답글 입력페이지
@RequestMapping("/reply.html")
public
ModelAndView reply(@ModelAttribute("boardDTO")BoardDTO
boardDTO)throws Exception{
mav = new
ModelAndView("reply","reply",boardDTO);
return
mav;
}
// 답글 저장
@RequestMapping("/replyOk.html")
public
ModelAndView replyOk(@ModelAttribute("boardDTO")BoardDTO
dto, BoardDTO boardDTO)throws Exception{
boardDTO.setTitle("re:"+boardDTO.getTitle());
boardDTO.setFilename(" ");
boardService.replyBoard(boardDTO);
mav = new
ModelAndView("redirect:/list.html");
return
mav;
}
}
6.
/WEB-INF/spring/appServlet/servlet-context.xml
<?xml version="1.0"
encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- DispatcherServlet Context: defines this
servlet's request-processing infrastructure -->
<!-- com.onj.board 패키지의 Class들을 Scan한다.
[Controller]-->
<context:component-scan
base-package="com.onj.board" />
<!-- Enables the Spring MVC @Controller programming model
-->
<annotation-driven
/>
<!-- Handles HTTP GET requests for /resources/**
by efficiently serving up static resources in the ${webappRoot}/resources
directory -->
<resources mapping="/resources/**"
location="/resources/" />
<beans:bean
id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName"
value="oracle.jdbc.driver.OracleDriver"/>
<beans:property name="url"
value="jdbc:oracle:thin:@localhost:1521:ex"/>
<beans:property name="username"
value="study"/>
<beans:property name="password"
value="study"/>
</beans:bean>
<!-- Resolves views selected for rendering by
@Controllers to .jsp resources in the /WEB-INF/views directory
-->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix"
value="/WEB-INF/jsp/"/>
<beans:property name="suffix" value=".jsp"
/>
</beans:bean>
</beans:beans>
7.
/WEB-INF/spring/appServlet/root-contextxml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 파일 업로드 -->
<bean
id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property
name="maxUploadSize" value="90000000"/>
<property
name="defaultEncoding" value="utf-8"/>
</bean>
<!-- Root Context: defines shared resources visible
to all other web components -->
<context:component-scan
base-package="com.board.dao"/>
<context:component-scan
base-package="com.board.service"/>
<context:component-scan
base-package="com.board.util"/>
</beans>
평일주간[100%환급과정]
(8/08)Spring,MyBatis,Hibernate실무과정
(8/08)C#4.0,WinForm,ADO.NET
(8/11)SQL기초에서 Schema Object까지
(8/11)채용예정교육
(8/18)자바기초JDBC,Servlet/JSP까지
(8/18)안드로이드개발자과정
(8/18)PL/SQL,ORACLE HINT,TUNING
평일야간[개인80%환급]
(8/06)JSP,jQUERY,Spring,MyBatis
(8/11)SQL기초에서실무까지
(8/11)안드로이드개발자과정
(8/12)Spring, MyBatis, Hibernate
(8/13)C#,Network,ADO.NET,ASP.NET
(8/13)HTML5,CSS3,Ajax,jQuery마스터
(8/28)자바JSP,jQuery,Spring,MyBatis
주말주간[개인80%환급]
(8/09)SQL기초에서실무까지
(8/09)안드로이드개발자과정
(8/09)자바JSP,Ajax,jQuery,Spring,MyBatis(8/16)C#,ASP.NET마스터(8/16)웹퍼블리싱 마스터
(8/16)Spring, MyBatis, Hibernate
(8/23)JAVA,Network&WEB&Framework
주말야간[개인80%환급]
(8/09)SQL기초에서실무까지
(8/23)JAVA,Network&WEB&Framework
(8/08)Spring,MyBatis,Hibernate실무과정
(8/08)C#4.0,WinForm,ADO.NET
(8/11)SQL기초에서 Schema Object까지
(8/11)채용예정교육
(8/18)자바기초JDBC,Servlet/JSP까지
(8/18)안드로이드개발자과정
(8/18)PL/SQL,ORACLE HINT,TUNING
평일야간[개인80%환급]
(8/06)JSP,jQUERY,Spring,MyBatis
(8/11)SQL기초에서실무까지
(8/11)안드로이드개발자과정
(8/12)Spring, MyBatis, Hibernate
(8/13)C#,Network,ADO.NET,ASP.NET
(8/13)HTML5,CSS3,Ajax,jQuery마스터
(8/28)자바JSP,jQuery,Spring,MyBatis
주말주간[개인80%환급]
(8/09)SQL기초에서실무까지
(8/09)안드로이드개발자과정
(8/09)자바JSP,Ajax,jQuery,Spring,MyBatis(8/16)C#,ASP.NET마스터(8/16)웹퍼블리싱 마스터
(8/16)Spring, MyBatis, Hibernate
(8/23)JAVA,Network&WEB&Framework
주말야간[개인80%환급]
(8/09)SQL기초에서실무까지
(8/23)JAVA,Network&WEB&Framework
댓글 없음:
댓글 쓰기