[Java] MongoDB 이용해서 웹페이지 구현하기

반응형

 

MongoDB Atlas란?

  • MongoDB의 완전 관리형 클라우드 데이터베이스 서비스
  • 데이터베이스를 클라우드에서 호스팅 하고 관리하는 것을 중심으로 함
  • 개발자 및 기업이 손쉽게 애플리케이션을 빌드하고 배포할 수 있도록 지원함
  • AWS, Azure, GCP를 통해 배포에 관한 모든 것을 통합 관리해 줌
  • 클라우드 환경에서 사용할 수 있으며 나의 컴퓨팅 자원을 소모하지 않고 사용할 수 있는 원격 DB가 생성됨

 

MongoDB Atlas 다운로드

 

 

MongoDB Atlas: Cloud Document Database

Cloud-hosted MongoDB service on AWS, Azure, and GCP

www.mongodb.com

- Start Free 누른 후 가입하기

 

- 가입 후 파일 다운로드

 

- 다운로드 완료

 

- test > test에 데이터 입력하기

 

- Json 형식으로 key와 value를 입력하기

 

- 입력한 값이 잘 들어감

 

MongoDB와 JAVA 연결하기

 

01) 새로운 project 생성

 

02) Application.properties 설정

- 위와 같이 접속 정보를 확인한 후 아래의 코드에서 uri에 붙여 넣기

server.port=80 # thymeleaf호출시 경로 설정 spring.thymeleaf.cache=false spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html ## MongoDB Config ## spring.data.mongodb.uri=mongodb+srv://id:password@cluster0.tl1qsf1.mongodb.net/ spring.data.mongodb.database=name

 

03) Test.java 생성 

- 데이터베이스 테이블과 일치하는 객체 설정하기

package com.peazh.entity; import java.util.Map; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @Document(collection = "test") //mongoDB에서 연결할 테이블명 입력 @AllArgsConstructor @NoArgsConstructor public class Test { @Id private String id; private int age; private String name; private Map<String, String> hobby; }

- @AllArgsConstructor : 모든 필드를 매개 변수로 받아 객체를 생성할 때 사용할 수 있는 생성자를 만들어 줌

- @NoArgsConstructor : 매개변수가 없는 기본 생성자를 자동으로 생성함

 

04) TestController.java 생성

package com.peazh.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import com.peazh.entity.Test; import com.peazh.service.TestService; @Controller public class TestController { @Autowired private TestService testService; @GetMapping("/test") public String test(Model model) {// 데이터베이스의 값을 저장하고 타임리프로 보내주는 역할 ‌‌List<Test> list = testService.list(); ‌‌model.addAttribute("list",list); ‌‌return "test"; } }

 

05) TestService.java 생성

package com.peazh.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.peazh.entity.Test; import com.peazh.repository.TestRepository; @Service public class TestService { @Autowired private TestRepository testRepository; public List<Test> list() { ‌‌return testRepository.findAll(); } }

 

06) TestRepository.java 생성 (interface)

package com.peazh.repository; import org.springframework.data.mongodb.repository.MongoRepository; import com.peazh.entity.Test; //MongoRepository 자체가 값을 자동으로 만들어줌 public interface TestRepository extends MongoRepository<Test, Long>{ }

 

07) test.html 생성

<!DOCTYPE html> <html lang="ko" xmlns:th="http://thymeleaf.org"> <head> <meta charset="UTF-8"> <title>test</title> </head> <body> [[${list}]] </body> </html>

실행화면

 

 

MongoDB로 Board 만들기

 

01) Board.java 생성

package com.peazh.entity; import java.time.LocalDateTime; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @Document(collection = "board") @NoArgsConstructor @AllArgsConstructor public class Board { @Id private String id; private String title; private String content; private LocalDateTime date; private String name; private String img; }

- 보드 테이블 예시

{

  "_id": {

    "$oid": "64f6b6bb874910553a75f88f"

  },

  "title": "그림",

  "content": "그림",

  "date": {

    "$date": "2023-09-05T05:03:55.009Z"

  },

  "name": "홍길동"

}

 

 

