조원 4명이 게시판을 하나씩 맡아 구현하기로 하였습니다.
저는 정보 공유 게시판을 맡았습니다.
DataBase (Oracle)
테이블은 3개를 만들었습니다.
순서대로 게시판 테이블, 댓글 테이블, 추천 테이블 입니다.
-- 정보 게시판 Table
create table info_board(
num number(4) primary key, --게시글번호
nick varchar2(30), --작성자
title varchar2(100), --글제목
content varchar2(1000), --글내용
savedate date default sysdate, --작성일
hit number(4) default 0, --조회수
tag varchar2(20) --태그
);
create sequence info_board_seq;
-- 정보 게시판 댓글 Table
create table info_board_comment(
cnum number(4) PRIMARY key, --댓글고유번호
numgroup number(4) not null, --게시글번호
commentgroup number(4) not null, --댓글번호(대댓글이 몇번댓글에 달렸는지 확인할 때 사용)
nick varchar2(30) not null, --작성자
content varchar2(1000) not null, --댓글내용
savedate date default sysdate not null, --작성일
step number(4) not null --댓글은 0, 대댓글은 0 이상
);
create sequence info_board_comment_seq;
-- 정보 게시판 추천 Table
create table info_favorite(
num number, --게시글번호
userid varchar2(30), --추천인
CONSTRAINT a PRIMARY KEY (num,userid) --중복추전X
);
개발
사용된 주요 기술 : Mybatis, Trasaction, Ajax
1. 전체 목록 보기 페이지 / 검색 페이지
상세 기능 설계
① 전체 글 목록 또는 검색 결과에 맞는 전체 글 목록이 보이고, 글 제목 클릭시 글 상세보기 페이지로 넘어갑니다. 관리자가 쓴 글은 상단에 강조되어 보이고, 작성일이 오늘 날짜인 경우 시간으로 표시되고 new 표시를 띄웁니다. 게시글에 달린 댓글의 갯수를 표현합니다.
② 목록 밑의 글작성 버튼을 누르면 글작성 페이지로 넘어가게 구현하였습니다. 비로그인 상태라면 로그인 페이지로 넘어갑니다.
③ 공지, 이벤트 글을 제외하고 글을 10개씩 볼 수 있고, 더 많은 글을 보려면 페이지를 넘기도록 구현하기로 하였습니다.
④ 검색창을 구현하고 검색 페이지에는 무슨 키워드에 대한 검색 결과인지 알리는 문구를 띄웁니다.
상세 코드
InfoController
InfoService
InfoDAO
Info JDBC Config
=> Mybatis, Transaction 사용
*JDBC : Java Database Connectivity
=> 자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API
Mybatis => JDBC 중 하나
*Transaction
=> 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한
작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미
작업이 성공적으로 끝나면 -> commit 연산
하나의 트랜잭션 처리가 비정상적으로 종료되어 데이터베이스의 일관성을 깨뜨렸을 때 -> rollback연산
Info Mapper
2. 글작성 페이지 / 글수정 페이지
상세 기능 설계
① 태그를 선택할 수 있게 구현하였습니다. 로그인한 계정이 관리자라면 태그의 종류를 공지와 이벤트로 바꿔 띄웁니다.
② 글 내용 꾸미기 기능 및 사진 업로드 기능을 사용하기 위해 스마트 에디터를 사용했습니다. 완료 버튼을 누르면 제목과 글 내용이 비었는지를 확인하고, 게시판 테이블에 데이터를 저장합니다.
③ 직접 경로를 쳐서 들어와 글작성을 하는 것을 막는 스크립트를 작성하고, onload로 페이지가 로드되고 해당 스크립트를 실행되게 합니다.
상세 코드
InfoController
// 정보 게시판 글 작성 페이지
@RequestMapping("info_write")
public String info_write() {
return "sharing_info/info_write";
}
// 정보 게시판 글 저장 기능
@RequestMapping("info_save")
public String info_save(InfoDTO dto) {
int result=service.info_save(dto);
if(result==1) {
return "redirect:info_list?page=1";
}else {
return "redirect:info_write";
}
}
// 정보 게시판 글 수정 페이지
@RequestMapping("info_rewrite")
public String info_rewrite(@RequestParam int num, Model model) {
service.info_post(num,model);
return "sharing_info/info_rewrite";
}
// 정보 게시판 글 수정 기능
@RequestMapping("info_modify")
public String info_modify(InfoDTO dto) {
int result=service.info_modify(dto);
if(result==1) {
return "redirect:info_post?num="+dto.getNum();
}else {
return "redirect:info_rewrite?num="+dto.getNum();
}
}
InfoService
// 정보 게시판 글 저장 기능
public int info_save(InfoDTO dto) {
return dao.info_save(dto);
}
// 정보 게시판 글 수정 기능
public int info_modify(InfoDTO dto) {
return dao.info_modify(dto);
}
InfoDAO
// 정보 게시판 글 저장 기능
public int info_save(final InfoDTO dto) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
result=info_sqlSession.insert(namespace+".info_save",dto);
}
});
}catch (Exception e) {
e.printStackTrace();
}
return result;
}
// 정보 게시판 글 수정 기능
public int info_modify(final InfoDTO dto) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
result=info_sqlSession.update(namespace+".info_modify",dto);
}
});
}catch (Exception e) {
e.printStackTrace();
}
return result;
}
Info Mapper
<!-- 글 저장 기능 -->
<insert id="info_save" parameterType="infodto">
insert into info_board(num,nick,tag,title,content)
values (info_board_seq.nextval,#{nick},#{tag},#{title},#{content})
</insert>
<!-- 글 내용 가져오기 기능 -->
<select id="info_post" resultType="infodto" parameterType="int">
select * from info_board where num=#{num}
</select>
<!-- 조회수 기능 -->
<update id="info_uphit" parameterType="int">
update info_board set hit=hit+1 where num=#{num}
</update>
<!-- 글 수정 기능 -->
<update id="info_modify" parameterType="infodto">
update info_board set tag=#{tag}, title=#{title}, content=#{content} where num=#{num}
</update>
3. 글 상세보기 페이지
상세 기능 설계
① 글 목록 페이지에서 글제목을 누르면 넘어오는 구조입니다. DB에 저장된 글의 상세정보를 보여줍니다. 작성자 닉네임을 누르면 해당 유저의 여행수첩이 보입니다.
② 작성자 닉네임 옆의 하트를 누르면 추천이 되고, 다시 누르면 취소가 됩니다.
③ 신고버튼을 눌러 신고 사유를 입력하면 글을 신고할 수 있습니다. 관리자 계정에서 신고글들을 확인하고 관리할 수 있습니다.
④ 로그인한 계정과 해당 글의 작성자가 같을 경우 수정, 삭제 버튼이 보입니다. 로그인한 계정과 다를 경우 보이지 않습니다. 관리자 계정일 경우 삭제 버튼만 보입니다.
⑤ 댓글은 기본적으로 숨겨져 있고, 댓글보기를 클릭하면 댓글들이 보이게 구현하였습니다. 먼저 10개의 댓글이 보이고 더보기 버튼을 누르면 10개씩 더 보이게 구현하였습니다.
댓글 작성자가 글 작성자과 같다면 "작성자"라는 표시를 하고, 댓글 작성자가 관리자라면 "관리자"라는 표시를 합니다.
일반 유저는 본인의 댓글만 삭제, 수정할 수 있고 일반 유저가 댓글을 삭제할 경우 해당 댓글, 대댓글의 내용을 "삭제된 댓글입니다."라는 문구로 바꿔 저장합니다.
로그인한 계정이 관리자라면 모든 댓글을 삭제 할 수 있고 관리자가 삭제 시 테이블에 저장된 데이터 자체를 삭제합니다. 관리자가 대댓글 삭제 시 해당 대댓글만 삭제, 댓글 삭제 시 해당 댓글 밑에 달린 대댓글도 전부 삭제됩니다.
⑥ 댓글달기, 수정, 삭제 버튼을 클릭하면 해당 기능들을 페이지를 새로 로드하지 않고도 사용할 수 있게 Ajax 기법을 사용해 비동기식 웹 페이지를 구현하였습니다. 서버와 주고 받는 데이터는 Json 형태입니다.
상세 코드
*Ajax 정의
*JSON 정의
속성-값 쌍( attribute–value pairs and array data types (or any other serializable value)) 또는 "키-값 쌍"으로 이루어진
데이터 오브젝트를 전달하기 위해 인간이 읽을 수 있는 텍스트를 사용하는 개방형 표준 포맷이다.
InfoController
// 정보 게시판 글 상세보기 기능
@RequestMapping("info_post")
public String save(@RequestParam int num,Model model, HttpServletRequest request, HttpServletResponse response) {
service.info_post(num,model);
Cookie[] cookies = request.getCookies();
Cookie upHit = null;
if(cookies != null && cookies.length > 0) {
for(Cookie cookie : cookies) {
if(cookie.getName().equals("info"+num)) {
upHit = cookie;
}
}
}
if(upHit == null) {
Cookie cookie = new Cookie("info"+num, "upHit");
cookie.setMaxAge(60*60*24);
response.addCookie(cookie);
service.upHit(num);
}
service.info_post(num, model);
return "sharing_info/info_post";
}
// 정보 게시판 글 삭제 기능
@RequestMapping("info_delete")
public String info_delete(@RequestParam int num) {
int result=service.info_delete(num);
if(result==1) {
return "redirect:info_list?page=1";
}else {
return "redirect:info_post?num="+num;
}
}
/* 추천 */
// 추천하기
@RequestMapping(value="info_favoriteUp", produces = "application/json;charset=utf-8")
@ResponseBody
public String favoriteUp(FavoriteDTO dto) {
service.favoriteUp(dto);
return null;
}
// 추천취소
@RequestMapping(value="info_favoriteDown", produces = "application/json;charset=utf-8")
@ResponseBody
public String favoriteDown(FavoriteDTO dto) {
service.favoriteDown(dto);
return null;
}
// 추천수 가져오기
@RequestMapping(value="info_favorite", produces = "application/json;charset=utf-8")
@ResponseBody
public String favorite(FavoriteDTO dto) throws JsonProcessingException {
CommentNumber cn = service.favorite(dto);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(cn);
return json;
}
/* 신고 */
// 글 신고
@RequestMapping(value="report",method=RequestMethod.POST,
produces = "application/json;charset=utf-8")
@ResponseBody
public String report(ReportPostDTO dto) throws JsonProcessingException {
String result=service.report(dto);
ObjectMapper mapper=new ObjectMapper();
String strJson=mapper.writeValueAsString(result);
return strJson;
}
/* 댓글 기능 */
// 댓글 저장 기능
@RequestMapping(value="info_getCommentList",method=RequestMethod.POST,
produces = "application/json;charset=utf-8")
@ResponseBody
public String info_getCommentList(InfoCommentDTO dto) throws JsonProcessingException {
List<InfoCommentDTO> list=service.info_getCommentList(dto);
ObjectMapper mapper=new ObjectMapper();
String strJson=mapper.writeValueAsString(list);
return strJson;
}
@RequestMapping(value="info_comment_save",method=RequestMethod.POST,
produces = "application/json;charset=utf-8")
@ResponseBody
public String info_comment_save(InfoCommentDTO dto) throws JsonProcessingException {
List<InfoCommentDTO> list=service.comment_save(dto);
ObjectMapper mapper=new ObjectMapper();
String strJson=mapper.writeValueAsString(list);
return strJson;
}
// 댓글 수정 기능
@RequestMapping(value="info_comment_modify",method=RequestMethod.POST,
produces = "application/json;charset=utf-8")
@ResponseBody
public String info_comment_modify(InfoCommentDTO dto) throws JsonProcessingException {
List<InfoCommentDTO> list=service.comment_modify(dto);
ObjectMapper mapper=new ObjectMapper();
String strJson=mapper.writeValueAsString(list);
return strJson;
}
// 댓글 삭제 기능
@RequestMapping(value="info_comment_delete",method=RequestMethod.POST,
produces = "application/json;charset=utf-8")
@ResponseBody
public String info_comment_delete(InfoCommentDTO dto) throws JsonProcessingException {
List<InfoCommentDTO> list=service.comment_delete(dto);
ObjectMapper mapper=new ObjectMapper();
String strJson=mapper.writeValueAsString(list);
return strJson;
}
// admin 댓글 삭제 기능
@RequestMapping(value="comment_delete_admin",method=RequestMethod.POST,
produces = "application/json;charset=utf-8")
@ResponseBody
public String comment_delete_admin(InfoCommentDTO dto) throws JsonProcessingException {
List<InfoCommentDTO> list=service.comment_delete_admin(dto);
ObjectMapper mapper=new ObjectMapper();
String strJson=mapper.writeValueAsString(list);
return strJson;
}
// 대댓글 저장 기능
@RequestMapping(value="info_comment_reply_save",method=RequestMethod.POST,
produces = "application/json;charset=utf-8")
@ResponseBody
public String info_comment_reply_save(InfoCommentDTO dto) throws JsonProcessingException {
List<InfoCommentDTO> list=service.comment_reply_save(dto);
ObjectMapper mapper=new ObjectMapper();
String strJson=mapper.writeValueAsString(list);
return strJson;
}
InfoService
// 정보 게시판 글 상세보기 기능
public void info_post(int num,Model model) {
model.addAttribute("info_post",dao.info_post(num));
model.addAttribute("comment_list",dao.comment_list(num));
model.addAttribute("favoriteList",dao.postFavoriteList(num));
model.addAttribute("commentcount",dao.commentCount());
}
public void upHit(int num) {
dao.info_uphit(num);
}
// 정보 게시판 글 수정 기능
public int info_modify(InfoDTO dto) {
return dao.info_modify(dto);
}
// 정보 게시판 글 삭제 기능
public int info_delete(int num) {
return dao.info_delete(num);
}
/* 댓글 기능 */
// 댓글 전체 목록 가져오기
public List<InfoCommentDTO> info_getCommentList(InfoCommentDTO dto) {
return dao.comment_list(dto.getNumgroup());
}
// 댓글 저장 기능
public List<InfoCommentDTO> comment_save(InfoCommentDTO dto) {
dao.comment_save(dto);
return dao.comment_list(dto.getNumgroup());
}
// 댓글 수정 기능
public List<InfoCommentDTO> comment_modify(InfoCommentDTO dto) {
dao.comment_modify(dto);
return dao.comment_list(dto.getNumgroup());
}
// 댓글 삭제 기능
public List<InfoCommentDTO> comment_delete(InfoCommentDTO dto) {
dao.comment_delete(dto);
return dao.comment_list(dto.getNumgroup());
}
// admin 댓글 삭제 기능
public List<InfoCommentDTO> comment_delete_admin(InfoCommentDTO dto) {
dao.comment_delete_admin(dto);
return dao.comment_list(dto.getNumgroup());
}
// 대댓글 저장 기능
public List<InfoCommentDTO> comment_reply_save(InfoCommentDTO dto) {
dao.comment_reply_save(dto);
return dao.comment_list(dto.getNumgroup());
}
// 신고
public String report(ReportPostDTO dto) {
return dao.report(dto);
}
// 추천
public void favoriteUp(FavoriteDTO dto) {
dao.favoriteUp(dto);
}
// 추천 취소
public void favoriteDown(FavoriteDTO dto) {
dao.favoriteDown(dto);
}
// 게시글별 추천 수
public void favoriteList(Model model) {
model.addAttribute("favoriteList", dao.favoriteList());
}
// 게시글의 추천 수
public CommentNumber favorite(FavoriteDTO dto) {
return dao.favorite(dto);
}
InfoDAO
// 정보 게시판 글 상세보기 기능
public InfoDTO info_post(final int num) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
dto=info_sqlSession.selectOne(namespace+".info_post", num);
}
});
}catch (Exception e) {
e.printStackTrace();
}
return dto;
}
// 정보 게시판 조회수 기능
public void info_uphit(final int num) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
info_sqlSession.update(namespace+".info_uphit", num);
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
// 정보 게시판 글 삭제 기능
public int info_delete(final int num) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
result=info_sqlSession.delete(namespace+".info_delete",num);
info_sqlSession.delete(namespace+".info_delete_comment",num);
}
});
}catch (Exception e) {
e.printStackTrace();
}
return result;
}
/* 댓글 기능 */
// 댓글 리스트 가져오기 기능
public List<InfoCommentDTO> comment_list(final int num) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
comment_list=info_sqlSession.selectList(namespace+".comment_list",num);
System.out.println("댓글 리스트 가져오기 성공");
}
});
}catch (Exception e) {
e.printStackTrace();
}
return comment_list;
}
//댓글 수 표시 기능
public List<CommentNumber> commentCount(){
return info_sqlSession.selectList(namespace+".commentcount");
}
// 댓글 저장 기능
public void comment_save(final InfoCommentDTO dto) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
info_sqlSession.update(namespace+".replyShape",dto);
result=info_sqlSession.insert(namespace+".comment_save",dto);
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
// 댓글 수정 기능
public void comment_modify(final InfoCommentDTO dto) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
result=info_sqlSession.insert(namespace+".comment_modify",dto);
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
// 댓글 삭제 기능
public void comment_delete(final InfoCommentDTO dto) {
dto.setContent("<b>삭제된 댓글입니다.</b>");
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
result=info_sqlSession.insert(namespace+".comment_delete",dto);
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
// admin 댓글 삭제 기능
public void comment_delete_admin(final InfoCommentDTO dto) {
dto.setContent("삭제된 댓글입니다.");
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
System.out.println(dto.getCnum());
System.out.println(dto.getCommentgroup());
if(dto.getCnum()==dto.getCommentgroup()) {
result=info_sqlSession.insert(namespace+".comment_reply_delete_admin",dto);
}else {
result=info_sqlSession.insert(namespace+".comment_delete_admin",dto);
}
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
// 대댓글 저장 기능
public void comment_reply_save(final InfoCommentDTO dto) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
result=info_sqlSession.insert(namespace+".comment_reply_save",dto);
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
// 게시글 신고
public String report(final ReportPostDTO dto2) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
result=info_sqlSession.insert(namespace+".report",dto2);
}
});
}catch (Exception e) {
e.printStackTrace();
}
System.out.println(result);
if(result==1) {
return "신고 성공";
}else {
return "신고 실패";
}
}
// 추천 눌렀을 때
public void favoriteUp(final FavoriteDTO dto) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
info_sqlSession.insert(namespace+".favoriteUp", dto);
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
// 추천취소
public void favoriteDown(final FavoriteDTO dto) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
info_sqlSession.delete(namespace+".favoriteDown", dto);
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
// 추천 전체 목록 가져오기
List<CommentNumber> cnlist;
public List<CommentNumber> favoriteList() {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
cnlist=info_sqlSession.selectList(namespace+".favoriteList");
}
});
}catch (Exception e) {
e.printStackTrace();
}
return cnlist;
}
CommentNumber cn;
public CommentNumber favorite(final FavoriteDTO dto) {
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
cn=info_sqlSession.selectOne(namespace+".favorite", dto);
}
});
}catch (Exception e) {
e.printStackTrace();
}
return cn;
}
// 특정 게시글의 추천수 가져오기
List<FavoriteDTO> favorite;
public List<FavoriteDTO> postFavoriteList(final int num){
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
favorite=info_sqlSession.selectList(namespace+".postFavoriteList", num);
}
});
}catch (Exception e) {
e.printStackTrace();
}
return favorite;
}
Info Mapper
<!-- 글 내용 가져오기 기능 -->
<select id="info_post" resultType="infodto" parameterType="int">
select * from info_board where num=#{num}
</select>
<!-- 조회수 기능 -->
<update id="info_uphit" parameterType="int">
update info_board set hit=hit+1 where num=#{num}
</update>
<!-- 글 삭제 기능 -->
<delete id="info_delete" parameterType="int">
delete from info_board where num=#{num}
</delete>
<!-- 글 삭제시 댓글들 삭제 기능 -->
<delete id="info_delete_comment" parameterType="int">
delete from info_board_comment where numgroup=#{numgroup}
</delete>
<!-- 댓글 전체 목록 가져오기 -->
<select id="comment_list" resultType="commentdto">
select * from info_board_comment where numgroup=#{numgroup}
order by commentgroup asc, cnum asc
</select>
<!-- 댓글 저장 기능 -->
<insert id="comment_save" parameterType="commentdto">
insert into info_board_comment(cnum,numgroup,commentgroup,nick,content,step)
values(info_board_comment_seq.nextval, #{numgroup}, info_board_comment_seq.currval, #{nick}, #{content}, #{step})
</insert>
<!-- 대댓글 저장 기능 -->
<insert id="comment_reply_save" parameterType="commentdto">
insert into info_board_comment(cnum,numgroup,commentgroup,nick,content,step)
values(info_board_comment_seq.nextval,#{numgroup},#{commentgroup},#{nick},#{content},#{step})
</insert>
<!-- 댓글 정렬하는 기능 -->
<update id="replyShape" >
update info_board_comment set step=step+1 where numgroup=#{numgroup} and step > #{step}
</update>
<!-- 댓글 수정 기능 -->
<update id="comment_modify" parameterType="commentdto">
update info_board_comment set content=#{content} where cnum=#{cnum}
</update>
<!-- 댓글 삭제 기능 -->
<update id="comment_delete" parameterType="commentdto">
update info_board_comment set content=#{content} where cnum=#{cnum}
</update>
<delete id="comment_delete_admin" parameterType="commentdto">
delete from info_board_comment where cnum=#{cnum}
</delete>
<delete id="comment_reply_delete_admin" parameterType="commentdto">
delete from info_board_comment where commentgroup=#{commentgroup}
</delete>
<!-- 게시글 신고 -->
<insert id="report">
insert into report_post values(#{board},#{num},#{title},#{content},#{writer},#{usernick})
</insert>
<!-- 게시글 추천 -->
<insert id="favoriteUp">
insert into info_favorite values(#{num}, #{userid})
</insert>
<!-- 게시글 추천 취소 -->
<delete id="favoriteDown">
delete from info_favorite where num=#{num} and userid=#{userid}
</delete>
<!-- 게시글 추천 불러오기 -->
<select id="favorite" resultType="com.cpkl.dto.CommentNumber">
select num, (count(*))count from info_favorite group by num having
num=#{num}
</select>
<!-- 게시글 목록 추천 불러오기 -->
<select id="favoriteList" resultType="com.cpkl.dto.CommentNumber">
select num, (count(*))count from info_favorite group by num
</select>
<!-- 게시글 추천 목록 -->
<select id="postFavoriteList" resultType="com.cpkl.dto.FavoriteDTO">
select*from info_favorite where num=#{num}
</select>
<!-- 게시글 별 댓글 수 -->
<select id="commentcount" resultType="cn">
select numgroup, (count(*))count from info_board_comment group by numgroup
</select>
전체 파일
Java
JDBC (Mybatis)
JSP
'Java > Spring 프로젝트' 카테고리의 다른 글
1. Github 협업 준비 (0) | 2020.07.19 |
---|---|
0. 프로젝트 설계 [Travelers] (0) | 2020.06.26 |