본문 바로가기
개발일지

SpringLegacy Project -2-

by 태운콩즙 2024. 2. 7.
728x90
반응형

오늘은 영화 정보 홈페이지에 영화 등록 기능 , 페이징 처리를  구현 하였다

 

 

페이징 처리 (페이지 네이션. Pagination) 처리
전체 콘텐츠를  페이지 단위로 나누어 페이지 번호를 부여하거나.
'이전', '다음',버튼으로 이동하는 방식
MySQL의 limit를 활용.

전체 페이지 개수 = 전체 콘텐즈/ 페이지 당 보여질 콘텐츠 개수
이 때, 나머지가 0이 아닐경우 1페이지 추가

페이지 번호(버튼) <a> 태그를 활용

 

package com.icia.movieinfo.service;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.icia.movieinfo.dao.MovieDao;
import com.icia.movieinfo.dto.MovieDto;
import com.icia.movieinfo.util.PagingUtil;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class MovieService {
	// DAO
	@Autowired
	private MovieDao mDao;

	// 영화 목록을 가져와서 컨트롤러에 넘기는 메소드
	public String getMovieList(Integer pageNum, Model model, HttpSession session) {
		log.info("getMovieList()");

		if (pageNum == null) {
			pageNum = 1; // 처음에 사이트가 열릴 떄 첫페이지가 되도록 설정
		}
		int listCnt = 5; // 페이지당 보여질 콘텐츠 개수

		Map<String, Integer> pMap = new HashMap<String, Integer>();
		pMap.put("pageNum", (pageNum - 1) * listCnt);
		pMap.put("listCnt", listCnt);

		List<MovieDto> mList = mDao.getMovieList(pMap);

		model.addAttribute("mList", mList);

		// 페이징 처리
		String pageHtml = getPaging(pageNum, listCnt);
		model.addAttribute("paging", pageHtml);

		return "home";
	}

	private String getPaging(Integer pageNum, Integer listCnt) {
		String pageHtml = null;

		// 전체 영화 정보 개수
		int maxNum = mDao.cntMovie();
		// 페이지 당 보여질 번호 개수
		int pageCnt = 5;

		PagingUtil paging = new PagingUtil(maxNum, pageCnt, listCnt, pageCnt);

		pageHtml = paging.makePaging();

		return pageHtml;
	}

	public String insertMovie(List<MultipartFile> files, MovieDto movie, HttpSession session, RedirectAttributes rttr) {
		log.info("insertMovie()");
		String msg = null; // DB 저장성공 .실패 관련 메시지 저장
		String view = null; // 대상 페이지 지정 변수
		String upFile = files.get(0).getOriginalFilename();
		// 업로드 하는 파일의 이름을 추출

		try {
			if (!upFile.equals("")) {
				fileUpload(files, session, movie);
			}
			mDao.insertMovie(movie);
			view = "redirect:/?pageNum=1";
			msg = "작성 성공";

		} catch (Exception e) { // 저장 실패
			e.printStackTrace();
			view = "redirect:writeFrm";
			msg = "작성 실패";
		}

		rttr.addFlashAttribute("msg", msg);

		return view;
	}

	private void fileUpload(List<MultipartFile> files, HttpSession session, MovieDto movie) throws Exception {
		log.info("fileUpload()");
		String sysname = null; // 변경하는 파일명
		String oriname = null; // 원래 파일명

		String realPath = session.getServletContext().getRealPath("/");
		log.info(realPath);
		realPath += "resources/upload/";
		File folder = new File(realPath);
		// isDirectory(): 해당 이름이 폴더가 아니거나 존재하지 않으면 false
		if (folder.isDirectory() == false) {
			folder.mkdir();// 폴더 생성 매서드
		}
		
		MultipartFile mf = files.get(0);
		oriname = mf.getOriginalFilename();
		
		sysname = System.currentTimeMillis() + oriname.substring(oriname.lastIndexOf("."));
		
		File file = new File(realPath + sysname);
		
		mf.transferTo(file); // 하드디스크에 저장( 경로상의 폴더)에 저장
		movie.setP_sysname(sysname);
	}

} // class end


