본문 바로가기
프로젝트/여행 프로젝트

스프링 팀프로젝트[2] - jsp를 활용한 여행사이트: 백엔드 기능구현

by CodeMango 2023. 3. 18.

3. 백엔드 기능구현

이제 tiles설정은 끝났으니, 기능을 구현해보겠습니다.

기본적으로 데이터가 흐르는 경로는 mapper -> dao -> service -> controller -> view 입니다.

저는 먼저 dto를 만들고, interface를 이용하여 mapper -> dao -> daoImpl -> service-> serviceImpl -> controller -> view 순서로 진행했습니다.

 

3-1. dto 

HotelDto

package mul.cam.a.dto;

import java.sql.Timestamp;

public class HotelDto {
	 private int seq;
	 private int readCount;
	 private String hotel_name;
	 private String thumbnail;
	 private Timestamp wdate;
	 private String content;
	 private String map;
	 private String book;
	 
	  public HotelDto() {
		}
        
 //get, set 생략

HotelCommentDto

package mul.cam.a.dto;

import java.sql.Timestamp;

public class HotelCommentDto {

	  private int seq;
	  private String id;
	  private int hotelSeq;
	  private String content;
	  private Timestamp wdate;

	public HotelCommentDto() {
		}
//get, set 생략

HotelPagingDto

package mul.cam.a.dto;

public class HotelPagingDto {
	private int pageNo; // 페이지번호
	private int viewCount; // 보여줄갯수
	private String orderBy; // 정렬
	private int limit; // 시작 limit index
	
