빅데이터 Java 개발자 교육 - 09일차 [DB의 내용을 Swing JFrame으로 나타내기-2 (댓글, 게시글)]

Jun_Gyu·2023년 2월 26일
0


지난시간 DB의 내용을 swing을 통하여 나타내는 실습을 진행하였고,

3번째 메소드까지 작성을 완료하였다.

package day8;

import java.util.List;

public interface BookDB {
	// 책등록 (int인 이유는 책넘버가 int이기 때문! (_id ))
	public int insertBook(Book book);

	// 책 전체조회
	public List<Book> selectBookList();

	// 책 10개씩 조회
	public List<Book> selectBookListPage(int page);
/*-------------------------------------- 요까지 함! ----------------------------------------*/
	// 책 삭제
	public int deleteBook(int no);

	// 책 수정
	public int updateBook(Book book);

	// 책1권 조회 // 반환타입
	public Book selectOneBook(int no);

	// n이상의 가격에 해당하는 책 조회
	public List<Book> selectBookPrice(long price);

	// 분류에 해당하는 항목만 조회
	public List<Book> selectBookCate(char cate);

}

이 부분들에 대해서는 추후에 복습을 진행하면서 기능을 완성해보도록 하자.


오늘은 저번 7일차에 만들었던 게시판의 기능에 들어갈

'댓글'기능을 추가할 예정이다.

들어가기 앞서서 생성자에서 사용할 값들이다.



바로 사용하기 간편하도록 위와같이 설정을 해주었다. 먼저 댓글의 뼈대가 되어 줄 reply class를 만들어 주자.

package day9;

import java.util.Date;
import lombok.Data;

//import lombok.AllArgsConstructor;
//import lombok.Getter;
//import lombok.NoArgsConstructor;
//import lombok.Setter;
//import lombok.ToString;

@Data // 지금까지 썻던 롬복 데이터를 한번에 불러옴! [블로그]
//@Getter
//@Setter
//@ToString
//@AllArgsConstructor
//@NoArgsConstructor

//답글번호 (시퀀스사용), 답글내용, 작성자, 등록일, 원본게시글 정보
public class Reply {
	private long no = 0L;
	private String content = null;
	private String writer = null;
	private Date regdate = null;
	private Board board = null;
}

그 다음으로는 설계도인 interface이다.

package day9;

import java.util.List;

// DB연동 설계
public interface ReplyDB {

// 댓글입력
	public short insertReply( Reply reply ) throws Exception; // 오류발생시 넘김

// 댓글수정
	public short updateReply( Reply reply ) throws Exception;

// 댓글삭제
	public short deleteReply( long no ) throws Exception;

// 댓글 한개 선택하기
	public Reply selectReplyOne( long no );

// 문제) 원본게시글 번호를 전달하면 해당하는 모든 답글을 반환하기.
	public List<Reply> selectReplyList(long boardNo);

}

다음으로는 implements 클래스인 ReplyDBImpl 이다.

package day9;

import java.util.List;
import java.util.Vector;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.InsertOneResult;
import com.mongodb.client.result.UpdateResult;

import day8.Config;