StringBuffer 객체
문자열 처리를 위한 공간을 제공하는 객체
문자열을 붙이거나 자르거나 등의 수정이 많은 경우 활용하는 객체

 

package com.icia.movieinfo.util;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class PagingUtil {
	private int maxNum; // 전체 콘텐츠 개수 저장 변수
	private int pageNum; // 현재 보이는 페이지의 번호 저장 변수
	private int listCnt; // 한 페이지 당 보일 콘텐츠 개수 저장 변수
	private int pageCnt; // 보여질 페이지 번호 개수 저장 변수

	// 페이징용 html 코드를 만드는 메소드
	public String makePaging() {
		String pageStr = null;
		StringBuffer sb = new StringBuffer();

		// 1. 전체 페이지 개수 구하기
		// 전체 콘텐츠 개수 4 페이지 5개씩 출력
		int totalPage = (maxNum % listCnt) > 0 ? maxNum / listCnt + 1 : maxNum / listCnt;
		// 2. 현재 페이지가 속해 있는 번호 그룹 구하기
		int curGroup = (pageNum % pageCnt) > 0 ? pageNum / pageCnt + 1 : pageNum / pageCnt;
		// 3. 번호 그룹의 시작 번호
		int start = (curGroup * pageCnt) - (pageCnt - 1);
		// 두번째 그룹 시작 번호 : 2 * pageCnt(5) - (5 - 1 ) = 6

		// 4. 번호구릅의 마지막 번호
		int end = (curGroup * pageCnt) >= totalPage ? totalPage : curGroup * pageCnt;

		// 두번째 그룹 마지막 번호 : 2 * pageCnt(5) = 10
		// 5. 이전버튼 처리
		if (start != 1) {
			sb.append("<a class = 'pno' href='./?pageNum=");
			sb.append((start - 1) + "'>");
			
			sb.append("◀</a>");
		} // a class = 'pno' href='./?pageNum=5'>◀</a>
			// 6. 중간 번호 버튼 처리
		for (int i = start; i <= end; i++) {
			if (pageNum != i) {// 현재 보이는 페이지가 아닌 경우
				sb.append("<a class='pno' href='./?pageNum=");
				sb.append(i + "'>" + i + "</a>");
			} // <a class = 'pno' href ='./?pageNum=2;>2</a>
			else {	// 현재 보이는 페이지인 경우
				sb.append("<font class='pno'>" + i + "</forn>");
			}//<font class='pno'>3</font>
		}
		// 7. 다음 버튼 처리
		if(end != totalPage) {
			sb.append("<a class = 'pno' href = './?pageNum=");
			sb.append((end + 1) + "'>");
			sb.append("▶</a>");
		}// <a class ='pno' href'./?pageNum=6>▶</a>
		
		// StringBuffer 에 저장된 내용을 문자열로 변환
		pageStr = sb.toString();
		
		return pageStr;
	}
}


Session
클라이언트가 서버에 접속하게 되면 각 클라이언트 별로 할당되는 공간
(일종의 클라이언트와 서버 간의 통로를 나타내는 말인데..
 메모리를 사용하기 때문에 공간이라고 표현합니다.)

인터넷의 통신 메커니즘 : Best Effort 방식.
3way handshaking 방식
클라이언트 요청 -> 서버 응답 -> 클라이언트 데이터 전송 -> 서버 응답
로그인 상황을 유지하지 않는다!
로그인 상황을 유지하기 위한 로그인 성공 정보를 어딘가에 저장해서 사용.
1) 성공 정보를 클라이언트에서 저장 - 쿠키(cookie)
2) 성공 정보를 서버에서 저장 - session