	public HotelPagingDto() {
	}   
 //get, set 생략

 

3-2. mapper (Hotel.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="Hotel">

<!-- 1페이지(호텔 상세페이지) -->
	<!-- 호텔list 모두 가져오기 + orderby정렬 + 페이징 -->
											
	<select id = "hotellist" parameterType="mul.cam.a.dto.HotelPagingDto"
							 resultType="mul.cam.a.dto.HotelDto">
	
		<!-- 서브쿼리 : hotels의 seq와 hotel_comment의 hotelseq가 동일한 댓글의 개수 반환 -->
		select 
			seq, hotel_name, readcount, thumbnail, wdate, content, map, book, 
		  	(SELECT COUNT(*) 
		  	FROM hotel_comments B 
		  	WHERE B.hotelseq = A.seq) AS COMMENT_COUNT		
		from hotels A
		<if test="orderBy != null">
			<if test='"1".equals(orderBy)'>	 <!-- orderby 파라미터 1인 경우 조회수정렬 -->
	      		order by readcount DESC
			</if>
			<if test='"2".equals(orderBy)'>	 <!-- orderby 파라미터 2인 경우 댓글순정렬 -->
	      		order by COMMENT_COUNT DESC	
			</if>
	   	 </if>
	   	 LIMIT #{limit}, #{viewCount}	<!--  페이징처리 -->
	</select>
	
	<!--  조회수 업데이트  -->
	<update id="updateReadCount" parameterType="int">
		  update hotels set readcount = readcount + 1
		  where seq = #{seq}
	</update>

	<!-- 글의 총수 가져오기 -->
	<select id="getHotelTotalCount" resultType="int">
		SELECT COUNT(*) FROM hotels
	</select>	
	  
<!-- 2페이지(호텔 상세페이지) -->
	<!-- seq 매개변수 값에 해당하는 게시글 조회 -->							
	<select id="getHotel" parameterType="Integer" 
						  resultType="mul.cam.a.dto.HotelDto">
		select seq, hotel_name, readcount, thumbnail, wdate, content, map, book
		from hotels
		where seq=#{seq}	<!--http://localhost:8090/hoteldetail.do?seq=1 ~18 을 찾기 위해  -->
	</select> 

	<!-- 댓글 등록하기 -->
	<!-- HotelCommentDto 객체를 받아 DB의 hotel_comments 테이블에 댓글 정보 삽입 -->
	<insert id="HotelcommentWrite" parameterType="mul.cam.a.dto.HotelCommentDto">
	  INSERT INTO hotel_comments (id, hotelseq, content, wdate)
	  VALUES (#{id},#{hotelSeq},#{content},now()) 
	</insert>
	
	<!--  댓글을 화면에 뿌려주기 -->
	<!--  해당 글의 sequence에 대한 댓글만 쫙 부려줘야함. -->
	<select id="HotelcommentList" parameterType="Integer" 
								  resultType="mul.cam.a.dto.HotelCommentDto">
	 select id, hotelseq, content, wdate
	 from hotel_comments
	 where hotelseq=#{hotelSeq}
	 order by wdate desc	 <!--  날짜 역순 : 최신순으로 정렬하기 -->
	</select>
	
</mapper>

 

3-3. dao (HotelDao)

package mul.cam.a.dao;

import java.util.List;

import mul.cam.a.dto.BbsDto;
import mul.cam.a.dto.HotelCommentDto;
import mul.cam.a.dto.HotelDto;
import mul.cam.a.dto.HotelPagingDto;

public interface HotelDao {
/* 1페이지(호텔페이지)   */
	
	//호텔list 모두 가져오기 + orderby정렬 + 페이징
	//hotellist를 HotelDto 객체의 리스트(List<HotelDto>)로 반환
	List<HotelDto> hotellist(HotelPagingDto param);

	//조회수 증가 (정렬에 활용)
	void updateReadCount(int seq);
	
	//데이터 총수 가져오기 ( 페이징에 활용 )
	int getHotelTotalCount();

	
/* 2페이지(호텔 상세페이지)   */	
	//seq에 해당하는 데이터(hoteldto)가져오기
	HotelDto getHotel(int seq);
	
	//댓글 등록하기
	int HotelcommentWrite(HotelCommentDto com);	  
	
	//댓글 목록 가져오기 (댓글 화면에 뿌려주기 위해)
	List<HotelCommentDto> HotelcommentList(int hotelseq);
		
}

3-4. daoImpl (HotelDaoImpl)

package mul.cam.a.dao.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import mul.cam.a.dao.HotelDao;
import mul.cam.a.dto.HotelCommentDto;
import mul.cam.a.dto.HotelDto;
import mul.cam.a.dto.HotelPagingDto;

@Repository // == 저장소
public class HotelDaoImpl implements HotelDao {

	@Autowired  // 자동생성
	SqlSession session;

	String ns = "Hotel.";
/* 1페이지(호텔페이지)   */
	
	//호텔list 모두 가져오기 + orderby정렬 + 페이징
	//hotellist를 HotelDto 객체의 리스트(List<HotelDto>)로 반환
	@Override
	public List<HotelDto> hotellist(HotelPagingDto param) {
		return session.selectList(ns + "hotellist", param);
	}
	
	//조회수 증가 (정렬에 활용)
	@Override
	public void updateReadCount(int seq) {
		 session.update(ns + "updateReadCount", seq);
	}
	
	//데이터 총수 가져오기 ( 페이징에 활용 )
	@Override
	public int getHotelTotalCount() {
		return session.selectOne(ns + "getHotelTotalCount");
	}

	
/* 2페이지(호텔 상세페이지)   */	
	//seq에 해당하는 데이터(hoteldto)가져오기
	@Override
	public HotelDto getHotel(int seq) {
		return session.selectOne(ns + "getHotel", seq);	
	}
	
	//댓글 등록하기
	@Override
	public int HotelcommentWrite(HotelCommentDto com) {	
		return session.insert(ns + "HotelcommentWrite", com);
	}
		
	//seq에 맞는 등록 댓글 목록 가져오기 (댓글 화면에 뿌려주기 위해)
	@Override
	public List<HotelCommentDto> HotelcommentList(int hotelseq) {
		return session.selectList(ns + "HotelcommentList", hotelseq);
	}
}

3-5. service (HotelService)

package mul.cam.a.service;

import java.util.List;

import mul.cam.a.dto.BbsDto;
import mul.cam.a.dto.HotelCommentDto;
import mul.cam.a.dto.HotelDto;
import mul.cam.a.dto.HotelPagingDto;

public interface HotelService {
	
/* 1페이지(호텔페이지)   */
	
	//호텔list 모두 가져오기 + orderby정렬 + 페이징
	//hotellist를 HotelDto 객체의 리스트(List<HotelDto>)로 반환
	List<HotelDto> hotellist(HotelPagingDto pagingDto);

	//조회수 증가 (정렬에 활용)
	void updateReadCount(int seq);
	
	//데이터 총수 가져오기 ( 페이징에 활용 )
	int getHotelTotalCount();
	
/* 2페이지(호텔 상세페이지)   */
	//seq에 해당하는 데이터(hoteldto)가져오기
	HotelDto getHotel(int seq);
	
	//댓글 등록하기
	boolean HotelcommentWrite(HotelCommentDto com); //리턴값 boolean으로 변경
	
	//seq에 맞는 등록 댓글 목록 가져오기 (댓글 화면에 뿌려주기 위해)
	List<HotelCommentDto> HotelcommentList(int hotelseq);	
}

 

3-6. serviceImpl (HotelServiceImpl)

package mul.cam.a.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import mul.cam.a.dao.HotelDao;
import mul.cam.a.dto.HotelCommentDto;
import mul.cam.a.dto.HotelDto;
import mul.cam.a.dto.HotelPagingDto;
import mul.cam.a.service.HotelService;


@Service
public class HotelServiceImpl implements HotelService {
	
@Autowired
HotelDao dao;

/* 1페이지(호텔페이지)   */

	//호텔list 모두 가져오기 + orderby정렬 + 페이징
	//hotellist를 HotelDto 객체의 리스트(List<HotelDto>)로 반환
	@Override
	public List<HotelDto> hotellist(HotelPagingDto param) {
		return dao.hotellist(param);
	}
	
	//조회수 증가 (정렬에 활용)
	@Override
	public void updateReadCount(int seq) {
	   dao.updateReadCount(seq);
	}
	//데이터 총수 가져오기 ( 페이징에 활용 )
	@Override
	public int getHotelTotalCount() {
		return dao.getHotelTotalCount();
	}

/* 2페이지(호텔 상세페이지)   */
	
	//seq에 해당하는 데이터(hoteldto)가져오기
	@Override
	public HotelDto getHotel(int seq) {
		return dao.getHotel(seq);
	}
	
	//댓글 등록하기
	@Override
	public boolean HotelcommentWrite(HotelCommentDto com) {
		int n = dao.HotelcommentWrite(com);
		return n<0?true:false;
	}

	//seq에 맞는 등록 댓글 목록 가져오기 (댓글 화면에 뿌려주기 위해)
	@Override
	public List<HotelCommentDto> HotelcommentList(int hotelseq) {
		return dao.HotelcommentList(hotelseq);
	}
}

 

3-7. controller (HotelController)

package mul.cam.a.controller;

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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
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.bind.annotation.ResponseBody;

import mul.cam.a.dto.HotelCommentDto;
import mul.cam.a.dto.HotelDto;
import mul.cam.a.dto.HotelPagingDto;
import mul.cam.a.service.HotelService;

@Controller
public class HotelController {
	/* 카테고리 메뉴 클릭시 해당 메뉴로 이동------------------------------------- */

	@Autowired
	HotelService service;

	
/*1페이지(호텔페이지)--------------------------------------------------------*/
// List<HotelDto>로 도착
	// 1. 호텔 정보 받기 + 페이징 + 정렬 
	@GetMapping("hotel.do")
	public String hotel(@RequestParam(name="page", defaultValue="1") int page,	//페이징
			@RequestParam(name="orderBy", defaultValue = "") String orderBy, //정렬
			HttpServletRequest req, Model model) {
		HotelPagingDto pagingDto = new HotelPagingDto(); //페이징
		pagingDto.setOrderBy(orderBy);
		pagingDto.setPageNo(page);
		pagingDto.setViewCount(99);
		pagingDto.setLimit((page - 1) * pagingDto.getViewCount());	
		
		List<HotelDto> list = service.hotellist(pagingDto); 	// 페이징 된 list
		model.addAttribute("hotellist", list);		// 사진 뿌리기 위해 보냄
		model.addAttribute("orderBy", orderBy);	// 정렬
		model.addAttribute("pageTitle", "Hotel Traballoon"); // 배경사진 제목 보내기
		model.addAttribute("pageDescription", "당신의 아름다운 하루를 즐겨보세요"); //배경사진 부제목 보내기
		
		int totalCount = service.getHotelTotalCount(); //hotels 테이블 총 개수 얻어오기
		model.addAttribute("page", page);	// 페이징
		model.addAttribute("totalCount", totalCount); // 페이징

		return "hotel";

	}

	 //2. 메뉴(사이드바)에서 사진 뿌리기
		@GetMapping(value = {"menu_sudo.do", "menu_gwd.do", "menu_ccd.do", "menu_gsd.do", "menu_jld.do", "menu_jeju.do"})
		public String menu(@RequestParam(name="page", defaultValue="1") int page,
				@RequestParam(name="orderBy", defaultValue = "") String orderBy,
		                   HttpServletRequest req, Model model) {
			
			HotelPagingDto pagingDto = new HotelPagingDto();	//페이징
			pagingDto.setOrderBy(orderBy);
			pagingDto.setPageNo(page);
			pagingDto.setViewCount(99);
			pagingDto.setLimit((page - 1) * pagingDto.getViewCount());	
			
			List<HotelDto> list = service.hotellist(pagingDto); 	// 페이징 된 list
			model.addAttribute("hotellist", list);		// 사진 뿌리기 위해 보냄
			model.addAttribute("orderBy", orderBy);		// 정렬
			model.addAttribute("pageTitle", "Hotel Traballoon");	// 배경사진 제목 보내기
			model.addAttribute("pageDescription", "당신의 아름다운 하루를 즐겨보세요");	//배경사진 부제목 보내기
			
			int totalCount = service.getHotelTotalCount();	//hotels 테이블 총 개수 얻어오기
			model.addAttribute("page", page);		// 페이징
			model.addAttribute("totalCount", totalCount);	// 페이징
	
		    String uri = req.getRequestURI();
		    String menu = uri.substring(uri.lastIndexOf('/') + 1);

		    if (menu.equals("menu_sudo.do")) {
		        return "menu_sudo";
		    } else if (menu.equals("menu_gwd.do")) {
		        return "menu_gwd";
		    } else if (menu.equals("menu_ccd.do")) {
		        return "menu_ccd";
		    } else if (menu.equals("menu_gsd.do")) {
		        return "menu_gsd";
		    } else if (menu.equals("menu_jld.do")) {
		        return "menu_jld";
		    } else if (menu.equals("menu_jeju.do")) {
		        return "menu_jeju";
		    }

		    return "error"; // 처리할 수 없는 url 패턴일 경우, 에러 페이지로 이동
		}
		
	//3. 조회수 증가
		
/*2페이지(호텔 상세페이지)----------------------------------------------------------*/
	  
	  //숙소 상세화면으로 가기 (a태그로 보내면 Get으로 받는다.)	
	  @GetMapping("hoteldetail.do") 
	  public String hoteldetail(Model model, int seq) { 
		  HotelDto hoteldto = service.getHotel(seq);	
		  String hotelname = hoteldto.getHotel_name();
		  String hotelbook = hoteldto.getBook();
		  String photo = hoteldto.getThumbnail();
		  String hotelmap = hoteldto.getMap();
		  String hotelcontent = hoteldto.getContent();
		  model.addAttribute("pageTitle", "Hotel Traballoon");	// 배경사진 제목 보내기
		  model.addAttribute("pageDescription", "당신의 아름다운 하루를 즐겨보세요");	//배경사진 부제목 보내기
		  
		  service.updateReadCount(seq);		//조회수 증가시키기
		  
		  model.addAttribute("hoteldto", hoteldto);
		  model.addAttribute("hotelname", hotelname);
		  model.addAttribute("hotelbook", hotelbook);
		  model.addAttribute("photo", photo);
		  model.addAttribute("hotelmap", hotelmap);
		  model.addAttribute("hotelcontent", hotelcontent);
		  return "hoteldetail"; 
		  } 
	  
	  //댓글 등록하기 
	  @PostMapping(value = "HotelcommentWriteAf.do")
	  public String HotelcommentWriteAf(HotelCommentDto com) {
		  boolean isS = service.HotelcommentWrite(com);
		  if(isS) {
				System.out.println("댓글작성에 성공했습니다");
		  }else {
				System.out.println("댓글작성에 실패했습니다");
			}
		  return "redirect:/hoteldetail.do?seq=" + com.getHotelSeq();
			//작성 성공해도 실패해도 hoteldetail페이지로 보내기 
			//hoteldetail.do는 seq를 받는 controller이기 때문에 seq를 같이 보내준다.
		}
	  
// 댓글을 화면에 뿌려주기
// 댓글은 버튼 클릭했을 때 뿌려주는게 아니라 hoteldetail 페이지에 들어오는 순간무조건 뿌려져있어야 한다.
// -> ajax 이용한다.
		@ResponseBody //@ResponseBody : ajax 
		@GetMapping(value = "HotelcommentList.do")
		public List<HotelCommentDto> HotelcommentList(@RequestParam("seq") int hotelseq){
			List<HotelCommentDto> list = service.HotelcommentList(hotelseq);
			return list; // list로 리턴할 수 있다!
		}
	}

댓글