public class ReplyDBImpl implements ReplyDB {
	/*------------------------------------------변수 지정.--------------------------------------*/
	private MongoCollection<Document> sequence = null;
	private MongoCollection<Document> replies = null;
	// 생성자
	// DB접속 및 컬렉션 선택
	public ReplyDBImpl() {
		try {// 몽고DB -> 접속URL -> DB이름
			MongoClient client = MongoClients.create(Config.URL);
			MongoDatabase db = client.getDatabase(Config.DBNAME);
			sequence = db.getCollection(Config.RESEQUENCECOL);
			replies = db.getCollection(Config.REPLYCOL);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	// 댓글 입력
	@Override
	public short insertReply(Reply reply) throws Exception {

		Document doc = sequence.findOneAndUpdate(Filters.eq("_id", "SEQ_REPLY_NO"), Updates.inc("idx", 2));
		// Document{{_id=SEQ_REPLY_NO, idx=210}}
		System.out.println(doc.toString());
		long idx = doc.getInteger("idx");

		Document doc1 = new Document().append("_id", idx).append("content", reply.getContent())
				.append("writer", reply.getWriter()).append("regdate", reply.getRegdate())
				// 전체적인 데이터를 추가하는것이 아니라, 기본키정보(게시글번호)만 DB에 추가함.
				.append("board", reply.getBoard().getBrdNo());

		// DB에 데이터가 정확하게 추가되면 반환값으로 답글번호를 반환.
		InsertOneResult result = this.replies.insertOne(doc1);

		System.out.println(result.toString());
		if (result.getInsertedId().asInt64().getValue() == idx) {
			return 1;
		}
		return 0;

	}
	/*-----------------------------------------------------------------------------------------------------*/

	// 수정
	@Override
	public short updateReply(Reply reply) throws Exception {
		
		// 변경하고자 하는 항목의 조건
		Bson filter = Filters.eq("_id", reply.getNo());
		// 변경할 항목들 "내용, 작성자"
		Bson update1 = Updates.set("content", reply.getContent());
		Bson update2 = Updates.set("writer", reply.getWriter());
		// updateOne (조건, 변경값) => 변경값이 하나의 Bson에만 가능.. combine
		Bson update = Updates.combine(update1, update2);
		UpdateResult result = this.replies.updateOne(filter, update);
		if (result.getModifiedCount() == 1) {
			return 1;
		}
		return 0;
	}
	/*-----------------------------------------------------------------------------------------------------*/

	// 삭제
	@Override
	public short deleteReply(long no) throws Exception {

		Bson filter = Filters.eq("_id", no);
		DeleteResult result = this.replies.deleteOne(filter);
		System.out.println(result.toString());
		if (result.getDeletedCount() == 1L) {
			return 1;

		}
		return -1;
	}

	/*-----------------------------------------------------------------------------------------------------*/

	// 한개 가져오기
	// replyno는 답글번호
	@Override
	public Reply selectReplyOne(long replyNo) {
		try {
			// doc값이 null경우는 해당하는 답글이 없음.
			// doc값이 null아니면 해당하는 답글이 존재한다.
			Document doc = this.replies.find(Filters.eq("_id", replyNo)).first();
			if (doc != null) { // Document -> Reply 타입으로 복사한 후 리턴
				Reply reply = new Reply();
				reply.setNo(doc.getLong("_id"));
				reply.setContent(doc.getString("dontent"));
				reply.setWriter(doc.getString("writer"));
				reply.setRegdate(doc.getDate("regdate"));

				Board board = new Board();
				board.setBrdNo(doc.getLong("board"));

				reply.setBoard(board);

				return reply;
			}
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	/*-----------------------------------------------------------------------------------------------------*/
// 문제 ) 원본게시글 번호를 전달하면 해당하는 모든 답글을 반환하기.
	@Override
	public List<Reply> selectReplyList(long boardNo) {
		try {
			Bson filter = Filters.eq("board", boardNo);
			Bson sort = Filters.eq("_id", -1);

			this.replies.find(filter).sort(sort);
			FindIterable<Document> docs = this.replies.find(filter).sort(sort);
			// FindIterable<Document> => List<Reply>

			// 인터페이스<> 객체명 = new 컬렉션 클래스();
			List<Reply> list = new Vector<Reply>();
			for (Document doc : docs) {
				Reply reply = new Reply();
				reply.setNo(doc.getLong("_id"));
				reply.setContent(doc.getString("dontent"));
				reply.setWriter(doc.getString("writer"));
				reply.setRegdate(doc.getDate("regdate"));
				reply.setBoard(null);

				list.add(reply);
                }
			if (!list.isEmpty()) {
				return list;
			}
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}  
}

이를 바탕으로 Main에서 실행시켜보았다.

package day9;

import java.util.List;
import java.util.Scanner;
import java.util.Vector;

public class Main {

	public static void main(String[] args) {
		try {
			/*----------답글의 갯수가 n개인 게시글 조회-----------------------------------------------------------------------------------*/
//			BoardDAO boardDAO = new BoardDAOImpl();
//			List<Board> list = boardDAO.selectBoardReplyCount(1);
//			for (Board board : list) {
//				System.out.println("┌---------------┐");
//				System.out.println("게시글번호 => " + board.getBrdNo());
//				System.out.println("게시글제목 => " + board.getBrdTitle());
//				System.out.println("게시글작성자 => " + board.getBrdContent());
//				System.out.println("게시글조회수 => " + board.getBrdHit());
//				System.out.println("게시글 날짜 => " + board.getBrdDate());
//				System.out.println("└---------------┘");
//			}
			
			/*-------댓글갯수 및 답글 번호 조회--------------------------------------------------------------------------------------*/
//			BoardDAO boardDAO = new BoardDAOImpl();
//			List<Board> list = boardDAO.selectBoardList();
//			for(Board board : list) {
//				System.out.println("┌---------------┐");
//				System.out.println("게시글번호 => " + board.getBrdNo());
//				System.out.println("게시글제목 => " + board.getBrdTitle());
//				System.out.println("게시글작성자 => " + board.getBrdContent());
//				System.out.println("게시글조회수 => " + board.getBrdHit());
//				System.out.println("게시글 날짜 => " + board.getBrdDate());
//				System.out.println("댓글 갯수 => " + board.getReplyCount());
//				System.out.println("답글 번호는 => ");
//				for(int i=0; i<board.getReplyNolist().size();i++) {
//				System.out.println(board.getReplyNolist().get(i) + ", ");
//				}
//				System.out.println("└---------------┘");
//			}
//			
			/*-------댓글조회--------------------------------------------------------------------------------------*/

			// 답글번호 한개 조회하기
			// 입력기능 추가
//			System.out.print("조회 할 답글번호를 눌러주세요. : ");
//			Scanner sc = new Scanner(System.in);
//            
//			ReplyDB replyDB = new ReplyDBImpl();
//		    Reply reply = replyDB.selectReplyOne(sc.nextLong()); // 해당 번호의 글 불러오기
//		    if(reply!=null) {
//			System.out.println("┌---------------------------------------┐");
//			System.out.println("답글번호 => " + reply.getNo());
//			System.out.println("답글내용 => " + reply.getContent());
//			System.out.println("답글작성자 => " + reply.getWriter());
//			System.out.println("답글일자 => " + reply.getRegdate());
//			System.out.println("원본게시글 정보 => " + reply.getNo());
//			System.out.println("└---------------------------------------┘");
//			}
			/*-----------------------------------------------------------------------------------------------------*/
			/*
			 * // 답글 쓰기 테스트 Reply reply = new Reply(); reply.setContent("content2");
			 * reply.setWriter("writer2"); reply.setRegdate(new Date()); // String => long
			 * 
			 * Board board = new Board(); board.setBrdNo(1L);
			 * 
			 * reply.setBoard(board); short ret = replyDB.insertReply(reply);
			 * System.out.println(ret);
			 */
			/*-------게시글번호의 댓글 조회----------------------------------------------------------------------------------------*/

//			ReplyDB replyDB = new ReplyDBImpl();
//			List<Reply> list = replyDB.selectReplyList(4L); // 해당 번호의 글 불러오기
//			for (Reply one : list) {
//				System.out.println("┌---------------------------------------┐");
//				System.out.println("답글번호 => " + one.getNo());
//				System.out.println("답글내용 => " + one.getContent());
//				System.out.println("답글작성자 => " + one.getWriter());
//				System.out.println("답글일자 => " + one.getRegdate());
//				System.out.println("└---------------------------------------┘");
//			}

			/*---------삭제하기---------------------------------------------------------------------------------------*/

//			ReplyDB obj = new ReplyDBImpl();
//			obj.deleteReply(231);

			/*---------댓글 수정하기--------------------------------------------------------------------------------------*/
//			ReplyDB replyDB = new ReplyDBImpl();
//			Reply reply = new Reply();
//			
//			System.out.print("조회할 글의 번호를 입력 해주세요. : ");
//			Scanner sc = new Scanner(System.in);
//			reply.setNo(sc.nextShort());
//			System.out.print("수정할 글의 내용을 입력 해주세요. : ");
//			reply.setContent(sc.next());
//			System.out.print("수정할 글의 작성자를 입력 해주세요. : ");
//			reply.setWriter(sc.next());
//			sc.close();
//
//			short ret = replyDB.updateReply(reply);
//
//			System.out.println(ret);

		    /*---------게시판 번호 불러와서 수정하기--------------------------------------------------------------------------------------*/

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

기능이 정상적으로 작동되는지의 여부를 확인하기 위하여 따로따로 변수를 지정해주었다.

추가로 7일차에 작성하였던 '게시판' 인터페이스를 가져와서 오늘 만든 댓글 인터페이스와 함께 잘 연동되는지에 대해서도 실습을 진행해보았다.

(위의 메인소스코드에 잘 보면 맨 첫번째와 두번째코드가 게시글과 함께 연동된 코드임을 알 수 있따.)

package day9;

import java.util.Date;
import java.util.List;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString

public class Board {

	private long brdNo = 0L;
	private String brdTitle = "";
	private String brdContent = "";
	private String brdWriter = "";
	private long brdHit = 100L;
	private Date brdDate = null;
	/*--------------------오늘 추가한 두가지-------------------------*/
	private int replyCount = 0; // 답글개수를 보관할 변수
	private List<Long> replyNolist = null;

오늘은 저 두가지 변수를 추가하여 n개의 댓글이 달린 게시글은 몇개있는지, 모든 게시글들이 댓글은 몇개가있는지(몇번까지있는지) 에 대해서 기능을 사용할 수 있도록 진행했다.

package day9;

import java.util.List;

public interface BoardDAO {

	// 답글의 갯수가 n개 이상인 게시글 조회
	public List<Board> selectBoardReplyCount(int n);
/*
	// 게시글 추가
	public int insertBoard(Board board);

	// 게시글 수정
	public int updateBoard(Board board);

	// 게시글 삭제
	public int deleteBoard(long no);
*/
	// 전체 조회  // 여기에도 한가지 기능만 추가하였다.
	public List<Board> selectBoardList();
/*
	// 게시글 수에 따른 조회 ex)n보다 큰 경우
	public List<Board> selectBoardHitList(long hit);

	// 게시글 1개 조회
	public Board selectBoardOne(long no);
*/
}

인터페이스에는 한가지 기능을 더 추가하였고, 이를 바탕으로 implement에는 아래의 내용으로 구성하였다.

@Override
	public List<Board> selectBoardReplyCount(int n) { // n개 입력
		try {

			// 1. 전체 게시글을 가져옴.
			FindIterable<Document> list = this.boardColl.find(); // DB의 Board를 모두 불러온 배열

			// 2. 반복한다
			List<Board> retList = new ArrayList<Board>();
			for (Document doc : list) {

				// 3. 게시글 번호를 이용해서 답글의 개수를 구한다.
                // 구하고자 하는 부분을 필터로 만듦.
				Bson filter = Filters.eq("board", doc.getLong("_id")); // 여기가 제일 헷갈렷던 부분.

				long replyCount = this.replies.countDocuments(filter); // 전체 게시글에서 댓글갯수를 카운트.
				if (replyCount >= n) { // 댓글의 개수가 n보다 크다면
					Board board = new Board(); // board 객체를 만든 뒤
					board.setBrdNo(doc.getLong("_id"));
					board.setBrdTitle(doc.getString("title"));
					board.setBrdContent(doc.getString("content"));
					board.setBrdWriter(doc.getString("writer"));
					board.setBrdHit(doc.getLong("hit"));
					board.setBrdDate(doc.getDate("date"));   // 위의 모든 값들을 전부 board에 저장함.
					retList.add(board);  // 위의 반복된 board 값을 retList에 추가한다.
				}
			}
			return retList; // retList값 반환.
		} catch (Exception e) {
			e.printStackTrace();
			return null; // 아님말고
	}
}

메인에서 실행시킨 코드는 위의 메인클래스 참고할것!

profile
시작은 미약하지만, 그 끝은 창대하리라

0개의 댓글