02) BoardController.java 생성

package com.peazh.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import com.peazh.entity.Board; import com.peazh.service.BoardService; @Controller public class BoardController { @Autowired private BoardService boardService; ​​​​// 게시판 가져오기 @GetMapping("/board") public String board(Model model) { ‌‌List<Board> list = boardService.list(); ‌‌model.addAttribute("list",list); ‌‌return "board"; } }

 

03) BoardService.java 생성

package com.peazh.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.peazh.entity.Board; import com.peazh.repository.BoardRepository; @Service public class BoardService { @Autowired private BoardRepository boardRespository; public List<Board> list() { ‌‌return boardRespository.findAll(); } }

 

04) BoardRepository.java 생성

package com.peazh.repository; import org.springframework.data.mongodb.repository.MongoRepository; import com.peazh.entity.Board; public interface BoardRepository extends MongoRepository<Board, Long> { }

 

05) board.html 생성

<!DOCTYPE html> <html lang="ko" xmlns:th="http://thymeleaf.org"> <head> <meta charset="UTF-8"> <title>BOARD</title> </head> <body> [[${list}]] <button th:onclick="|location.href='@{/write}'|">작성하기</button> </body> </html>

 

 

 

Board에서 글 작성하기

 

01) BoardController.java 수정

// 게시판 작성하기 @GetMapping("/write") public String write() { ​​​​return "write"; } // 작성한 값 가져오기 @PostMapping("/write") ​​​​​​​​​​​​// 입력된 값을 img는 img로 받고 나머지는 request로 받음 public String write(@RequestParam("img") MultipartFile img, HttpServletRequest request) throws IOException { ​​Board board = new Board(); ​​board.setTitle(request.getParameter("title")); ​​board.setContent(request.getParameter("content")); ​​board.setName("홍길동"); ​​board.setDate(LocalDateTime.now());//현재시간 ​​if(img.getSize() > 0) {// 파일 입력한게 0보다 클 경우 = 파일이 있을 경우 ​​​​​String fileName = img.getOriginalFilename();// 파일을 fileName으로 저장할 것 ​​​​​// 파일명 .뒤에 있는 글자(확장자명)가 jpg, gif, png로 끝날 경우 ​​​​​if(Pattern.matches("([^\\s]+(\\.(?i)(jpg|gif|png))?)", fileName)) { ​​​​​​​​// 문자열로 표현된 이미지 데이터를 바이트 배열로 변환하고, 그 바이트 배열을 Base64로 인코딩하기 ​​​​​​​​// 그림을 바이트 단위로 깨서 저장하기 ​​​​​​​​byte[] img2Byte = Base64.encodeBase64(img.getBytes()); ​​​​​​​​// Base64로 인코딩된 이미지 데이터를 특정 형식의 문자열로 저장하기 ​​​​​​​​board.setImg("data:image/png;base64," + new String(img2Byte)); ​​​​​} ​​} ​​boardService.save(board); ​​return "redirect:/board"; }

 

02) BoardService.java 수정

public void save(Board board) { ‌boardRepository.save(board); }

 

03) write.html 생성

