반응형
목차
jQuery .ajax() 😄
미래의 내가 보기 위해 남겨둠
jQuery의 ajax 사용법만 간단히 남기려고 했으나 예시 코드에 있는 코드들도 같이 적는게 좋을 듯 싶어서 같이 남김
// 예시
$.ajax({
// 호출 url
url: '/reply/insert',
// 전달방식
type: 'post',
// dataType: "json" // 데이터타입 json으로 할 경우
// 전달할 데이터
data: {'boardId': boardId, 'replyContent': replyContent, 'replyWriter': replyWriter},
// 성공 시 콜백 함수, 밑에 실패 시 콜백도 만들어도 좋다.
success: function (data) {
getRelyList();
}
// 댓글 조회 예시
function getRelyList(){
let boardId = $("#boardId").val();
$.ajax({
url:'/reply/list',
type:'get',
// 게시글에 대한 댓글 목록이므로 boardId를 넘김
// 이렇게 조회해야 되서(SELECT * FROM reply WHERE board_id = #{boardId})
data:{'boardId':boardId},
success:function(data){
// 댓글 페이지네이션 처리를 위한 변수(이전, 다음 존재여부, 시작~끝값)
let prev = data.pageMaker.prev;
let next = data.pageMaker.next;
let startPage = data.pageMaker.startPage;
parseInt(startPage);
let isPrev = startPage - 1;
let endPage = data.pageMaker.endPage;
parseInt(endPage);
let isNext = endPage + 1;
// console.log('prev : ' + prev + '\n' + 'next : ' + next + '\n' + 'startPage : ' + startPage + '\n' + 'endPage : ' + endPage);
// 서버에서 가져온 댓글 데이터를 $.each로 루프 돌려서 <div id="replyList">여기에 넣음</div>
let replyHtml = "";
$.each(data.replyList,function(key,value){
replyHtml += '<div>';
replyHtml += '<div>' + '댓글번호:'+ value.replyId+ ' / 작성자:' + value.replyWriter + ' / 작성일: ' + value.regDate;
// click 이벤트안에 parameter 넣을 때 ""안에 ''를 붙여줘야 함(이게 처음 할 땐 은근히 스트레스)
replyHtml += '<button onclick="replyUpdateForm('+ value.replyId +',\'' + value.replyContent + '\');">수정</button>';
replyHtml += '<button onclick="replyDelete(' + value.replyId + ');">삭제</button></div>';
replyHtml += '<div id="replyContentArea"><p>내용:'+value.replyContent+'</p>';
replyHtml += '</div>';
});
$("#replyList").html(replyHtml);
// 페이지네이션 표시
viewPagination(boardId, prev, next, startPage, endPage, isPrev, isNext);
}});
}
// 페이지네이션 처리(어떤 식으로 하는 원리만 알기 위한 예제라서 간단하게 함)
function viewPagination(boardId, prev, next, startPage, endPage, isPrev, isNext) {
// console.log('prev: ' + prev + '\n' + 'next: ' + next + '\n' + 'startPage: ' + startPage + '\n' + 'endPage: ' + endPage + '\n' + 'isPrev: ' + isPrev + '\n' + 'isNext: ' + isNext);
// 페이지네이션 영역
let replyPagination = "";
// 이전 페이지
if (prev == true) {
replyPagination += '<li>';
replyPagination += '<a href="/reply/list?boardId=' + boardId + '&pageNum=' + isPrev +'">' + "Prev" + '</a>';
replyPagination += '</li>';
}
for (let num = startPage; num <= endPage; num++) {
replyPagination += '<li>';
replyPagination += '<a href="/reply/list?boardId=' + boardId + '&pageNum=' + num +'">' + num + '</a>';
replyPagination += '</li>';
}
// 다음 페이지
if (next == true && endPage > 0) {
replyPagination += '<li>';
replyPagination += '<a href="/reply/list?boardId=' + boardId + '&pageNum=' + isNext +'">' + "Next" + '</a>';
replyPagination += '</li>';
}
// 페이지네이션 영역을 div에 붙임
$("#reply-pagination").html(replyPagination);
}
// 댓글 리스트 영역
<div class="container">
<div id="replyList"></div>
</div>
// 댓글 페이지네이션 영역
<div>
<ul id="reply-pagination" class="pagination pagination-sm no-margin pull-right"></ul>
</div>
controller
// boardId와 Criteria를 받아서 댓글 목록 반환
@GetMapping("/reply/list")
@ResponseBody
public Map<String, Object> replyListPaging(@RequestParam("boardId") Long boardId, Criteria cri) {
Map<String, Object> map = new HashMap<>();
List<ReplyVO> replyList = replyService.findReplyListPaging(boardId, cri);
int replyCount = replyService.findCount(boardId);
// 댓글 목록
map.put("replyList", replyList);
// 페이지네이션 화면 처리 데이터
map.put("pageMaker", new PageMaker(replyCount, cri));
return map;
}
service
package paging.study.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import paging.study.domain.Criteria;
import paging.study.domain.vo.ReplyVO;
import paging.study.mapper.ReplyMapper;
import java.util.List;
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional(readOnly = true)
public class ReplyService {
private final ReplyMapper replyMapper;
public List<ReplyVO> findReplyListPaging(Long boardId, Criteria cri) {
return replyMapper.findReplyListPaging(boardId, cri);
}
public int findCount(Long replyId) {
return replyMapper.findCount(replyId);
}
}
mapper
package paging.study.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import paging.study.domain.Criteria;
import paging.study.domain.vo.ReplyVO;
import java.util.List;
@Mapper
public interface ReplyMapper {
List<ReplyVO> findReplyListPaging(@Param("boardId") Long boardId, @Param("cri") Criteria cri);
int findCount(Long boardId);
}
mapper 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="paging.study.mapper.ReplyMapper">
<resultMap id="replydMap" type="paging.study.domain.vo.ReplyVO">
<id column="reply_id" property="replyId"/>
<result column="board_id" property="boardId"/>
<result column="reply_content" property="replyContent"/>
<result column="reply_writer" property="replyWriter"/>
<result column="reg_date" property="regDate"/>
<result column="update_date" property="updateDate"/>
</resultMap>
<select id="findReplyListPaging" parameterType="map" resultMap="replydMap">
SELECT * FROM t_reply
WHERE board_id = #{boardId}
ORDER BY reg_date DESC
limit #{cri.limitStart}, #{cri.amount}
</select>
<select id="findCount" parameterType="Long" resultType="int">
SELECT COUNT(*) FROM t_reply
WHERE board_id = #{boardId}
</select>
</mapper>
ReplyVO
package paging.study.domain.vo;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDateTime;
// 댓글 용도
@Getter @Setter
@ToString
@NoArgsConstructor
public class ReplyVO {
private Long replyId;
private Long boardId;
private String replyContent;
private String replyWriter;
private LocalDateTime regDate;
private LocalDateTime updateDate;
public ReplyVO(Long boardId, String replyContent, String replyWriter) {
this.boardId = boardId;
this.replyContent = replyContent;
this.replyWriter = replyWriter;
}
}
Criteria
package paging.study.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter @Setter
@ToString
public class Criteria {
// for paging
private int pageNum; // 페이지 번호(현재 페이지가 몇 페이지인지)
private int amount; // 한 화면에 출력한 페이지 개수
private int limitStart; // 쿼리에서 (pageNum -1) * amount 사용하기 위한 변수
// for search
private String title;
private String name;
// 기본 생성자에서 강제로 페이지 번호와 출력 페이지 수 세팅(페이지네이션 정책에 따라 변경하면 됨)
public Criteria() {
this(1,10);
}
public Criteria(int pageNum, int amount) {
this.pageNum = pageNum;
this.amount = amount;
}
// 쿼리에서 limit 1번 째 parameter로 쓸 값(mybatis에서 이 getter 이용해서 값을 )
public int getLimitStart() {
return this.limitStart = (pageNum - 1) * this.amount;
}
}
PageMaker
package paging.study.domain.paging;
import lombok.Getter;
import lombok.ToString;
import paging.study.domain.Criteria;
@Getter @ToString
// 실제 페이지네이션 화면 처리 계산 담당(공통 모듈)
public class PageMaker {
private int startPage; //페이징 화면 하단의 시작 번호(5페이지라고 하면 [1][2][3][4][5] 여기서 제일 첫 번 째 시작번호인 [1])
private int endPage; //페이징 화면 하단의 끝 번호(5페이지라고 하면 [1][2][3][4][5] 여기서 제일 끝 번호인 [5])
private boolean prev, next; // 이전, 다음 존재 여부
private int totalCount; // 전체 게시글 수
private Criteria cri; // 프론트에서 전달하는 pageNum(현재 페이지), amount(출력 페이지) 전달 역할
public PageMaker(int totalCount, Criteria cri) {
this.totalCount = totalCount;
this.cri = cri;
this.endPage = (int)(Math.ceil(cri.getPageNum() / 10.0) * 10);
this.startPage = this.endPage - 9;
// 실제 끝 번호
int realEnd = (int)(Math.ceil(totalCount * 1.0) / cri.getAmount());
if (realEnd < this.endPage) {
this.endPage = realEnd;
}
this.prev = this.startPage > 1;
this.next = this.endPage < realEnd;
}
}
댓글 table
-- 댓글
CREATE TABLE t_reply(
reply_id bigint auto_increment,
board_id bigint,
reply_content varchar (30),
reply_writer varchar (30),
reg_date timestamp,
update_date timestamp,
primary key(reply_id)
);
jQeury에서 ajax를 어떤 식으로 쓰는지 알기 위한 간단한 예제임
to 미래의 너 그대로 가져다 쓰진 말고 수정해서 쓰는걸 권장함(유지보수나 확장성 등을 고려하고 짠 소스가 아님)
반응형
'IT > development' 카테고리의 다른 글
[JavaScript] submit control(feat. onsubmit) (0) | 2022.11.22 |
---|---|
[spring Boot] Request method 'POST' not supported(feat. thymeleaf) (0) | 2022.11.22 |
[IDE] intellJ IDEA live template 생성 (0) | 2022.11.21 |
[mybatis] mybatis 이중 foreach insert(feat. 이중 계층 객체 저장) (0) | 2022.11.21 |
[Spring data JPA] 초간단 CRUD (0) | 2022.11.21 |