일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- update
- spring
- service
- 게시판 List
- CRUD
- 게시판
- log4j
- MVC
- Oracle
- mybatis
- hikaricp
- MVC 게시판
- MVC CRUD
- delete
- jdbc
- MVC설정
- 게시판만들기
- Connection pool
- 환경설정
- Oracle 연결
- log4jdbc
- 서비스계층
- Controller
- Today
- Total
yahayaha
20. 댓글 처리하기 (CRUD) 본문
댓글을 추가하기 위해서 구조에 맞는 테이블을 설계.
create table tbl_reply(
rno number(10,0),
bno number(10,0) not null,
reply varchar2(1000) not null,
replyer varchar2(50) not null,
replyDate date default sysdate,
updateDate date default sysdate
);
create sequence seq_reply;
alter table tbl_reply add constraint pk_reply primary key(rno);
alter table tbl_reply add constraint fk_reply_board
foreign key (bno) references tbl_board(bno);
tbl_reply 테이블은 bno라는 칼럼을 이용해서 해당 댓글이 어떤 게시물의 댓글인지를 명시.
댓글 자체는 단독으로 CRUD가 가능하므로, 별도의 PK를 부여하고, 외래키(FK) 설정을 통해서 tbl_board 테이블을 참조하도록 설정.
ReplyVo 클래스 추가.
import java.util.Date;
import lombok.Data;
@Data
public class ReplyVO {
private Long rno;
private Long bno;
private String reply;
private String replyer;
private Date repltDate;
private Date updateDate;
}
ReplyMapper 클래스 XML 처리
댓글 처리도 화면상에서 페이지 처리가 필요할 수 있으므로 Criteria를 이용해서 처리.
mapper패키지에 ReplyMapper 인터페이스, resources에 ReplyMapper.xml을 생성.

작업을 진행하기 전에 tbl_reply 테이블이 tbl_board 테이블과 FK(외래키)의 관계로 처리되어 있다는걸 알아야함.
tbl_reply가 tbl_board 테이블의 bno 값과 정확히 일치 해야함. 테스트를 진행하기 전에 최신 bno 번호 몇 개를 확인.