<!DOCTYPE html> <html lang="ko" xmlns:th="http://thymeleaf.org"> <head> <meta charset="UTF-8"> <title>WRITE</title> <script type="text/javascript"> ​​​function writef(){ ​​​​​​let title = document.getElementById('title'); ​​​​​​let content = document.getElementById('content'); ​​​​​​ ​​​​​​const reg = new RegExp('.jpg|.png|.gif'); ​​​​​​// 제목을 입력 안했을 경우 ​​​​​​if(title.value == '' || title.value == null){ ​​​​​​​​​document.querySelector('#result').innerText = "제목을 입력하세요."; ​​​​​​​​​title.style.backgroundColor = "red";// 배경색 변경 ​​​​​​​​​title.style.borderColor = "#FF0000";// 테두리색 변경 ​​​​​​​​​title.focus(); ​​​​​​​​​return false; ​​​​​​} ​​​​​​title.style.backgroundColor = "write"; ​​​​​​ ​​​​​​// 내용을 입력 안했을 경우 ​​​​​​if(content.value == '' || content.value == null){ ​​​​​​​​​document.querySelector('#result').innerText = "내용을 입력하세요."; ​​​​​​​​​content.style.backgroundColor = "red";// 배경색 변경 ​​​​​​​​​content.style.borderColor = "#FF0000";// 테두리색 변경 ​​​​​​​​​content.focus(); ​​​​​​​​​return false; ​​​​​​} ​​​​​​content.style.backgroundColor = "write"; ​​​​​​document.getElementById('write-form').style.backgroundColor = "gray"; ​​​​​​ ​​​​​​let file = document.getElementById("img").value; ​​​​​​ ​​​​​​// 파일이 있을 경우 ​​​​​​if(file != "" || file != null){ ‌​​​​​​​// 파일의 마지막 글자가 jpg, gif, png일 때 확장자를 reg로 저장 ​​​​​​​​​const reg = /([^\s]+(?=\.(jpg|gif|png))\.\2)/; ​​​​​​​​​//alert(reg.test(file)); ​​​​​​​​​// 확장자가 jpg, gif, png가 아닐 경우 ​​​​​​​​​if(!(reg.test(file))){ ​​​​​​​​​​​​alert("그림파일(jpg, png, gif)만 선택 가능합니다."); ​​​​​​​​​​​​document.querySelector('#result').innerText = "그림파일(jpg, png, gif)만 선택 가능합니다."; ​​​​​​​​​​​​return false; ​​​​​​​​​} ​​​​​​} ​​​} </script> </head> <body> <h1>write</h1> <div id="write-form"> ​​​​​​​​​<form action="./write" method="post" enctype="multipart/form-data" onsubmit="return writef();"> ​​​​​​​​​​​​<input type="text" name="title" id="title"> ​​​​​​​​​​​​<textarea name="content" id="content"></textarea> ​​​​​​​​​​​​<input type="file" name="img" id="img" accept=".jpg, .png, .gif"> ​​​​​​​​​​​​<div id="result">그림파일(jpg, png, gif)만 선택 가능</div> ​​​​​​​​​​​​<button type="submit">write</button> ​​​​​​​​​</form> ​​​​​​</div> </body> </html>

글 작성하기
작성완료
MongoDB에 작성한 글이 저장됨

 

 

Board 글 상세 보기

 

01) BoardController.java 수정

@GetMapping("/detail") ​​​public String board(@RequestParam("no") String id, Model model) { ‌​​​Board detail = boardService.findById(id).get(); ‌​​​//Optional ‌​​​model.addAttribute("detail", detail); ‌​​​return "detail"; ​​​}

 

02) BoardService.java 수정

public Optional<Board> findById(String id) { ‌‌return boardRepository.findById(id); }

 

03) BoardRepository.java 수정

Optional<Board> findById(String id);

- 해당하는 id의 글을 가져와야 하므로 repository 작성해 줌

 

04) detail.html 생성

<!DOCTYPE html> <html lang="ko" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="stylesheet" type="text/css" th:href="@{./css/thymeleaf.css}"> </head> <body> <th:block th:insert="~{/menu.html :: menu}"></th:block> <div class="main"> ‌‌<h1>상세보기</h1> ‌‌<button th:onclick="|location.href='@{/update(no=${detail.id})}'|">update</button> ‌‌<button th:onclick="|location.href='@{/delete(no=${detail.id})}'|">delete</button> ‌‌<hr> ‌‌[[${detail.id}]]<br> [[${detail.title}]]<br> ‌‌[[${detail.content}]]<br> [[${detail.name}]]<br> ‌‌[[${detail.date}]]<br> ‌‌<div th:if="${detail.img ne null}"> ‌‌‌<img th:src="${detail.img}"> ‌‌</div> ‌‌<button th:onclick="|location.href='@{/board}'|">board</button> </div> </body> </html>

실행화면

 

 

Board에 sns 만들기

 

01) BoardController.java 수정

