BoardMapper.xml 내용추가
댓글의 개수를 추가 하기위해 SQL 작성
<!-- 게시판 전체 목록/검색 목록 --> 부분 내용추가
LEFT OUTER JOIN (SELECT COUNT (*) re_cnt, board_num FROM spboard_reply GROUP BY board_num) USING(board_num)
이젠 상세페이지에 댓글갯수를 보이게 하려고함
boardView.jsp
span id를 추가
<!-- 댓글수 -->
<span id="output_rcount"></span>
board.reply.js
내용수정
//댓글 수 읽어오기
displayReplyCount(param.count);
/*===================
댓글수 표시
===================*/
function displayReplyCount(count){
let output;
if(count>0){
output = '댓글수('+count+')';
}else{
output = '댓글수(0)';
}
//문서 객체에 추가
$('#output_rcount').text(output);
}
//다음 댓글 보기 버튼 클릭시 데이터 추가
$('.paging-button input').click(function(){
selectList(currentPage + 1);
});
board.css
댓글들이 너무 붙어있는 부분을 해결하기위해 내용수정
div.item{
margin-top:10px;
}
댓글 수정 폼 작성
board.reply.js
/*===================
댓글 수정
===================*/
//댓글 수정 버튼 클릭시 수정폼 노출
$(document).on('click','.modify-btn',function(){
//댓글번호
let re_num = $(this).attr('data-num');
//댓글 내용
let re_content = $(this).parent()
.find('p')
.html()
.replace(/<br>/gi,'\r\n') /*부모태그에 p태그를 찾아서 바꾼다.*/
/*g: 지정문자열 모두, i: 대소문자 무시 => 즉 대소문자 상관없이 모든 문자열 모두를 줄바꿈해라.*/
//댓글 수정폼 UI
let modifyUI = '<form id="mre_form">';
modifyUI += '<input type="hidden" name="re_num" id="re_num" value="'+re_num+'">';
modifyUI += '<textarea rows="3" cols="50" name="re_content" id="mre_content" class="rep-content">'+re_content+'</textarea>';
modifyUI += '<div id="mre_first"><span class="letter-count">300/300</span></div>';
modifyUI += '<div id="mre_second" class="align-right">';
modifyUI += ' <input type="submit" value="수정">';
modifyUI += ' <input type="button" value="취소" class="re-reset">';
modifyUI += '</div>';
modifyUI += '<hr size="1" noshade width="96%">';
modifyUI += '</form>';
//답글이 있는 경우 답글을 초기화
//답글이 있는 경우 답글을 초기화
//이전에 이미 수정하는 댓글이 있을 경우 수정 버튼을 클릭하면
//숨김 sub-item를 환원시키고 수정폼을 초기화함
initModifyForm();
//지금 클릭해서 수정하고자 하는 데이터는 감추기
//(수정 버튼을 감싸고있는 div)
$(this).parent().hide(); //삭제가 아닌 감추기 (부모쪽에서 찾은다음 숨기기)
//수정폼을 수정하고자 하는 데이터가 있는 div에 노출
$(this).parents('.item').append(modifyUI); //parent는 직계부모. parents는 뒤에 이름을 지정해서 여러부모중 한 부모를 찾는것.
//입력한 글자수 셋팅
let inputLength = $('#mre_content').val().length;
let remain = 300 - inputLength;
remain += '/300';
//문서 객체에 반영
$('#mre_first .letter-count').text(remain);
});
//수정폼에서 취소 버튼 클릭시 수정폼 초기화
$(document).on('click','.re-reset',function(){
initModifyForm();
});
//댓글 수정폼 초기화
function initModifyForm(){
$('.sub-item').show();
$('#mre_form').remove();
}
댓글 수
BoardMapper.java
>>BoardMapper에서 회원번호를 구해서 자신의 댓글과 일치하는지 알아내고,
//댓글 수정,삭제시 작성자 회원번호를 구하기 위해 사용
@Select("SELECT * FROM spboard_reply WHERE re_num=#{re_num}")
public BoardReplyVO selectReply(Long re_num);
수정할 수 있도록 SQL문 작성
@Update("UPDATE spboard_reply SET re_content=#{re_content},re_ip=#{re_ip},re_mdate=SYSDATE WHERE re_num=#{re_num}")
public void updateReply(BoardReplyVO boardReply);
BoardServiceImpl
@Override
public BoardReplyVO selectReply(Long re_num) {
return boardMapper.selectReply(re_num);
}
@Override
public void updateReply(BoardReplyVO boardReply) {
boardMapper.updateReply(boardReply);
}
BoardAjaxController
댓글수정 포스트매핑으로 받은 후 수정값넣기,로그인 여부 확인등
/*===================
댓글 수정
===================*/
@PostMapping("/board/updateReply")
@ResponseBody
public Map<String,String> modifyReply(
BoardReplyVO boardReplyVO,
HttpSession session,
HttpServletRequest request){
log.debug("<<댓글 수정>> :"+boardReplyVO);
Map<String,String> mapJson = new HashMap<String, String>();
MemberVO user = (MemberVO)session.getAttribute("user"); //로그인을 했는지 확인하기위해 (회원제 서비스이기 떄문에)
BoardReplyVO db_reply = boardService.selectReply(boardReplyVO.getRe_num());
if(user == null) {
//로그인이 되지 않은 경우
mapJson.put("result","logout");
}else if(user !=null
&& user.getMem_num()==db_reply.getMem_num()) {
//로그인 회원번호와 작성자 회원번호 일치
//ip저장
boardReplyVO.setRe_ip(request.getRemoteAddr());
//댓글 수정
boardService.updateReply(boardReplyVO);
mapJson.put("result","success");
}else {
//로그인 회원번호와 작성자 회원번호 불일치
mapJson.put("result","wrongAccess");
}
return mapJson;
}
board.reply.js
수정을 눌렀을 때 수정폼의 있는 수정버튼을 연결해서 수정하고자함.
//댓글 수정
$(document).on('submit','#mre_form',function(event){
if($('#mre_content').val().trim()==''){ //수정폼의 내용이 없을경우
alert('내용을 입력하세요!');
$('#mre_content').val().focus();
return false;
}
//폼에 입력한 데이터 반환
let form_data = $(this).serialize();
//서버와 통신
$.ajax({
url:'updateReply',
type:'post',
data:form_data,
dataType:'json',
success:function(param){
if(param.result =='logout'){
alert('로그인해야 수정할 수 있습니다.');
}else if(param.result == 'success'){
$('#mre_form').parent().find('p').html($('#mre_content').val().replace(/</g,'<')
.replace(/>/g,'>')
.replace(/\r\n/g,'<br>')
.replace(/\r/g,'<br>')
.replace(/\n/g,'<br>'));
//최근 수정일 처리
$('#mre_form').parent().find('modify-date').text('최근 수정일: 5초미만');
//수정폼 초기화
initModifyForm();
}else if(param.result =='wrongAccess'){
alert('타인의 글은 수정할 수 없습니다.');
}else{
alert('댓글 수정 오류 발생');
}
},
error:function(){
alert('네트워크 오류 발생');
}
});
//기본 이벤트 제거 (작성이 끝나면 이벤트를 없애야되니까)
event.preventDefault();
});
태그 적용되는걸 없애려고함.
BoardMapper.xml
<!-- 게시판 전체 목록/검색 목록 -->
<select id="selectList" parameterType="map" resultType="boardVO">
SELECT
*
FROM (SELECT
a.*,
rownum rnum
FROM (SELECT
board_num,
<![CDATA[
REPLACE(REPLACE(title,'<','<'),'>','>') title,
]]>
hit,
filename,
reg_date,
mem_num,
id,
nick_name,
re_cnt,
fav_cnt
FROM spboard
LEFT OUTER JOIN (SELECT COUNT (*) re_cnt, board_num FROM spboard_reply GROUP BY board_num) USING(board_num)
LEFT OUTER JOIN (SELECT COUNT (*) fav_cnt, board_num FROM spboard_fav GROUP BY board_num) USING(board_num) <!-- fav_cnt는 알리아스 명칭임 이 괄호는 인라인 뷰 -->
JOIN spmember USING(mem_num)
<include refid="boardSearch"></include>
<include refid="boardOrder"></include>
)a)
<![CDATA[
WHERE rnum >= #{start} AND rnum <= #{end}
]]>
</select>
아래코드 부분을 추가했다.
board_num,
<![CDATA[
REPLACE(REPLACE(title,'<','<'),'>','>') title,
]]>
hit,
filename,
reg_date,
mem_num,
id,
nick_name,
re_cnt,
fav_cnt
BoardMapper.java
댓글 삭제말고도 부모글 삭제시 댓글,답글 자동삭제하는 SQL도 만들어두긴했음.
@Delete("DELETE FROM spboard_reply WHERE re_num=#{re_num}")
public void deleteReply(Long re_num);
//부모글 삭제시 댓글이 존재하면 부모글 삭제전 댓글 삭제
@Delete("DELETE FROM spboard_reply WHERE board_num=#{board_num}")
public void deleteReplyByBoardNum(Long board_num);
//부모글 삭제시 댓글의 답글이 존재하면 댓글 번호를 구해서 답글 삭제시 사용
@Select("SELECT * FROM spboard_reply WHERE board_num=#{board_num}")
public List<Long> selectReNumsByBoard_num(Long board_num);
boardServiceImpl
@Override
public void deleteReply(Long re_num) {
boardMapper.deleteReply(re_num);
}
BoardAjaxController
/*===================
댓글 삭제
===================*/
@PostMapping("/board/deleteReply")
@ResponseBody
public Map<String,String> deleteReply(long re_num,
HttpSession session){
log.debug("<<댓글 삭제 - re_num>>:"+ re_num);
Map<String,String> mapJson = new HashMap<String, String>();
MemberVO user = (MemberVO)session.getAttribute("user"); //로그인을 했는지 확인하기위해 (회원제 서비스이기 떄문에)
BoardReplyVO db_reply = boardService.selectReply(re_num);
if(user == null) {
//로그인이 되지 않은 경우
mapJson.put("result","logout");
}else if(user !=null
&& user.getMem_num()==db_reply.getMem_num()) {
//로그인 회원번호와 작성자 회원번호 일치
boardService.deleteReply(re_num);
mapJson.put("result","success");
}else {
//로그인 회원번호와 작성자 회원번호 불일치
mapJson.put("result","wrongAccess");
}
return mapJson;
}
board.reply.js
/*===================
댓글 삭제
===================*/
//위에서 만들었던 class=delete-btn을 클릭했을 시
$(document).on('click','.delete-btn',function(){
//댓글 번호
let re_num = $(this).attr('data-num');
//서버와 통신
$.ajax({
url:'deleteReply',
type:'post',
data:{re_num:re_num},
dataType:'json',
success:function(param){
if(param.result == 'logout'){
alert('로그인해야 삭제할 수 있습니다.');
}else if(param.result=='success'){
alert('삭제완료');
selectList(1); //1페이지 목록을 호출
}else if(param.result=='wrongAccess'){
alert('타인의 글을 삭제할 수 없습니다');
}else{
alert('댓글 삭제 오류 발생');
}
},
error:function(){
alert('네트워크 오류 발생');
}
});
});
table.sql
sqldeveloper => java에 구동
--댓글 좋아요
create table sqreply_fav(
re_num number not null,
mem_num number not null,
constraint refav_fk1 foreign key (re_num)
references spboard_reply (re_num),
constraint refav_fk2 foreign key (mem_num)
references spmember (mem_num)
);
BoardReFavVO 클래스 생성
package kr.spring.board.vo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class BoardReFavVO {
private long re_num;
private long mem_num;
}
BoardMapper.java
//댓글 좋아요
public BoardReFavVO selecReFav(BoardReFavVO fav);
public Integer selectReFavCount(Long re_num);
public void insertReFav(BoardReFavVO fav);
public void deleteReFav(BoardReFavVO fav);
public void deleteReFavByRenum(Long re_num);
public void deleteReFavByBoardNum(Long board_num);
BoardService에다 위에 4개만 복사해서 넣어준다.
BoardServiceImpl
에 add method를 해준다.
추가로 service에 복사를 안했던 2개의 메서드를 명시해준다.
@Override
public void deleteBoard(Long board_num) {
//답글 삭제
//댓글 좋아요 삭제
boardMapper.deleteReFavByBoardNum(board_num);
@Override
public void deleteReply(Long re_num) {
//답글
//댓글 좋아요
boardMapper.deleteReFavByRenum(re_num);
//댓글
boardMapper.deleteReply(re_num);
}
BoardMapper.java
sql문 작성
//댓글 좋아요
@Select("SELECT * FROM spreply_fav WHERE re_num=#{re_num} AND mem_num=#{mem_num}")
public BoardReFavVO selecReFav(BoardReFavVO fav);
@Select("SELECT * COUNT(*) FROM spreply_fav WHERE re_num=#{re_num}")
public Integer selectReFavCount(Long re_num);
BoardServiceImpl
작성한 sql문을 연결시켜
@Override
public BoardReFavVO selecReFav(BoardReFavVO fav) {
return boardMapper.selecReFav(fav);
}
@Override
public Integer selectReFavCount(Long re_num) {
return boardMapper.selectReFavCount(re_num);
}
BoardAjaxController
/*===================
댓글 좋아요 읽기
===================*/
@GetMapping("/board/getReFav")
@ResponseBody
public Map<String,Object> getReFav(
BoardReFavVO fav,
HttpSession session){
log.debug("<<댓글 좋아요>>:" +fav);
Map<String,Object> mapJson = new HashMap<String, Object>();
MemberVO user = (MemberVO)session.getAttribute("user"); //로그인을 했는지 확인하기위해 (회원제 서비스이기 떄문에)
if(user == null) {
mapJson.put("result","success");
mapJson.put("result","noFav");
}else {
fav.setMem_num(user.getMem_num());
BoardReFavVO boardReFav = boardService.selecReFav(fav);
if(boardReFav!=null) {
mapJson.put("result","success");
mapJson.put("result","yesFav");
}else {
mapJson.put("result","success");
mapJson.put("result","noFav");
}
}
mapJson.put("count",boardService.selectReFavCount(fav.getRe_num()));
return mapJson;
}
'쌍용교육(JAVA) > SpringBoot' 카테고리의 다른 글
쌍용교육 -JSP수업 99일차 ch15SpringPage(10) (0) | 2024.07.08 |
---|---|
쌍용교육 -JSP수업 98일차 ch15SpringPage(9) (0) | 2024.07.05 |
쌍용교육 -JSP수업 96일차 ch15SpringPage(7) (0) | 2024.07.03 |
쌍용교육 -JSP수업 94일차 ch15SpringPage(5) (0) | 2024.07.01 |
쌍용교육 -JSP수업 93일차 ch15SpringPage(4) (0) | 2024.06.28 |