2016년 10월 17일 월요일

[자바강의,스프링강의,IT실무교육_탑크리에듀]2.(스프링4 게시판)[모델,DAO,Service만들기,Spring JDBC]Spring4@MVC-멀티파일업로드,답변형,JSR303

첨부파일 URL참조 - http://ojc.asia/bbs/board.php?bo_table=LecSpring&wr_id=431

2.(스프링4 게시판)[모델,DAO,Service만들기,Spring JDBC]Spring4@MVC-멀티파일업로드,답변형,JSR303 @Valid,@Controller,@ModelAttribute,@SessionAttributes,어노테이션기반,자바학원,스프링마이바티스교육


1. 먼저 모델쪽 클래스를 만들자,


package onj.board.model;

import java.io.Serializable;
import java.util.List;

import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.web.multipart.MultipartFile;

public class BoardDTO implements Serializable  {
private static final long serialVersionUID = 3297423984732894L;
private int seq;
@NotEmpty   //Spring JSR303 Validation Check를 위한 어노테이션, 필수입력
private String name;
@NotEmpty
@Size(min = 1, max = 20)   //들어올 값의크기 범위를 지정
private String passwd;
@NotEmpty
@Size(min = 1, max = 500)
private String title;
@NotEmpty
@Size(min = 1, max = 4000)
private String content;
private List<MultipartFile> files;    //파일업로드폼을 위한것
private String fileName1;            
private String fileName2;
private String fileName3;
private String regdate;
private int readCount;
private int reply;
private int reply_step;
private int reply_level;
public BoardDTO() {}
public BoardDTO(String name, String passwd, String title, String content, String fileName1, String fileName2, String fileName3) {
this.name = name;
this.passwd = passwd;
this.title = title;
this.content = content;
this.fileName1 = fileName1;
this.fileName2 = fileName2;
this.fileName3 = fileName3;
}
public BoardDTO(String name, String passwd, String title, String content, String fileName1, String fileName2, String fileName3, int readCount) {
this.name = name;
this.passwd = passwd;
this.title = title;
this.content = content;
this.fileName1 = fileName1;
this.fileName2 = fileName2;
this.fileName3 = fileName3;
this.readCount = readCount;
}

public int getSeq() {
return seq;
}

public void setSeq(int seq) {
this.seq = seq;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPasswd() {
return passwd;
}

public void setPasswd(String passwd) {
this.passwd = passwd;
}

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 List<MultipartFile> getFiles() {
return files;
}
public void setFiles(List<MultipartFile> files) {
this.files = files;
}
public String getFileName1() {
return fileName1;  
}

public void setFileName1(String fileName1) {
this.fileName1 = fileName1;
}
public String getFileName2() {
return fileName2;  
}

public void setFileName2(String fileName2) {
this.fileName2 = fileName2;
}
public String getFileName3() {
return fileName3;  
}

public void setFileName3(String fileName3) {
this.fileName3 = fileName3;
}


public String getRegdate() {
return regdate.substring(0, 10);  //2013-07-15 형태
}

public void setRegDate(String regdate) {
this.regdate = regdate;
}

public int getReadCount() {
return readCount;
}

public void setReadCount(int readCount) {
this.readCount = readCount;
}

public int getReply() {
return reply;
}

public void setReply(int reply) {
this.reply = reply;
}

public int getReply_step() {
return reply_step;
}

public void setReply_step(int reply_step) {
this.reply_step = reply_step;
}

public int getReply_level() {
return reply_level;
}

public void setReply_level(int reply_level) {
this.reply_level = reply_level;
}
}





package onj.board.model;

public class CommentDTO {
public String seq;       //게시글 번호
public String name;   //이름
public String comment;//커맨트
public CommentDTO() {}
public String getSeq() {
return seq;
}
public void setSeq(String seq) {
this.seq = seq;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}




2. DAO단 클래스 제작


[onj.board.dao.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;

}



[onj.board.dao.BoardDAOImpl.java]


package onj.board.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

@Repository("boardDAO")
public class BoardDAOImpl implements BoardDAO {
@Autowired
private JdbcOperations jdbcTemplate;
String sql = "";

// /게시판 전체 리스트 보기(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과 관계없이
*/
sql = " select * from  (select seq, name , passwd, "
+ "                        title, content, filename1, filename2,filename3,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.setFileName1(rs.getString("filename1"));
board.setFileName2(rs.getString("filename2"));
board.setFileName3(rs.getString("filename3"));
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 {
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 {
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.setFileName1(rs.getString("filename1"));
board.setFileName2(rs.getString("filename2"));
board.setFileName3(rs.getString("filename3"));
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 {
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 {
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 {
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 {
sql = "insert into board values(board_seq.nextval , ? , ? , ? , ? , ? ,? , ?, sysdate , 0 , board_seq.currval , 0 , 0)";
Object[] obj = { board.getName(), board.getPasswd(),
board.getTitle(), board.getContent(), board.getFileName1(), board.getFileName2(), board.getFileName3() };
return jdbcTemplate.update(sql, obj);
}

// 게시글 수정
public int updateBoard(BoardDTO board) throws DataAccessException {

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 fileName1 = boardDTO.getFileName1();
String fileName2 = boardDTO.getFileName2();
String fileName3 = boardDTO.getFileName3();
int reply = boardDTO.getReply();
int reply_step = boardDTO.getReply_step();
int reply_level = boardDTO.getReply_level();

// 현재 답변을 단 게시물 보다 더 높은 스텝의 게시물이 있다면 스텝을 하나씩 상승시킴
sql = "update board set reply_step = reply_step + 1 "
+ "where reply = " + reply + " and reply_step > " + reply_step;

jdbcTemplate.update(sql);

sql = "insert into board values(board_seq.nextval , ? , ? , ? , ? , ? , ? , ?,  sysdate , 0 , ? , ? , ?)";

// reply_step과 reply_level을 1씩 증가시킨 후 내용을 저장
Object[] obj2 = { name, passwd, title, content, fileName1, fileName2, fileName3, reply,
reply_step + 1, reply_level + 1 };

result = jdbcTemplate.update(sql, obj2);

return 0;
}

}





3. Service계층 클래스, 인터페이스




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);
}





package onj.board.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import onj.board.dao.BoardDAO;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;

@Service("boardService")
public class BoardServiceImpl implements BoardService {
@Autowired
    private 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);
}
}




package onj.board.service;

import javax.servlet.ServletContext;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/*
 * 리스트보기에서 게시물의 본문 내용을 마우스 이동시 미리 볼수 있도록 불러오는 기능을
 * 서블릿으로  구현 했는데, 서블릿은 스프링 오브젝트가 아니므로 DI가 불가능,
 * 그래서 BoardService를 돌려주는 Helper를 만들었음.
 */
public class BoardServiceHelper {
public static BoardService getBoardService(ServletContext ctx) {
WebApplicationContext wac = WebApplicationContextUtils
                   .getRequiredWebApplicationContext(ctx);
//boardConfig.xml에 정의된 boardService 빈을 리턴
//이 부분은 게시물 미리보기 서블릿(ContentPreview)에서 스프링의 인스턴스를 얻을 때 이용 
return (BoardService) wac.getBean("boardService");
}
}

댓글 없음:

댓글 쓰기