@GetMapping("/sns") ​​​public String sns(Model model) { ‌​​​// 정렬 옵션 ​​​​​​List<Sort.Order> order = new ArrayList<Sort.Order>(); ​​​​​​// 날짜 순으로 정렬할거임 ​​​​​​order.add(Sort.Order.desc("date")); ​​​​​​ ​​​​​​// 최신글 10개만 뜨기 ​​​​​​Page<Board> list = boardService.findAll(PageRequest.of(0, 10, Sort.by(order))); ​​​​​​model.addAttribute("list", list); ​​​​​​return "sns"; ​​​}

 

02) BoardService.java 수정

public Page<Board> findAll(PageRequest of) { return boardRepository.findAll(of); }

 

03) sns.html 생성

<!DOCTYPE html> <html lang="ko" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="stylesheet" type="text/css" th:href="@{./css/thymeleaf.css}"> <style type="text/css"> .box{ width: 500px; height: auto; background-color: rgb(231, 231, 231); margin: 10px; padding: 10px; } .box img{ width: 500px; } </style> </head> <body> <th:block th:insert="~{/menu.html :: menu}"></th:block> <div class="main"> ‌‌<button th:onclick="|location.href='@{/write}'|">글쓰기</button> ‌‌<th:block th:each="row : ${list}"> ‌‌‌<div class="box"> ‌‌‌‌[[${row.title}]] ‌‌‌‌[[${row.name}]] / [[${row.date}]] ‌‌‌‌<hr> ‌‌‌‌[[${row.content}]] ‌‌‌‌<div th:if="${row.img ne null}"> ‌‌‌‌‌<img th:src="${row.img}"> ‌‌‌‌</div> ‌‌‌</div> ‌‌‌ ‌‌‌ ‌‌</th:block> </div> </body> </html>

실행화면

 

 

Board 글 삭제하기

 

01) BoardController.java 수정

@GetMapping("/delete") ​​​public String delete(@RequestParam("no") String id) { ‌​​​// id를 기준으로 찾아서 삭제하기 ‌​​​boardService.deleteById(id); ​​​​​​return "redirect:/board"; ​​​}

 

02) BoardService.java 수정

public void deleteById(String id) { ‌‌boardRepository.deleteById(id); }

 

03) BoardRepository.java 수정

void deleteById(String id);

 

- 글 상세 보기에서 삭제하기 버튼 클릭 

 

 

- 해당 글이 삭제되어 게시판에 글이 없음

 

 

Board 작성한 글 수정하고 글의 개수 가져오기

 

01) BoardController.java 수정

@GetMapping("/update") public String update(@RequestParam("no") String id, Model model) { ​​Board detail = boardService.findById(id).get(); ​​model.addAttribute("detail", detail); ​​return "update"; } ​​​ @PostMapping("/update") public String update(Board board) { ​​board.setName("수정함."); ​​board.setDate(LocalDateTime.now());// 수정한 시간으로 변경 ​​boardService.save(board); ​​return "redirect:/board"; } // 작성한 글 개수 가져오기 @GetMapping("/board") ‌public String board(Model model) { ‌‌ ‌‌int count = boardService.count(); ‌‌model.addAttribute("count",count);

- save는 이미 생성했으므로 service나 repository에 생성 안 해줘도 됨

 

02) BoardService.java 수정

public int count() { return (int) boardRepository.count(); }

 

03) update.html 생성

<!DOCTYPE html> <html lang="ko" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>수정하기</title> <link rel="stylesheet" type="text/css" th:href="@{./css/thymeleaf.css}"> <link rel="stylesheet" type="text/css" th:href="@{./css/write.css}"> </head> <body> <th:block th:insert="~{/menu.html :: menu}"></th:block> <div class="main"> ‌‌<h1>update</h1> ‌‌<div class="write-form"> ‌‌‌<form action="./update" method="post"> ‌‌‌‌<input type="text" name="title" th:value="${detail.title}"> ‌‌‌‌<textarea name="content">[[${detail.content}]]</textarea> ‌‌‌‌<input type="hidden" name="id" th:value="${detail.id}"> ‌‌‌‌<button type="submit">수정</button> ‌‌‌</form> ‌‌</div> </div> </body> </html>

글 수정하기
수정완료

 

반응형

댓글