반갑읍니다 즐거운 주말이네요 ~ 오늘은 몽고DB를 이용한 FAQ의 백엔드 부분을 포스팅하고자합니다. (^人^)
몽고DB는 좀 재밌는 .. 일화가 있는데요 .. ?
바로 .. 해킹 사건입니다 .. 몽고DB에 비밀번호를 걸지 않을 경우 해킹당할 수 있습니다. 조심하시오 ..
발표 때 쓸려고 이쁜 데이터를 넣어뒀는데 뭔가 날라갈 거 같아서 백업해둔 게 빛을 발휘했습니다.
사실 그런 거짓 데이터 만드는 거 얼마 안 걸리는데 은근 머리 쓰잖아요 .. ?

다른 건 다 오라클 / mysql 사용했는데 FAQ만 몽고DB로 한 이유는,
다양한 DB를 쓰기 위해서였습니다.
근데 페이징도 간단하고 그래서 좋았었움 ㅎ0ㅎ ~~ 프론트 부분은 내일 보여드리겠습니다 !@
테이블 먼저 보여드리겠습니다. 몽고DB의 경우 시퀀스는 없지만 어떻게 만든 걸 보고,
그거 쓰면 되겠거니 했는데 프라이머리키는 절대적으로 '_id'로만 가능하다는 걸 나중에 알았습니다 ..
그 강제 시퀀스 문장 찾아다닐려고 한창 구글링했는데 .. (´。_。`)
보시면 title과 content가 있습니다.

글번호 / 날짜 / 매니저 아이디까지는 받을 필요가 없어서 딱 '_id', 'title', 'content'만 있습니다 !@

이중에 Criteria와 Paging는 사용되지 않았습니다 ~~
제일 먼저 FAQDTO 보여드리겠습니다.
DB에 있는대로 생성해줬고요 ~
package com.project.faq;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "faq")
public class FaqDTO {
@Id
private String _id;
private String title;
private String content;
public FaqDTO() {
}
public FaqDTO(String _id, String title, String content) {
super();
this._id = _id;
this.title = title;
this.content = content;
}
@Override
public String toString() {
return "faqDTO [_id=" + _id + ", title=" + title + ", content=" + content + "]";
}
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String gettitle() {
return title;
}
public void settitle(String title) {
this.title = title;
}
public String getcontent() {
return content;
}
public void setcontent(String content) {
this.content = content;
}
}
FaqMongoDAO입니다. 실제로 웹사이트에 구현돼있는 기술은 CRUD, list, paging, search 입니다.
package com.project.faq;
import java.util.List;
public interface FaqMongoDAO {
public List<FaqDTO> findCriteria(String key,String value);
public FaqDTO findById(String key,String value);
public void insertDocument(FaqDTO doc);
public void insertAllDocument(List<FaqDTO> docs);
public void update(FaqDTO document); //업데이트
public void delete(String _id); //삭제
//페이징 처리돼있는 목록 화면
public List<FaqDTO> findAll();
public List<FaqDTO> findAll(int pageNo);//페이징
}
FaqMongodbDAOImpl입니다.
package com.project.faq;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
@Repository
public class FaqMongodbDAOImpl implements FaqMongoDAO {
//spring-data-mongodb에서 제공하는 라이브러리
MongoTemplate mongoTemplate;
//페이징처리와 소트를 쉽게 구현하기 위해서 (spring-data-commons라이브러리에서 제공) - CRUD(CLRUD)를 위한 메소드를 제공
FaqRepository FaqRepository; //SimpleMongoRepository이용해서 작업
@Autowired
public FaqMongodbDAOImpl(MongoTemplate mongoTemplate, FaqRepository faqRepository) {
super();
this.mongoTemplate = mongoTemplate;
this.FaqRepository = faqRepository;
}
@Override
public void insertDocument(FaqDTO doc) {
mongoTemplate.insert(doc);
}
//search
@Override
public List<FaqDTO> findCriteria(String key, String value) {
String[] data = key.split(",");
Criteria criteria = new Criteria(data[0]);
//^ =>해당 필드가 ^다음의 문자열로 시작하는 데이터 => like 연산자와 동일 where dept like '인사%'
//criteria.regex("^"+value);
criteria.regex(".*"+value+".*");//dept like '%사%'
Query query = new Query(criteria);
List<FaqDTO> docs = mongoTemplate.find(query, FaqDTO.class,"faq");
System.out.println("dao=>"+docs);
return docs;
}
//
@Override
public FaqDTO findById(String key, String value) {
//Criteria객체는 spring data mongodb에서 조건을 모델링한 객체
//어떤 필드에 어떤 조건을 적용할 것인지 정의
//필드명과 필드의 조건을 정의하면 내부에서 json의 쿼리조건을 만들어 처리
//1. 조건을 객체로 정의
Criteria criteria = new Criteria(key);
//조건에 대한 설정
criteria.is(value);
//2.Criteria객체를 이용해서 Query를 생성
System.out.println("findById->"+value);
Query query = new Query(criteria);
FaqDTO doc = mongoTemplate.findOne(query, FaqDTO.class,"faq");
System.out.println("doc ~~~"+doc);
return doc;
}
@Override
public void update(FaqDTO document) {
//조건(Criteria,Query) - 조건에 만족하는 document를 수정
Criteria criteria = new Criteria("_id");
criteria.is(document.get_id());
Query query = new Query(criteria);
//업데이트기능을 수행하는 객체를 생성하고 적절한 값을 셋팅
Update update = new Update();
update.set("title", document.gettitle());
update.set("content", document.getcontent());
System.out.println("query : "+query);
System.out.println("update : "+update);
mongoTemplate.updateFirst(query, update,"faq");
}
//https://souning.tistory.com/68
//https://sg-choi.tistory.com/388
public void delete(String _id){
Criteria criteria = new Criteria("_id");
criteria.is(_id);
Query query = new Query(criteria);
System.out.println("DAOImpl _id : "+_id);
mongoTemplate.remove(query,"faq");
System.out.println("DAOImpl"+query);
}
@Override
public List<FaqDTO> findAll() {
return mongoTemplate.findAll(FaqDTO.class,"faq");
}
//리스트 페이징처리
@Override
public List<FaqDTO> findAll(int pageNo) {
Page<FaqDTO> page = FaqRepository.findAll(new PageRequest(pageNo, 10));
return page.getContent();
}
@Override
public void insertAllDocument(List<FaqDTO> docs) {
// TODO Auto-generated method stub
}
}
FaqMongoService입니다.
package com.project.faq;
import java.util.List;
public interface FaqMongoService {
//데이터 찾기
public FaqDTO findById(String key,String value);
//데이터 추가
public void insertDocument(FaqDTO doc);
public List<FaqDTO> findCriteria(String key,String value);
public void update(FaqDTO document); //진짜 업데이트
public List<FaqDTO> findAll();
public void delete(String _id); //삭제
//페이징처리
public List<FaqDTO> findAll(int pageNo);//페이징
void insertAllDocument(List<FaqDTO> docs);
}
FaqMongoServiceImpl입니다 ~
package com.project.faq;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class FaqMongoServiceImpl implements FaqMongoService {
FaqMongoDAO dao;
@Autowired
public FaqMongoServiceImpl(FaqMongoDAO dao) {
super();
this.dao = dao;
}
@Override
public FaqDTO findById(String key, String value) {
return dao.findById(key, value);
}
@Override
public void insertDocument(FaqDTO doc) {
dao.insertDocument(doc);
}
@Override
public void insertAllDocument(List<FaqDTO> docs) {
dao.insertAllDocument(docs);
}
@Override
public List<FaqDTO> findCriteria(String key, String value) {
return dao.findCriteria(key, value);
}
@Override
public List<FaqDTO> findAll() {
return dao.findAll();
}
@Override
public List<FaqDTO> findAll(int pageNo) { //페이징
//PaginfAndSortingRepository의 findAll메소드를 호출하면 페이징 처리된 객체를 전달 받을 수 있다.
//fiindAll 메소드 내부에서 페이징 처리를 할 수 있도록 PageRequest객체를 이용해서 실행할 페이지의 번호와 한 페이지를 구성할 document
//를 매개 변수로 전달해야하 한다.
return dao.findAll(pageNo);
}
@Override
public void update(FaqDTO document) {
System.out.println("서비스입플 도큐먼트입니다 ~~~ "+document);
dao.update(document);
}
@Override
public void delete(String _id) {
System.out.println("서비스임플입니다 _id >> "+_id);
dao.delete(_id);
}
}
몽고DB에서 중요한 FaqRepository도 보여드리겠습니다 !
package com.project.faq;
import java.util.List;
import org.springframework.data.repository.PagingAndSortingRepository;
import oracle.jdbc.proxy.annotation.Post;
//spring-data 내부에서 자동으로 하위 객체를 생성하고 코드를 만들고 mongodv에서 데이터를 조회해서 매핑시킨다.
public interface FaqRepository extends PagingAndSortingRepository<FaqDTO, String>{
// List<Post> findAllByOrderByIdDesc();
}
FaqIndexController입니다.
package com.project.faq;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class FaqIndexController {
@RequestMapping("/faq.do")
public String basefaq() {
return "faq";
}
}
대부분의 역할을 수행하는 FaqController입니다.
package com.project.faq;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class FaqController {
FaqMongoService service;
public FaqController() {
}
@Autowired
public FaqController(FaqMongoService service) {
super();
this.service = service;
}
// inset페이지로 이동
@RequestMapping(value = "/service/faqinsert", method = RequestMethod.GET)
public String insertPage() {
return "service_faqinsert"; // .jsp
}
// faq에 insert하기
@RequestMapping(value = "/service/faqinsert", method = RequestMethod.POST)
public String insert(FaqDTO document) {
// System.out.println("컨트롤러:"+document);
service.insertDocument(document);
System.out.println("FAQ컨트롤러 ~~" + document);
return "redirect:/admin_faq.do?pageNo=0";
}
// search 하기.
@RequestMapping(value = "/faq/search", method = RequestMethod.POST)
public ModelAndView search(String field, String criteria, String value) {
List<FaqDTO> docs = service.findCriteria(field + "," + criteria, value);
return new ModelAndView("faq_search", "faqlist", docs);
}
// 읽기
@RequestMapping("/faq/detail")
public ModelAndView findById(String key, String value, String action) {
System.out.println("findById _id 1234 : " + value);
FaqDTO list = service.findById(key, value);
System.out.println("list 1234 : " + list);
String view = "";
if (action.equals("read")) {
view = "service_faqread";
} else {
view = "service_faqupdate";
}
return new ModelAndView(view, "list", list);
}
// get : 디비에서 데이터 가져올 때
// post : 디비에 데이터 생성, 수정 할 때
// RESTful API
//
// get.article
// post.article
// put.article 기존 게시글에 덮어 씌우기 (업데이트. 통째로 덮어씌움)
// patch.article 기존 게시글에 일부만 바꿔서 업데이트 (업데이트. 일부만 업데이트 함)
// 개발자끼리 이렇게 개발하자고 약속
@RequestMapping("/faq/list")
public String mongolist(Model model) {
List<FaqDTO> faqlist = service.findAll();
model.addAttribute("faqlist", faqlist);
return "list";
}
// user list
// user list
@RequestMapping("/faq/paginglist")
public ModelAndView pagemongolist(String pageNo) {
ModelAndView mav = new ModelAndView("service_faq");
List<FaqDTO> faqlist = service.findAll(Integer.parseInt(pageNo));
List<FaqDTO> faqcount = service.findAll();
int total_article = faqcount.size();
mav.addObject("faqlist", faqlist);
mav.addObject("faqcount", total_article);
return mav;
}
// @RequestMapping("/faq/paginglist")
// public ModelAndView pagemongolist(String pageNo, HttpServletRequest request) {
// List<FaqDTO> faqlist = service.findAll();
// int total_article = faqlist.size();
// // 페이징 객체
//// Paging paging = new Paging();
//// paging.setCri(pageNo);
// paging.setTotalCount(total_article); // 리스트 총갯수 (디비에서 count(*) 가지고 와야 함)
//
// request.setAttribute("paging", paging);
//
//// model.addAttribute("faqlist", faqlist);
////
//// List<FaqDTO> faqlist = service.findAll(Integer.parseInt(pageNo));
// // System.out.println(pageNo);
//
// return new ModelAndView("service_faq", "faqlist", faqlist);
// }
// admin list
@RequestMapping("/admin_faq.do")
public ModelAndView pagemongolist2(String pageNo) {
ModelAndView mav = new ModelAndView("admin_faqlist");
List<FaqDTO> faqlist = service.findAll(Integer.parseInt(pageNo));
List<FaqDTO> faqcount = service.findAll();
int total_article = faqcount.size();
mav.addObject("faqlist", faqlist);
mav.addObject("faqcount", total_article);
return mav;
}
@RequestMapping(value = "/faq/update", method = RequestMethod.POST)
public String update(FaqDTO document, @RequestParam String _id) {
System.out.println("update test1234 : " + document);
System.out.println("_id test1234 : " + _id);
document.set_id(_id);
service.update(document);
return "redirect:/admin_faq.do?pageNo=0";
}
// admin delete
@RequestMapping(value = "/faq/delete.do", method = RequestMethod.GET)
public String delete(String _id) {
System.out.println("FAQ 컨트롤러 ~~삭제하기 눌려짐");
service.delete(_id);
System.out.println("컨트롤러 document > " + _id);
return "redirect:/admin_faq.do?pageNo=0";
}
}
몽고DB를 사용하기 위해서는 pom.xml에 추가해야하는 내용도 있는데 남겨두겠습니다.
...
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>
...
위에도 남겨두었는데 내일은 프론트 부분을 포스팅하겠습니다 ~
'coding > Java' 카테고리의 다른 글
웹서비스 백엔드 개발자 과정 수료 후기 - 6 (API/미세먼지A) (0) | 2023.02.06 |
---|---|
웹서비스 백엔드 개발자 과정 수료 후기 - 5 (게시판/FAQ B) (0) | 2023.02.05 |
웹서비스 백엔드 개발자 과정 수료 후기 - 3 (게시판/공지사항B) (0) | 2023.02.03 |
웹서비스 백엔드 개발자 과정 수료 후기 - 2 (게시판/공지사항A) (0) | 2023.02.02 |
웹서비스 백엔드 개발자 과정 수료 후기 - 1 (후기) (1) | 2023.02.01 |