ReplyMapper가 사용 가능 한지에 대한 테스트 코드를 실행. ReplyMapperTest 클래스 생성.
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.SpringRunner;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@RunWith(SpringRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class ReplyMapperTests {
@Setter(onMethod_ = @Autowired)
private ReplyMapper mapper;
@Test
public void testMapper() {
log.info(mapper);
}
}

댓글 등록
외래키를 사용하는 등록 작업 우선 진행.
public interface ReplyMapper {
public int insert(ReplyVO reply);
}
ReplyMapper의 SQL처리.
<mapper namespace="org.zerock.mapper.ReplyMapper">
//등록
<insert id="insert">
insert into tbl_reply (rno, bno, reply, replyer)
values (seq_reply.nextval, #{bno}, #{reply}, #{replyer})
</insert>
</mapper>
SQL도 작성이 되었으면 테스트를 진행.
@RunWith(SpringRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class ReplyMapperTests {
// 해달 번호가 게시물이 존재하는지 확인해야함.
private Long[] bnoArr = { 2461L, 2460L , 2459L, 2458L, 2457L};
@Setter(onMethod_ = @Autowired)
private ReplyMapper mapper;
@Test
public void testCreate() {
IntStream.rangeClosed(1, 10).forEach(i ->{
ReplyVO reply = new ReplyVO();
//게시물 번호
reply.setBno(bnoArr[i % 5]);
reply.setReply("댓글 테스트" + i);
reply.setReplyer("댓글 작성자" + i);
mapper.insert(reply);
});
}
}
bnoArr은 게시물 번호의 일부로 실제 데이터베이스에 있는 번호여야함.
(PK와 FK의 관계로 묶여 있기 때문)
테스트 결과를 확인.
select * from tbl_reply order by rno desc;

등록 작업이 처리된 것을 확인 후 조회 작업을 처리.
댓글 조회
public interface ReplyMapper {
public int insert(ReplyVO reply);
public ReplyVO read(Long rno); //특정 댓글 읽기
}
<mapper namespace="org.zerock.mapper.ReplyMapper">
//등록
<insert id="insert">
insert into tbl_reply (rno, bno, reply, replyer)
values (seq_reply.nextval, #{bno}, #{reply}, #{replyer})
</insert>
//조회
<select id="read" resultType="org.zerock.domain.ReplyVO">
select * from tbl_reply where rno = #{rno}
</select>
</mapper>
@Test
public void testRead() {
Long targetRno = 5L;
ReplyVO reply = mapper.read(targetRno);
log.info(reply);
}
정상적으로 5번 댓글이 조회되는지 확인.

댓글 삭제
public interface ReplyMapper {
public int insert(ReplyVO reply);
public ReplyVO read(Long rno); //특정 댓글 읽기
public int delete(Long rno);
}
<mapper namespace="org.zerock.mapper.ReplyMapper">
//등록
<insert id="insert">
insert into tbl_reply (rno, bno, reply, replyer)
values (seq_reply.nextval, #{bno}, #{reply}, #{replyer})
</insert>
//조회
<select id="read" resultType="org.zerock.domain.ReplyVO">
select * from tbl_reply where rno = #{rno}
</select>
//삭제
<delete id="delete">
delete from tbl_reply where rno = #{rno}
</delete>
</mapper>
@Test
public void testDelete() {
Long targetRno = 1L;
mapper.delete(targetRno);
}


삭제가 된걸 확인.
댓글 수정
댓글의 수정은 현재 tbl_reply 테이블의 구조에서는 댓글의 내용과 최종 수정시간을 수정.
public interface ReplyMapper {
public int insert(ReplyVO reply);
public ReplyVO read(Long rno); //특정 댓글 읽기
public int delete(Long rno);
public int update(ReplyVO reply);
}
<mapper namespace="org.zerock.mapper.ReplyMapper">
//등록
<insert id="insert">
insert into tbl_reply (rno, bno, reply, replyer)
values (seq_reply.nextval, #{bno}, #{reply}, #{replyer})
</insert>
//조회
<select id="read" resultType="org.zerock.domain.ReplyVO">
select * from tbl_reply where rno = #{rno}
</select>
//삭제
<delete id="delete">
delete from tbl_reply where rno = #{rno}
</delete>
//수정
<update id="update">
update tbl_reply set reply = #{reply}, updatedate = sysdate where rno = #{rno}
</update>
</mapper>
@Test
public void testUpdate() {
Long targetRno = 10L;
ReplyVO reply = mapper.read(targetRno);
reply.setReply("수정 댓글");
int count = mapper.update(reply);
log.info("업데이트 카운트 " + count);
}


@Param어노테이션과 댓글 목록
댓글의 목록과 페이징 처리는 기존의 게시물 페이징 처리와 유사하지만, 추가적으로
특정한 게시물의 댓글들만을 대상으로 하기 때문에 추가로 게시물의 번호가 필요.
MyBatis는 두 개 이상의 데이터를 파라미터로 전달하기 위해서는
1. 별도의 객체로 구성
2. Map 사용
3. @Param 사용
여러 방식 중에 가장 간단한 @Param을 이용하는 방식을 사용.
@Param의 송성값은 MyBatis에서 SQL을 이용할 때 '#{}'의 이름으로 사용 가능.
페이징 처리는 Criteria를 사용하는데 추가적으로 해당 게시물의 번호는 파라미터를 전달하도록 ReplyMapper를 수정.
public interface ReplyMapper {
public int insert(ReplyVO reply);
public ReplyVO read(Long rno); //특정 댓글 읽기
public int delete(Long rno);
public int update(ReplyVO reply);
public List<ReplyVO> getListWithPaging(
@Param("cri") Criteria cri,
@Param("bno") Long bno);
}
<mapper namespace="org.zerock.mapper.ReplyMapper">
//등록
<insert id="insert">
insert into tbl_reply (rno, bno, reply, replyer)
values (seq_reply.nextval, #{bno}, #{reply}, #{replyer})
</insert>
//조회
<select id="read" resultType="org.zerock.domain.ReplyVO">
select * from tbl_reply where rno = #{rno}
</select>
//삭제
<delete id="delete">
delete from tbl_reply where rno = #{rno}
</delete>
//수정
<update id="update">
update tbl_reply set reply = #{reply}, updatedate = sysdate where rno = #{rno}
</update>
//#{bno}가 @Param("bno")와 매칭
<select id="getListWithPaging" resultType="org.zerock.domain.ReplyVO">
select rno, bno, reply, replyer, replyDate, updatedate
from tbl_reply
where bno = #{bno}
order by rno asc
</select>
</mapper>
@Test
public void testList() {
Criteria cri = new Criteria();
//2461L
List<ReplyVO> replies = mapper.getListWithPaging(cri, bnoArr[0]);
replies.forEach(reply -> log.info(reply));
}

'spring > 프로젝트' 카테고리의 다른 글
22. ajax 댓글 처리 (0) | 2024.02.09 |
---|---|
21. 댓글 처리하기 (Controller 처리) (0) | 2024.02.08 |
19. 검색처리 (JSP수정) (0) | 2024.02.04 |
18. 검색 처리 (동적 쿼리) (0) | 2024.01.29 |
17. 페이징 이벤트 처리 ( 수정 / 삭제 ) (0) | 2024.01.27 |