댓글 기능 구현 순서
1. DB테이블 생성
2. Mapper XML 작성
3. DAO 작성 & 테스트
4. Service 작성 & 테스트
5. 컨트롤러 작성 & 테스트
6. 뷰UI) 작성 & 테스트
DB테이블 생성
CREATE TABLE `usedhunter`.`comment` (
`cno` INT NOT NULL AUTO_INCREMENT,
`bno` INT NOT NULL,
`pcno` INT NULL,
`comment` VARCHAR(3000) NULL,
`commenter` VARCHAR(30) NULL,
`reg_date` DATETIME NULL DEFAULT now(),
`up_date` DATETIME NULL DEFAULT now(),
PRIMARY KEY (`cno`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
insert 테스트
insert into comment (bno, comment, commenter) values (1, 'hello', 'asdf');
commentMapper.xml 작성
<?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="com.jcy.usedhunter.dao.CommentMapper">
<insert id="insert" parameterType="CommentDto">
INSERT INTO comment
(bno, pcno, comment, commenter, reg_date, up_date)
VALUES
(#{bno}, #{pcno}, #{comment}, #{commenter}, now(), now())
</insert>
<sql id="selectFromComment">
SELECT cno, bno, pcno, comment, commenter, reg_date, up_date
FROM comment
</sql>
<select id="select" parameterType="int" resultType="CommentDto">
<include refid="selectFromComment"/>
WHERE cno = #{cno}
</select>
<select id="selectAll" resultType="CommentDto">
<include refid="selectFromComment"/>
WHERE bno = #{bno}
ORDER BY reg_date DESC, cno DESC
</select>
<select id="count" resultType="int">
SELECT count(*) FROM comment
WHERE bno = #{bno}
</select>
<update id="update" parameterType="CommentDto">
UPDATE comment
SET comment = #{comment}
, up_date = now()
WHERE cno = #{cno} and commenter = #{commenter}
</update>
<delete id="delete" parameterType="map">
DELETE FROM comment WHERE cno = #{cno} and commenter = #{commenter}
</delete>
<delete id="deleteAll">
DELETE FROM comment
WHERE bno = #{bno}
</delete>
</mapper>
mybatis-config.xml
alias="CommentDto" 추가
<typeAlias alias="CommentDto" type="com.jcy.usedhunter.domain.CommentDto"/>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias alias="BoardDto" type="com.jcy.usedhunter.domain.BoardDto"/>
<typeAlias alias="SearchCondition" type="com.jcy.usedhunter.domain.SearchCondition"/>
<typeAlias alias="CommentDto" type="com.jcy.usedhunter.domain.CommentDto"/>
</typeAliases>
</configuration>
CommentDto 작성
package com.jcy.usedhunter.domain;
import java.util.Date;
import java.util.Objects;
public class CommentDto {
private Integer cno;
private Integer bno;
private Integer pcno;
private String comment;
private String commenter;
private Date reg_date;
private Date up_date;
public CommentDto() {
}
public CommentDto(Integer bno, Integer pcno, String comment, String commenter) {
this.bno = bno;
this.pcno = pcno;
this.comment = comment;
this.commenter = commenter;
}
public Integer getCno() {
return cno;
}
public void setCno(Integer cno) {
this.cno = cno;
}
public Integer getBno() {
return bno;
}
public void setBno(Integer bno) {
this.bno = bno;
}
public Integer getPcno() {
return pcno;
}
public void setPcno(Integer pcno) {
this.pcno = pcno;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getCommenter() {
return commenter;
}
public void setCommenter(String commenter) {
this.commenter = commenter;
}
public Date getReg_date() {
return reg_date;
}
public void setReg_date(Date reg_date) {
this.reg_date = reg_date;
}
public Date getUp_date() {
return up_date;
}
public void setUp_date(Date up_date) {
this.up_date = up_date;
}
@Override
public String toString() {
return "CommentDto [cno=" + cno + ", bno=" + bno + ", pcno=" + pcno + ", comment=" + comment + ", commenter="
+ commenter + ", reg_date=" + reg_date + ", up_date=" + up_date + "]";
}
@Override
public int hashCode() {
return Objects.hash(bno, cno, commenter, comment, pcno);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CommentDto other = (CommentDto) obj;
return Objects.equals(bno, other.bno) && Objects.equals(cno, other.cno)
&& Objects.equals(commenter, other.commenter) && Objects.equals(comment, other.comment)
&& Objects.equals(pcno, other.pcno);
}
}
CommnetDao 작성
package com.jcy.usedhunter.dao;
import java.util.List;
import com.jcy.usedhunter.domain.CommentDto;
public interface CommentDao {
int insert(CommentDto commentDto) throws Exception;
CommentDto select(Integer cno) throws Exception;
List<CommentDto> selectAll(Integer bno) throws Exception;
int count(Integer bno) throws Exception;
int update(CommentDto commentDto) throws Exception;
int delete(Integer cno, String commenter) throws Exception;
int deleteAll(Integer bno) throws Exception;
}
CommentDaoImpl 작성
package com.jcy.usedhunter.dao;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.jcy.usedhunter.domain.CommentDto;
@Repository
public class CommentDaoImpl implements CommentDao{
@Autowired
SqlSession session;
private static String namespace = "com.jcy.usedhunter.dao.CommentMapper."; // 마지막에 '.' 잊지 말기
@Override
public int insert(CommentDto commentDto) throws Exception {
return session.insert(namespace + "insert", commentDto);
}
@Override
public CommentDto select(Integer cno) throws Exception {
return session.selectOne(namespace + "select", cno);
}
@Override
public List<CommentDto> selectAll(Integer bno) throws Exception {
return session.selectList(namespace + "selectAll", bno);
}
@Override
public int count(Integer bno) throws Exception {
return session.selectOne(namespace + "count", bno);
}
@Override
public int update(CommentDto commentDto) throws Exception {
return session.update(namespace + "update", commentDto);
}
@Override
public int delete(Integer cno, String commenter) throws Exception {
Map map = new HashMap();
map.put("cno", cno);
map.put("commenter", commenter);
return session.delete(namespace + "delete", map);
}
@Override
public int deleteAll(Integer bno) throws Exception {
return session.delete(namespace + "deleteAll", bno);
}
}
CommentDaoImpl 테스트
package com.jcy.usedhunter;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.jcy.usedhunter.dao.CommentDao;
import com.jcy.usedhunter.domain.CommentDto;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/**/root-context.xml"})
public class CommentDaoImplTest {
@Autowired
CommentDao commentDao;
@Test
public void insert() throws Exception {
commentDao.deleteAll(1);
CommentDto commentDto = new CommentDto(1, 0, "comment", "asdf");
assertTrue(commentDao.insert(commentDto)==1);
assertTrue(commentDao.count(1)==1);
commentDto = new CommentDto(1, 0, "comment", "asdf");
assertTrue(commentDao.insert(commentDto)==1);
assertTrue(commentDao.count(1)==2);
}
@Test
public void select() throws Exception {
commentDao.deleteAll(1);
CommentDto commentDto = new CommentDto(1, 0, "comment", "asdf");
assertTrue(commentDao.insert(commentDto)==1);
assertTrue(commentDao.count(1)==1);
List<CommentDto> list = commentDao.selectAll(1);
String comment = list.get(0).getComment();
String commenter = list.get(0).getCommenter();
assertTrue(comment.equals(commentDto.getComment()));
assertTrue(commenter.equals(commentDto.getCommenter()));
}
@Test
public void selectAll() throws Exception {
commentDao.deleteAll(1);
CommentDto commentDto = new CommentDto(1, 0, "comment", "asdf");
assertTrue(commentDao.insert(commentDto)==1);
assertTrue(commentDao.count(1)==1);
List<CommentDto> list = commentDao.selectAll(1);
assertTrue(list.size()==1);
commentDto = new CommentDto(1, 0, "comment", "asdf");
assertTrue(commentDao.insert(commentDto)==1);
assertTrue(commentDao.count(1)==2);
list = commentDao.selectAll(1);
assertTrue(list.size()==2);
}
@Test
public void update() throws Exception {
commentDao.deleteAll(1);
CommentDto commentDto = new CommentDto(1, 0, "comment", "asdf");
assertTrue(commentDao.insert(commentDto)==1);
assertTrue(commentDao.count(1)==1);
List<CommentDto> list = commentDao.selectAll(1);
commentDto.setCno(list.get(0).getCno());
commentDto.setComment("comment2");
assertTrue(commentDao.update(commentDto)==1);
list = commentDao.selectAll(1);
String comment = list.get(0).getComment();
String commenter = list.get(0).getCommenter();
assertTrue(comment.equals(commentDto.getComment()));
assertTrue(commenter.equals(commentDto.getCommenter()));
}
@Test
public void count() throws Exception {
commentDao.deleteAll(1);
assertTrue(commentDao.count(1)==0);
}
@Test
public void delete() throws Exception {
commentDao.deleteAll(1);
CommentDto commentDto = new CommentDto(1, 0, "comment", "asdf");
assertTrue(commentDao.insert(commentDto)==1);
assertTrue(commentDao.count(1)==1);
}
}
CommentService 작성
boardMapper.xml
updateCommnetCnt 추가
<update id="updateCommentCnt" parameterType="map">
UPDATE board
SET comment_cnt = comment_cnt + #{cnt}
WHERE bno = #{bno}
</update>
BoardDao.java
updateCommnetCnt 추가
int updateCommnetCnt(Integer bno, int cnt);
BoardDaImpl.java
updateCommnetCnt 추가
@Override
public int updateCommnetCnt(Integer bno, int cnt) {
Map map = new HashMap();
map.put("cnt", cnt);
map.put("bno", bno);
return session.update(namespace + "updateCommentCnt", map);
}
CommentService.java
package com.jcy.usedhunter.service;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
import com.jcy.usedhunter.domain.CommentDto;
public interface CommentService {
@Transactional(rollbackFor = Exception.class)
int write(CommentDto commentDto) throws Exception;
CommentDto read(Integer cno) throws Exception;
List<CommentDto> getList(Integer bno) throws Exception;
int getCount(Integer bno) throws Exception;
int modify(CommentDto commentDto) throws Exception;
@Transactional(rollbackFor = Exception.class)
int remove(Integer cno, Integer bno, String commneter) throws Exception;
}
CommentServiceImpl 작성
package com.jcy.usedhunter.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jcy.usedhunter.dao.BoardDao;
import com.jcy.usedhunter.dao.CommentDao;
import com.jcy.usedhunter.domain.CommentDto;
@Service
public class CommentServiceImpl implements CommentService{
// @Autowired
BoardDao boardDao;
//
// @Autowired
CommentDao commentDao;
// @Autowired
public CommentServiceImpl(CommentDao commentDao, BoardDao boardDao) {
this.commentDao = commentDao;
this.boardDao = boardDao;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int write(CommentDto commentDto) throws Exception {
boardDao.updateCommnetCnt(commentDto.getBno(), 1);
// throw new Exception("test");
return commentDao.insert(commentDto);
}
@Override
public CommentDto read(Integer cno) throws Exception {
return commentDao.select(cno);
}
@Override
public List<CommentDto> getList(Integer bno) throws Exception {
// throw new Exception("test");
return commentDao.selectAll(bno);
}
@Override
public int getCount(Integer bno) throws Exception {
return commentDao.count(bno);
}
@Override
public int modify(CommentDto commentDto) throws Exception {
return commentDao.update(commentDto);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int remove(Integer cno, Integer bno, String commneter) throws Exception {
int rowCnt = boardDao.updateCommnetCnt(bno, -1);
System.out.println("updateCommentCnt - rowCnt = " + rowCnt);
// throw new Exception("test");
rowCnt = commentDao.delete(cno, commneter);
System.out.println("rowCnt = " + rowCnt);
return rowCnt;
}
}
CommnetServiceImpl 테스트 작성
package com.jcy.usedhunter;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.jcy.usedhunter.dao.BoardDao;
import com.jcy.usedhunter.dao.CommentDao;
import com.jcy.usedhunter.domain.BoardDto;
import com.jcy.usedhunter.domain.CommentDto;
import com.jcy.usedhunter.service.CommentService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/**/root-context.xml"})
public class CommentServiceImplTest {
@Autowired
BoardDao boardDao;
@Autowired
CommentDao commentDao;
@Autowired
CommentService commentService;
@Test
public void write() throws Exception{
boardDao.deleteAll();
BoardDto boardDto = new BoardDto("hello", "hello", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
Integer bno = boardDao.selectAll().get(0).getBno();
System.out.println("bno = " + bno);
commentDao.deleteAll(bno);
CommentDto commentDto = new CommentDto(bno, 0, "hi", "qwer");
assertTrue(boardDao.select(bno).getComment_cnt()==0);
assertTrue(commentService.write(commentDto)==1);
Integer cno = commentDao.selectAll(bno).get(0).getCno();
assertTrue(boardDao.select(bno).getComment_cnt()==1);
}
@Test
public void remove() throws Exception{
boardDao.deleteAll();
BoardDto boardDto = new BoardDto("hello", "hello", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
Integer bno = boardDao.selectAll().get(0).getBno();
System.out.println("bno = " + bno);
commentDao.deleteAll(bno);
CommentDto commentDto = new CommentDto(bno, 0, "hi", "qwer");
assertTrue(boardDao.select(bno).getComment_cnt()==0);
assertTrue(commentService.write(commentDto)==1);
assertTrue(boardDao.select(bno).getComment_cnt()==1);
Integer cno = commentDao.selectAll(bno).get(0).getCno();
// 일부러 예외를 발생시키고 Tx가 취소되는지 확인
int rowCnt = commentService.remove(cno, bno, commentDto.getCommenter());
assertTrue(rowCnt==1);
assertTrue(boardDao.select(bno).getComment_cnt()==0);
}
}
write rollback 테스트
@Override
@Transactional(rollbackFor = Exception.class)
public int write(CommentDto commentDto) throws Exception {
boardDao.updateCommnetCnt(commentDto.getBno(), 1);
throw new Exception("test");
// return commentDao.insert(commentDto);
}
remove rollback 테스트
@Override
@Transactional(rollbackFor = Exception.class)
public int remove(Integer cno, Integer bno, String commneter) throws Exception {
int rowCnt = boardDao.updateCommnetCnt(bno, -1);
System.out.println("updateCommentCnt - rowCnt = " + rowCnt);
throw new Exception("test");
// rowCnt = commentDao.delete(cno, commneter);
// System.out.println("rowCnt = " + rowCnt);
// return rowCnt;
}
'프로젝트 > 중고헌터' 카테고리의 다른 글
중고헌터 - 댓글 기능 구현 3 - UI 구현 (0) | 2022.10.10 |
---|---|
중고헌터 - 댓글 기능 구현 2 - Controller 작성 (0) | 2022.10.09 |
중고헌터 - REST API와 Ajax (0) | 2022.10.08 |
중고헌터 - 게시판 검색 기능 구현하기 (1) | 2022.10.06 |
중고헌터 - 게시판 읽기, 쓰기, 수정, 삭제 구현 2 (0) | 2022.10.06 |