오늘은 갤러리를 카드 형식으로 만들어보기
부트스트랩에서 카드 형식으로 이미지 해보기
<div class="card text-dark bg-light mb-3" style="max-width: 18rem;">
<div class="card-header">Header</div>
<div class="card-body">
<h5 class="card-title">Light card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
</div>
해당 부분 가져와서 Header 삭제, text 부분에 image 추가, footer 추가하여 조회수, 좋아요, 날짜 출력하기
<c:forEach items="${list }" var="list">
<div class="card text-dark bg-light mb-3 mx-3" style="max-width: 18rem;">
<!-- <div class="card-header"></div> -->
<div class="card-body">
<h5 class="card-title">${list.gtitle }</h5>
<p class="card-text">
<img src="./upfile/thumbnail/${list.gfile }">
</p>
</div>
<div class="card-footer">
<div style="width: 30%;" class="d-inline-block text-start">
<i class="xi-eye-o"></i>
</div>
<div style="width: 68%;" class="d-inline-block text-end">
<span>${list.gdate }</span>
<span><i class="xi-heart-o"></i>${list.glike }</span>
</div>
</div>
</div>
</c:forEach>
조회수는 아직 DB 에 데이터를 만들지 않아서 이후에 추가
이런식으로 나옴
사진 클릭했을 때 내용 자세히 보기
먼저 사진 div 에 onclick 추가
<p class="card-text" onclick="galleryDetail(${list.gno})">
<img src="./upfile/thumbnail/${list.gfile }">
</p>
스크립트는 이렇게 받음
function galleryDetail(gno) {
location.href="./galleryDetail@" + gno;
}
컨트롤러에서 값 받기
만약 삭제되거나, 아직 만들어지지 않은 페이지 번호를 입력하면 없는 페이지 문구의 에러 페이지로 이동
// galleryDetail 갤러리 자세히보기 만들기
@GetMapping("/galleryDetail@{no}")
public String galleryDetail(Model model, @PathVariable("no") String no) {
if (util.intCheck(no)) {
GalleryDTO dto = galleryService.detail(util.str2Int(no));
// if (dto.getMname() == null || dto.getMname().equals("") || dto.getMname().isBlank()) {
if (dto == null) {
return "redirect:/errorNoPage";
} else {
dto.setGdate(dto.getGdate().substring(0, 16));
model.addAttribute("detail", dto);
return "galleryDetail";
}
} else {
return "redirect:/error";
}
}
Service, Repository 연결하기
// Service
public GalleryDTO detail(int no) {
return galleryRepository.detail(no);
}
// Repository
public GalleryDTO detail(int no) {
return sqlSession.selectOne("gallery.galleryDetail", no);
}
gallery-mapper 에 명령문 추가
<select id="galleryDetail" resultType="galleryDTO" parameterType="Integer">
select m.mname, m.mid, g.mno, g.gno, g.gtitle, g.gcontent, g.gfile, g.gdate, g.glike
from gallery g join member m on g.mno = m.mno
where g.gno = #{no} and g.gdel = '1'
</select>
galleryDetail.jsp 는 board detail.jsp 를 복사하여 사용
<section class="page-section" id="services">
<div class="container">
<div class="text-center">
<h2 class="section-heading text-uppercase">자세히 보기</h2>
</div>
<div class="row text-center">
<div class="btitle text-start fs-3">${detail.gtitle }</div>
<hr>
<div class="detailInfo">
<span class="mname">${detail.mname }
<c:if test="${sessionScope.mid eq detail.mid }">
<i class="xi-document"></i>
<i class="xi-close-circle-o" onclick="deletePost()"></i>
</c:if>
</span>
<span class="bcount">조회수없음<%-- ${detail.board_count } --%></span>
</div>
<div class="detailInfo">
<span class="bdate text-start">${detail.gdate }</span>
<span class="bdate text-start">ip없음<%-- ${detail.board_ip } --%></span>
</div>
<hr>
<div class="bcontent text-start">
<div class="gcontentImage mb-3">
<img alt="" src="./upfile/${detail.gfile }">
</div>
<div>${detail.gcontent }</div>
</div>
</div>
<div class="buttonList my-3">
<button class="btn btn-outline-dark" onclick="location.href='./gallery'">/gallery</button>
</div>
<hr id="commentHr" class="my-3">
<!-- 댓글 입력창 -->
<h1>댓글창 만들기</h1>
</div>
</section>
갤러리 글 삭제 만들기, 본체는 detail 과 비슷함
기존 detail 페이지와 같이 삭제 버튼에 스크립트 추가
<c:if test="${sessionScope.mid eq detail.mid }">
<i class="xi-document"></i>
<i class="xi-close-circle-o" onclick="deletePost()"></i>
</c:if>
스크립트에 post 로 글 번호와 아이디를 보내는 폼 생성
function deletePost() {
Swal.fire({
title: "정말 삭제하시겠습니까?",
text: "삭제를 진행하려면 아래 버튼을 눌러주세요.",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "삭제하기",
cancelButtonText: "취소"
}).then(result => {
if(result.isConfirmed) {
let vform = $('<form></form>');
vform.attr('method', 'post');
vform.attr('action', './galleryPostDel');
vform.append($('<input/>', {type:'hidden', name:'gno', value:'${detail.gno}'}));
vform.append($('<input/>', {type:'hidden', name:'mid', value:'${detail.mid}'}));
vform.appendTo('body');
vform.submit();
}
});
}
컨트롤러에서 값 받기
@PostMapping("galleryPostDel")
public String galleryPostDel(GalleryDTO dto) {
if (dto.getMid().equals(util.getMid())) {
int result = galleryService.galleryPostDel(dto);
if (result == 1) {
return "redirect:/gallery";
} else {
return "redirect:/error";
}
} else {
return "redirect:/error";
}
}
세션에 등록된 mid 를 검사하여 삭제 요청 들어온 mid 값과 세션의 mid 값이 같은지 체크
Service 와 Repository 연결
public int galleryPostDel(GalleryDTO dto) {
return galleryRepository.galleryPostDel(dto);
}
public int galleryPostDel(GalleryDTO dto) {
return sqlSession.update("gallery.galleryPostDel", dto);
}
mapper 에 update 문 작성하기
<update id="galleryPostDel" parameterType="galleryDTO">
update gallery set gdel='0'
where mno=(select mno from member where mid=#{mid}) and gno=#{gno}
</update>
컨트롤러에서 result 로 값 받아 정상 삭제 시 갤러리 페이지로 이동, 삭제 오류 시 에러 페이지로 이동
모든 Repository 에서 SqlSession 을 생성하지 않고 부모 클래스에서 SqlSession 을 받아서 사용하기
// 부모 형태로 존재
// 어노테이션이 없음 @
// public, protected, default, private
class AbstractRepository {
@Autowired
SqlSession sqlSession;
}
다른 Repository 에서 해당 클래스 상속받기
Service 에서는 Util util 을 상속받기
@Resource
javax 의 어노테이션 중에서는 @Resource 라는 것이 있는데
지정한 name 을 찾아서 Autowired 를 진행해 줌
@Resource(name="galleryService")
private GalleryService galleryService;
GalleryService 에도 이름을 넣어줘야 함
@Service("galleryService")
'Spring' 카테고리의 다른 글
240228 스프링 프로젝트 (2) | 2024.02.28 |
---|---|
240227 스프링 프로젝트 (1) | 2024.02.27 |
240223 스프링 프로젝트 (0) | 2024.02.23 |
240222 스프링 프로젝트 (0) | 2024.02.22 |
240221 스프링 프로젝트 (2) | 2024.02.21 |