COMMENTS TABLE 생성
댓글 기능을 구현하기위해 댓글을 저장하는 DB 테이블을 생성해주었다.
CREATE TABLE COMMENTS (
CNO INT(11) NOT NULL AUTO_INCREMENT,
PNO INT(11) NOT NULL,
CONTENT TEXT NOT NULL,
WRITER VARCHAR(30) NOT NULL,
CRE_DATE DATETIME NOT NULL,
PRIMARY KEY (CNO, PNO)
) COMMENT "댓글";
CNO : 댓글의 고유번호
PNO : 댓글이 작성된 피드의 번호
CONTENT : 피드 내용
WRITER : 댓글쓴이
CRE_DATE : 댓글 생성 날짜
Comment VO 생성
CommentDao 생성
DB와 직접 연결되서 Comment 데이터를 관리할 Dao를 생성해준다.
public class MySqlCommentDao {
public DataSource ds;
public void setDataSource(DataSource ds) { this.ds = ds; }
public List<Comment> selectList(int fno) throws Exception {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = ds.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT CNO, CONTENT, WRITER, CRE_DATE FROM COMMENTS WHERE PNO="+fno);
List<Comment> comments = new ArrayList<>();
while (rs.next()) {
comments.add(new Comment()
.setNo(rs.getInt("CNO"))
.setContent(rs.getString("CONTENT"))
.setWriter(rs.getString("WRITER"))
.setCreatedDate(rs.getDate("CRE_DATE"))
);
}
return comments;
} catch (Exception e) { throw e; }
finally {
closeAll(conn, stmt, null, rs);
}
}
public int insert(Comment comment, int no) throws Exception {
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = ds.getConnection();
stmt = conn.prepareStatement("INSERT INTO COMMENTS (PNO, CONTENT, WRITER, CRE_DATE) VALUES (?, ?, ?, NOW())");
stmt.setInt(1, no);
stmt.setString(2, comment.getContent());
stmt.setString(3, comment.getWriter());
return stmt.executeUpdate();
} catch (Exception e) { throw e; }
finally {
closeAll(conn, null, stmt, null);
}
}
public int delete(int cno) throws Exception {
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = ds.getConnection();
stmt = conn.prepareStatement("DELETE FROM COMMENTS WHERE CNO=?");
stmt.setInt(1, cno);
return stmt.executeUpdate();
} catch (Exception e) { throw e; }
finally {
closeAll(conn, null, stmt, null);
}
}
public int countComments(int fno) throws Exception {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = ds.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT COUNT(*) FROM COMMENTS WHERE PNO="+fno);
if (rs.next()) {
return rs.getInt("COUNT(*)");
} else {
return -1;
}
} catch (Exception e) { throw e; }
finally {
closeAll(conn, stmt, null, rs);
}
}
private void closeAll(Connection conn, Statement stmt, PreparedStatement pre_stmt, ResultSet rs) {
try { if (rs != null) rs.close(); } catch (Exception e) {}
try { if (stmt != null) stmt.close(); } catch (Exception e) {}
try { if (pre_stmt != null) stmt.close(); } catch (Exception e) {}
try { if (conn != null) conn.close(); } catch (Exception e) {}
}
}
- selectList(int fno) : List<Comment> 피드 고유번호(fno)를 받아 해당 피드에 달린 댓글을 List 타입으로 리턴한다.
- insert(Comment comment) : int comment 값 객체를 COMMENTS 디비에 삽입하고, 고유 번호(CNO)를 리턴한다.
- delete(int cno) : int 댓글 고유 번호(cno)에 해당 하는 댓글을 삭제한다.
- countComments(int fno) : int 피드 고유번호(fno)를 받아 해당 피드에 달린 댓글의 개수를 int 타입으로 리턴한다.
FeedContentController에 댓글 기능 추가
- getDataBinder()
public class FeedContentController implements Controller, DataBinding {
@Override
public Object[] getDataBinders() {
return new Object[] {
"no", Integer.class,
"password", String.class,
"comment", String.class
};
}
}
기존의 no(피드 번호) / password(피드 수정 비밀번호) 외에 댓글 생성시 필요한 데이터인 comment 까지 getDataBinder를 통해 전달 받는다.
- 댓글 생성
public class FeedContentController implements Controller, DataBinding {
@Override
public String execute(Map<String, Object> model) throws Exception {
// 2. create comments
if (model.get("comment") != null) {
String content = (String) model.get("comment");
Comment comment = new Comment()
.setContent(content)
.setWriter(loginUser);
commentDao.insert(comment, no);
}
}
}
다음은 FeedContentController에서 댓글을 생성하는 파트이다. 클라이언트로 부터 새로운 댓글이 전송되면, 댓글 내용과 현재 로그인 유저의 정보를 통해 Comment 객체를 만든후 dao 메서드를 통해 DB에 삽입한다.
- FeedContentController 전문
public class FeedContentController implements Controller, DataBinding {
MySqlFeedDao feedDao;
MySqlCommentDao commentDao;
public FeedContentController setFeedDao(MySqlFeedDao feedDao) {
this.feedDao = feedDao;
return this;
}
public FeedContentController setCommentDao(MySqlCommentDao commentDao) {
this.commentDao = commentDao;
return this;
}
@Override
public Object[] getDataBinders() {
return new Object[] {
"no", Integer.class,
"password", String.class,
"comment", String.class
};
}
@Override
public String execute(Map<String, Object> model) throws Exception {
Integer no = (Integer) model.get("no");
HttpSession session = (HttpSession) model.get("session");
Feed feed = feedDao.selectOne(no);
String loginUser = (String) session.getAttribute("loginUser");
// 1. check authority to modify when click modify button
if (model.get("password") != null) {
String password = (String) model.get("password");
if (feed.getWriter().startsWith("익명")) {
if (password.equals(feed.getWriter().substring(2))) {
return "redirect:edit.do?no="+no;
}
} else {
if (feed.getWriter().equals(session.getAttribute("loginUser"))) {
return "redirect:edit.do?no="+no;
}
}
model.put("alert", "수정 권한이 없습니다");
}
// 2. create comments
if (model.get("comment") != null) {
String content = (String) model.get("comment");
Comment comment = new Comment()
.setContent(content)
.setWriter(loginUser);
commentDao.insert(comment, no);
}
// 3. enter content page
// check authority to edit
if (!feed.getWriter().startsWith("익명")) {
model.put("authority", "readonly");
} else {
model.put("authority", "");
}
// update views
feedDao.updateViews(no);
Integer counts = Integer.valueOf(commentDao.countComments(no));
// parse feed writer name
if (feed.getWriter().startsWith("익명")) {
feed.setWriter("익명");
}
// feed content
model.put("comments", commentDao.selectList(no));
model.put("counts", counts.toString());
model.put("feed", feed);
return "/feed/FeedContent.jsp";
}
}
commentDao.seletList 메서드를 통해 해당 피드에 작성된 댓글 리스트를 뷰에 전달한다.
commentDao.countsComments 메서드를 통해 해당 피드에 작성된 댓글의 개수를 뷰에 전달한다.
'프로젝트 이야기 > CRUD 미니 게시판' 카테고리의 다른 글
220417 [번외] : 객체 생성을 자동화해야하는 이유 (feat. 관심사분리) (0) | 2022.04.17 |
---|---|
220413 (7) : DAO / Service 분리 (0) | 2022.04.13 |
220323 [bug] : 줄바뀜이 읽기/수정 폼에서 적용이 안되는 문제 (0) | 2022.03.23 |
220322 (5) : 객체 생성 자동화 (0) | 2022.03.22 |
220319 (4) : 로그인/회원가입 입력폼 예외처리 (0) | 2022.03.19 |