☘️ Spring

[Spring] Day70 - NULL update 이슈

harveydent 2023. 8. 18. 15:33
728x90

NULL update 이슈

NULL update 이슈란 데이터베이스 업데이트 작업 중에 NULL 값을 업데이트하려고 할 때 발생하는 문제를 의미합니다. 일반적으로 데이터베이스에서 NULL 값은 데이터가 존재하지 않음을 나타내기 위해 사용됩니다. 따라서 NULL 값을 업데이트하려는 시도는 데이터 무결성과 관련된 문제를 발생시킬 수 있습니다.

NULL update 이슈 사례

사진 게시판을 이용하는 사용자를 예시로 들어보겠습니다.

  1. 사용자가 사진 게시판 게시글 작성
  2. 제목, 내용, 사진 첨부 입력 후 작성 완료
  3. 사용자가 게시글 수정
  4. 수정 시 별도의 사진을 첨부하지 않으면 해당 파라미터 값이 NULL로 변경
  5. NULL값이 Controller → Service → DAO → DB까지 전달

이 상황은 사용자가 게시글을 수정할 때 항상 사진을 첨부해야 하므로 사용자 편의성이 떨어집니다.

 

@SessionAttributes

@SessionAttributes는 Spring 프레임워크에서 세션에 데이터를 저장하고 관리하는 데 사용되는 어노테이션입니다. 주로 컨트롤러 클래스나 메서드에서 세션에 데이터를 유지하고자 할 때 사용됩니다. @SessionAttributes를 사용하면 특정 모델 속성(attribute)을 세션에 저장할 수 있으며, 이 데이터는 세션에서 계속 유지되며 여러 HTTP 요청 간에 공유될 수 있습니다. Controller 단위로 사용하며 만약 NULL이면 View에서 가지고 있던 정보로 set을 해줍니다. 이때 View에 전달했던 정보로도 알려주어야 하기 때문에 @ModelAttribute 또한 함께 사용합니다.

BoardController.java

package com.spring.view.controller;

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

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.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;

import com.spring.biz.board.BoardService;
import com.spring.biz.board.BoardVO;
import com.spring.biz.member.MemberVO;

@Controller
@SessionAttributes("data")
public class BoardController {
	
	@Autowired
	private BoardService boardService;

	@ModelAttribute("searchMap")
	public Map<String,String> searchMap(){
		Map<String,String> map=new HashMap<String,String>();
		map.put("제목", "TITLE");
		map.put("작성자", "WRITER");
		return map;
	}
	
	@RequestMapping(value="/main.do")
	public String main(@ModelAttribute("mem")MemberVO mVO, BoardVO bVO, Model model) {
		System.out.println("searchCondition: "+bVO.getSearchCondition());
		System.out.println("searchContent: "+bVO.getSearchContent());
		if(bVO.getSearchCondition() == null) {
			bVO.setSearchCondition("TITLE");
			bVO.setSearchContent("");
		} // 검색 로직에서 종종 활용되는 기법
		
		mVO.setMid("test");
		mVO.setMpw("1234");
		
		// model.addAttribute("mem", mVO);
		model.addAttribute("datas", boardService.selectAll(bVO));
		return "main.jsp";
	}
	
	@RequestMapping(value="/board.do")
	public String selectBoard(BoardVO bVO, Model model) {
		model.addAttribute("data", boardService.selectOne(bVO));
		boardService.update(bVO);
		return "board.jsp";
	}
	
	@RequestMapping(value="/updateBoard.do")
	public String updateBoard(BoardVO bVO) {
		boardService.update(bVO);
		return "board.do";
	}
	
	@RequestMapping(value="/deleteBoard.do")
	public String deleteBoard(BoardVO bVO) {
		if(boardService.delete(bVO)){
			return "redirect:main.do";
		}
		else{
			return "board.do";
		}
	}
	
	@RequestMapping(value="/insertBoard.do", method=RequestMethod.GET)
	public String insertBoardPage() {
		// AOP 이전에는 일일히 로그를 직접 추가했었음
		// 단순 페이지요청조차도 로그가 찍혔음
		// 메서드 호출 == 느림
		
		// service를 사용하는 건에 대해서만 AOP를 수행하기때문에,
		// 로그가 안찍힘
		// 메서드 안 호출 == 빠름
		
		return "redirect:insertBoard.jsp";
	}
	
	@RequestMapping(value="/insertBoard.do", method=RequestMethod.POST)
	public String insertBoard(BoardVO bVO) throws IllegalStateException, IOException {
		MultipartFile fileUpload=bVO.getFileUpload();
		if(!fileUpload.isEmpty()){
			String fileName=fileUpload.getOriginalFilename();
			System.out.println("파일명: "+fileName);
			
			bVO.setFileName(fileName);
			
			fileUpload.transferTo(new File("D:\\PJH\\ws\\day60\\src\\main\\webapp\\images\\"+fileName));
		}
		else {
			bVO.setFileName("JJANGJJANGJ.png");
		}
		
		if(boardService.insert(bVO)){
			return "redirect:main.do";
		}
		else{
			return "redirect:insertBoard.jsp";
		}
	}
}

@SessionAttributes는 세션에 데이터를 저장하고 유지할 수 있습니다. 이를 통해 여러 HTTP 요청 간에 데이터를 공유하거나 임시 데이터를 보관할 수 있습니다. 또한 세션 관리를 위해 별도의 세션 객체를 생성하거나 관리할 필요가 없으므로 구현이 간단합니다.

하지만 세션은 서버 메모리를 사용하므로 세션에 저장되는 데이터가 크거나 많은 수의 사용자 세션을 관리해야 하는 경우 세션 오버헤드가 발생할 수 있으며 세션 데이터를 관리하고 유지하는 것은 서버 측에서 처리해야 하므로 서버 부하가 발생할 수 있습니다.

@SessionAttributes는 특정 상황에서 유용하지만, 데이터 공유와 관련된 다른 대안을 고려하고 애플리케이션의 요구 사항에 따라 적절한 데이터 관리 방식을 선택해야 합니다.

GitHub

https://github.com/Qkrwnsgus0522/Spring

 

GitHub - Qkrwnsgus0522/Spring

Contribute to Qkrwnsgus0522/Spring development by creating an account on GitHub.

github.com

 

728x90