본문 바로가기
공부기록/실습

6월 1일 Spring - movieinfo 1

by project100 2023. 6. 1.

기본설정

application.properties 설정

 

파일 업로드 루트 경로 만들기 : main - webapp 폴더 

 

resources 내에 폴더 만들기 : css, images 


templates 폴더 : error폴더 생성

movieinfo 폴더 : util, service, controller, entity, repository 폴더 생성

 

header, footer.html 작성

home.html 작성

js - cdn방식으로 연결, 크로스 오리진 설정이 필요

 

* 크로스 오리진 : 서버(오리진)이 2개 이상일 경우, 보안적인 위혐이 있음

 

jQuery CDN

The integrity and crossorigin attributes are used for Subresource Integrity (SRI) checking. This allows browsers to ensure that resources hosted on third-party servers have not been tampered with. Use of SRI is recommended as a best-practice, whenever libr

releases.jquery.com

controller 작성

package com.raspberry.movieinfo.controller;

import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@Slf4j
public class MovieController {
    private ModelAndView mv;

    @GetMapping("/")
    public  ModelAndView home(Integer pageNum, HttpSession session){
        log.info("home()");

        mv = new ModelAndView();
        mv.setViewName("home");

        return mv;
    }

}

entity - movieinfo 

 

테이블명세 

이름 : movietbl

컬럼 

- 일련번호 : mcode, 기본키(자동증가)

- 제목 : mname, not null. 100자

- 감독 : mdirector, not null 50자

- 국가 : mnation, not null, 50자

- 장르 : mgenre, not null, 100자

- 주연배우 : mactor, not null, 100자

- 개봉일 : mopen, not null, 10자(string 처리, 2023-06-01)

- 영화개요 : msynopsis, 2000자

- 포스터 : moriname, 50자 (원래 파일명)/ msysname 50자 (변경 파일명)

MovieRepository 생성 i

 

 

JPA에서의 paging 처리

Pageable 객체를 활용한 페이징

관련 객체 : Page, Pageable, PageRequest

Page : Paging한 데이터를 담는 객체(Entity를 기반으로 저장)

Pageable :  Paging을 처리하는 객체, DB와 연동하여 조건에 맞는 범위의 데이터를 가져옴

PageRequest : 조건을 작성하는 객체, 몇번째 페이지인가, 정렬하는 방식은? 등의 설정

 

Repository 메소드 중 범위에 따라 데이터를 가져오도록 처리하는 메소드 작명법 : GreaterThan

 

package com.raspberry.movieinfo.repository;

import com.raspberry.movieinfo.entity.Movieinfo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MovieRepository extends JpaRepository<Movieinfo, Long> {
    Page<Movieinfo> findByMcodeGreaterThan(Long mcode, Pageable pb);
}

 service

package com.raspberry.movieinfo.service;

import com.raspberry.movieinfo.entity.Movieinfo;
import com.raspberry.movieinfo.repository.MovieRepository;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

@Service
@Slf4j
public class MovieService {
    @Autowired
    private MovieRepository mRepo;

    private ModelAndView mv;

    public ModelAndView getMovieList(Integer pageNum, HttpSession session){
        log.info("getMovieList()");

        if(pageNum == null){
            pageNum = 1;
        } int listCnt = 5; // 한 페이지 당 5개씩 목록 출력

        // 페이징 조건 생성 (Pageable)
        // of(시작번호 0, 목록갯수, 정렬방식, 키필드명)
        Pageable pb = PageRequest.of((pageNum - 1), listCnt, Sort.Direction.DESC, "mcode");

        Page<Movieinfo> result = mRepo.findByMcodeGreaterThan(0L, pb);
        // 페이지 형태의 결과를 목록 형태로 변환
        List<Movieinfo> mList = result.getContent();

        // 전체 페이지 갯수
        int totalPage = result.getTotalPages();

        // 페이징 용 html 작성

        mv = new ModelAndView();
        mv.addObject("mList", mList);

        // 페이징 용 html 추가

        mv.setViewName("home");
        return mv;
    }
}

controller 수정

package com.raspberry.movieinfo.controller;

import com.raspberry.movieinfo.service.MovieService;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@Slf4j
public class MovieController {
    private ModelAndView mv;

    @Autowired
    private MovieService mServ;

    @GetMapping("/")
    public  ModelAndView home(Integer pageNum, HttpSession session){
        log.info("home()");

        mv = mServ.getMovieList(pageNum, session);
        return mv;
    }
}

 

화면 출력 home.html

<body>
<div class="wrap">
    <th:block th:insert="~{header.html}"></th:block>
    <div class="content">
        <div class="board-form">
            <h2 class="form-header">영화 목록</h2>
            <button class="wr-btn" th:onclick="|location.href='@{writeForm}'|">영화 등록</button>
        </div>
        <div class="data-area">
            <th:block th:if="${#lists.isEmpty(mList)}">
                <div class="movie-item" style="height: 100px;">
                    등록된 영화가 없습니다.
                </div>
            </th:block>
            <th:block th:unless="${#lists.isEmpty(mList)}">
                <th:block th:each="mitem:${mList}">
                    <div class="movie-item">
                        <th:block th:if="${mitem.msysname} == null">
                            <img th:src="@{images/no_image.jpg}" class="poster-pre">
                        </th:block>
                        <th:block th:unless="${mitem.msysname} == null">
                            <img th:src="@{upload/}+${mitem.msysname}" class="poster-pre">
                        </th:block>
                        <div class="info-pre">
                            <div class="title-pre">
                                <a th:href="@{detail(mcode=${mitem.mcode})}" th:text="${mitem.mname}"></a>
                            </div>
                            <div th:text="${mitem.mdirector}"></div>
                            <div th:text="${mitem.mopen}"></div>
                        </div>
                    </div>
                </th:block>
            </th:block>
        </div>
        <div class="paging-area">
            <div class="paging" th:utext="${paging}"></div>
        </div>
    </div>
    <th:block th:insert="~{footer.html}"></th:block>
</div>