MyBatis 표현식
SQL 쿼리문을 실행하는 객체 -Statement 객체
MyBatis는 PreparedStatement 객체를 사용

JDBC 프로그래밍
1. 드라이버 로딩
2. Connection 수립 (프로그램 <-> DB)
3.SQL 문 실행 결과 처리 
Statement는 쿼리 실행
ResultSet는 select 결과 저장 객체
4. Connection 해제

MYBatis 운영방식
 미완성 된 쿼리문에 데이터를 주입하는 방식

MyBatis 표현식
1) #{식별자}
식별자 - Dao 메소드에서 작성한 매개변수,
   Map의 Key , Dto의 멤버변수.
쿼리문에서 사용하는 값(데이터)
문자열일 경우 자동으로 데이터 앞뒤에 '를 붙임
숫자일 경우 그대로 입력.

2) ${식별자}
쿼리문에서 사용하는 컬럼명, 테이블명에서 사용
문자열, 숫자 상관없이 그대로 입력.
예를 들어, 검색 기능을 구현할 때
- 제목 검색 쿼리
SELECT * FROM mlist
WHERE m_name like '%범죄%';

-감독 검색 쿼리
SELECT * FROM mlist
WHERE m_director like '%스티븐%';

->mybatis map
SELECT * FROM mlist
WHERE ${colmn_name}LIKE CONCAT_WS('%', #{keyword}, '%');

MyBatis 쿼리맵 태그
<tag_name id= "method_name" parameterType="type"
resultType="return_type">

sql 쿼리문
</tag_name>

-tag_name: select, insert , update , delete
-id : Dao 메소드의 이름 '('와')'는 붙이지 않는다.
-parameterType : Dao 메소드의 매개변수 자료향
매개변수가 여러개일경우 생략 가능
(매개변수를 여러 개 사용하지 말고 Map으로 묶자)
- resultType : Dao 메소드의 반환형
빈환형이 List인 경우 '<' 와 '>' 사이의 작성하는 자료형을 작성

예) List<String> -> resultType = "String"

form을 통한 데이터 전송
Multipart데이터 = 텍스트 + 파일 (2진 데이터)

form태그에 반드시 enctype 을 작성. 속성값은 "Multipart/form-data"

 

<?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="com.icia.movieinfo.dao.MovieDao">
	<select id="getMovieList" resultType="movie"
		parameterType="HashMap">
		SELECT * FROM mlist
		LIMIT #{pageNum}, #{listCnt}
	</select>

	<insert id="insertMovie" parameterType="movie">
		INSERT INTO movietbl
		VALUES (null,#{m_name},#{m_director} ,#{m_nation},#{m_genre}
		,#{m_actor} ,#{m_open},#{m_synopsis},#{p_sysname})
	</insert>
</mapper>


파일 업로드용 라이브러리(dependency) -Maven repository에서.
1) commons-io
2) commons - fileupload

 

	<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.11.0</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.3</version>
		</dependency>


servlet - comtext.xml 에 업로드 용량 제한 등의 설정을 작성.


파일 input 태그로 받는 파일은 복수(배열/ 리스트) 로 취급 한다.
(multiple 속성 때문)

Form에 파일 input 태그가 존재할 경우 List<MultipartFile>의 size는 1이 된다
즉 파일을 업로드 하거나 안하거나 동일한 size가 된다
파일 업로드가 됨을 확인하는 방법이 필요한데
1) 파일 자체의 크기를 확인하는 방법
2) 파일명을 확인하는 방법
3) 기타... (isEmpty 메소드)






728x90
반응형

'개발일지' 카테고리의 다른 글

DNS (Dns 클래스)  (0) 2024.10.11
시리얼 통신(Serial Port)  (0) 2024.10.10
SpringLegacy Project -1-  (0) 2024.02.06
SpringLegacy -2-  (1) 2024.02.05
SpringLegacy(MVC)  (0) 2024.02.02