Web/Spring국비지원 수업 정리

<Spring 국비지원 수업> mybatis를 사용한 mvc 패턴
깝몬 2023. 8. 11. 16:21

mvc 패턴을 사용하기 전에 숙지 해야할 순서


요청 ↔ Controller ↔ Service ↔ Repository ↔ DB

 

우리가 jsp에서 실행 했던것과 동일하지만

 

annotation 만으로도 이 로직이 이루어지기때문에 이전에 connection을 매번 생성하고 rs와 statement를 생성해야하는 번거로움에서 벗어날 수 있다.

 

Spring에서 mvc를 통해 crud 구현

<1> 하나의 변수 받아오기

1. Controller

	@RequestMapping("/mvcPrac01")
	public return showMemberCnt(Model model) {
		int totalMemberCnt = memberService.showMemberCnt();
		model.addAttribute(totalMemberCnt);
		System.out.println("totalMemberCnt는"+totalMemberCnt);
        return "home";
	}

받아 온 후 attribute 지정도 보이고, view 지정도 보인다.

 

2. Service

	public int showMemberCnt() {
		int totalMemberCnt = memberRepository.showMemberCnt();
		return totalMemberCnt;
	}

 

3. Repository

	public int showMemberCnt() {
		int totalMemberCnt = sqlSession.selectOne("member.countMember");
		return totalMemberCnt;
	}

4.member.xml

	<!-- 회원수 조회 -->
	<select id="countMember" resultType="int">
	<![CDATA[
	select count(no)
	from member
	]]>
	</select>

<Sprin

 

이렇게 맞추어 실행 시켜주었을때 db내의 데이터 개수인

 

4개를 응답해야한다.

 

 

home에 이것을 attribute로 출력 시킨 후 확인해보자.

 

이와 같이 출력 됨을 확인 할 수 있다.

 

<2> 하나의 객체 받아오기

1. Controller

	@RequestMapping("/showMember")
	public String showMember(Model model) {
		Member member = memberService.showMember();
		model.addAttribute(member);
		return "memberTable";
	}

2. Service

	public Member showMember() {
		Member member = memberRepository.showMember();
		return member;
	}

3. Repository

	public Member showMember() {
		Member member = (Member)sqlSession.selectOne("member.showOneMember");
		return member;
	}

4.member.xml파일

	<!-- 특정유저 조회 -->
	<select id="showOneMember" resultType="Member">
	<![CDATA[
	select *
	from member
	where memberid='admin'
	]]>
	</select>

아까와 같이 내용물 일부만 가져왔으며 namespace는 동일하다.

 

이때 jsp에서 table에 정보를 뿌리는 형식으로 작업해주면

 

이와 같이 나타난다. jsp에서 간편화되었고, mybatis를 사용해서 편하게 객체를 받아왔다는 것에 의미를 두자.

 

 

 

 

<3> 객체List 받아오기

1. Controller

	@RequestMapping("/member/list") // 목록가져오기 : get방식으로
	public String memberList(@RequestParam(required = false, defaultValue = "1") int pageNo
			, Model model) {
		List<Member> memberList = memberService.memberList(pageNo);
		model.addAttribute(memberList);
		return "listMember";
	}

2. Service

	public List<Member> memberList(int pageNo) {
		List<Member> memberList = memberRepository.memberList(pageNo);
		return memberList;
	}

3. Repository

	public List<Member> memberList(int pageNo) {
		List<Member> memberList = sqlSession.selectList("member.listMember");
		return memberList;
	}

4. member.xml

	<!-- 유저전체 조회 -->
	<select id="listMember" resultType="Member">
	<![CDATA[
	select *
	from member
	]]>
	</select>

 

table에 c:foreach를 사용하여 var로 items에 담긴 객체를 뿌려주는 방식또한 jsp를 할때와 차이가 없기때문에 과정은 생략하고 결과물만 나타냈다.

 

 

 

<4> (HashMap 객체)들의 List 받아오기

1. Controller

	@RequestMapping("/member/list2") // 목록가져오기 : get방식으로
	public String memberList2(@RequestParam(required = false, defaultValue = "1") int pageNo
			, Model model) {
		List<HashMap<String, Object>> memberList = memberService.memberList2(pageNo);
		model.addAttribute(memberList);
		return "listMember";
	}

2. Service

	public List<HashMap<String, Object>> memberList2(int pageNo) {
		List<HashMap<String, Object>> memberList = memberRepository.memberList2(pageNo);
		return memberList;
	}

3. Repository

	public List<HashMap<String, Object>> memberList2(int pageNo) {
		List<HashMap<String, Object>> memberList = sqlSession.selectList("member.listMember");
		return memberList;
	}

4. member.xml

	<!-- 유저전체 조회 -->
	<select id="listMember" resultType="Map">
	<![CDATA[
	select *
	from member
	]]>
	</select>

 

3번의 방식과 차이가 크지는 않다.

 

다만 객체의 필드가 HashMap에 Key / 필드의 값이 Value에 담겨있기때문에 우리가 당장 이것을 쓰는것이 조금 더 복잡해 보일지라도 추후 더 복잡해질때는 이것을 이용하는 것이 더 좋아지는 경우도 있다고 하니 알아두자.

현재로서는 필드를 get메서드를 통해 쉽게 가져올 수 있는 3번의 방식이 더 좋아보인다.. ㅎㅎ

 

 

이것 또한 동일한 페이지의 코드로 view를 지정했는데

 

 

목록을 불러오는데는 문제가 없다.

 

 

<6> Parameter를 통해 입력받은 값에 해당하는 데이터 Row 출력하기

1. Controller

	//회원의 아이디를 입력받아서 그 아이디에 대한 상세 정보 받아오기
	@RequestMapping("/member/detail")
	public String selectMemberById(@RequestParam String memberId, Model model) {
		Member member = memberService.selectMemberById(memberId);
		model.addAttribute(member);
		return "memberTable";
	}

2. Service

	//회원의 아이디를 입력받아서 그 아이디에 대한 상세 정보 받아오기
	public Member selectMemberById(String memberId) {
		Member member = memberRepository.selectMemberById(memberId);
		return member;
	}

3. Repository

	//회원의 아이디를 입력받아서 그 아이디에 대한 상세 정보 받아오기
	public Member selectMemberById(String memberId) {
		Member member = sqlSession.selectOne("member.selectById", memberId);
		return member;
	}

4. member.xml

	<select id="selectById" resultType="Member"
	parameterType="string">
	<![CDATA[
	select *
	from member
	where memberid=#{memberid}
	]]>
	</select>

 

selectOne을 쓸때 쿼리문에 입력할 하나의 파라미터를 더 입력 한 후 member.xml에서 그 타입을 명시하면 잘 작동 하는것을 확인 할 수 있다.

 

 

 

<7> Parameter를 통해 입력받은 값에 해당하는 데이터 Row 삭제하기

1. Controller

	//회원의 상세페이지에서 그 회원의 정보를 삭제하기 버튼
	@RequestMapping("/member/delete")
	public ModelAndView deleteMemberByNo(@RequestParam("no") int no, ModelAndView mv) {
		//비즈니스 로직 수행
		int delCnt = memberService.deleteMemberByNo(no);
		//결과물로 삭제된 row의 개수가 나옴. 지워지면 1 안지워졌으면 0 일것이다.
		if(delCnt==1) {mv.setViewName("redirect:/member/list");}
		else {mv.setViewName("/fail/deleteFail");}
		return mv;
	}

2. Service

	//회원의 상세페이지에서 그 회원의 정보를 삭제하기 버튼
	public int deleteMemberByNo(int no) {
		int delCnt = memberRepository.deleteMemberByNo(no);
		return delCnt;
	}

3. Repository

	//회원의 상세페이지에서 그 회원의 정보를 삭제하기 버튼
	public int deleteMemberByNo(int no) {
		int delCnt = sqlSession.delete("member.deleteMemberByNo",no);
		return delCnt;
	}

4. member.xml

	<!-- 선택유저 삭제 -->
	<select id="deleteMemberByNo" parameterType="int">
	<![CDATA[
	delete from member
	where no=#{no}
	]]>
	</select>

 

 

순서대로 삭제전, 상세보기에서 삭제 누르기전, 삭제 후

 

정상적으로 잘 작동하는것을 확인했다.

 

 

 

<9> 수정 버튼을 눌러 수정 페이지 및 수정하기

1. Controller

	//정보수정 페이지 요청
	@RequestMapping("/member/updateForm")
	public String updateForm(@RequestParam String memberId,
							Model model) {
		Member member = memberService.selectMemberById(memberId);
		model.addAttribute("member", member);
		return "member/Update";
	}
	
	//정보수정 메서드
	@RequestMapping("/member/update")
	public ModelAndView update(	ModelAndView mv,
			@RequestParam String memberId,
			@RequestParam String password,
			@RequestParam String name,
			@RequestParam int no
									) {
		Member member = new Member(no, memberId, password, name);
		int updateCnt = memberService.update(member);
		return mv;
	}

정보수정은 눌렀을때 정보를 받아서 전달하므로 이동하는 메서드와 동작수행 메서드를 나누어둔다.

 

이에따라 정보요청 페이지를 만들어두자.

 

경로에 맞춰서

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<c:set var="cPath" value="<%=request.getContextPath()%>"/>
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
	$("#updateBtn").on("click", function(){
		 //input 값 변수선언
		 var memberId = $("#memberId").val();
         var password = $("#password").val();
         var name = $("#name").val();
         
         //유효성 검사
         if (memberId === "" || password === "" || name === "") {
             alert("빈 필드를 채워주세요.");
             if (memberId === "") {
                 $("#memberId").focus();
             } else if (password === "") {
                 $("#password").focus();
             } else {
                 $("#name").focus();
             }
         } else {
             alert("ok~");
             $("#memberUpdateForm").submit(); // 실제 서버로 폼을 제출합니다.
         }
	});
});
</script>
<meta charset="UTF-8">
<title>회원 정보 수정</title>
</head>
<body>
	<h2>회원 정보 수정 페이지</h2>
	<form action="${cPath}/member/join" method="post" id="memberUpdateForm">
		<input type="hidden" name="no" value="${member.no }">
		<p>
			<label for="memberId">아이디</label>
			<input type="text" name="memberId" id="memberId" required="required" value="${member.memberid}">
		</p>
		<p>
			<label for="password">비밀번호</label>
			<input type="password" name="password" id="password" required="required" value="${member.password}">
		</p>
		<p>
			<label for="name">이름</label>
			<input type="text" name="name" id="name" required="required" value="${member.name}">
		</p>
		<p>
			<button type="button" id="updateBtn">정보수정하기</button>
		</p>
	</form>
</body>
</html>

회원가입페이지와 유사하게 만들었지만, 이전 페이지의 model을 받아와서 사용하므로 value가 존재한다.

 

그리고 수정이므로 id값이 바뀐것들을 jquery에서 맞춰 수정해준다.

 

 

 

2. Service

	//회원의 정보를 수정
	public int update(Member member) {
		int updateCnt = memberRepository.update(member);
		return updateCnt;
	}

 

3. Repository

//회원의 정보를 수정
	public int update(Member member) {
		int updateCnt = sqlSession.insert("member.update",member);
		return updateCnt;
	}

멤버 객체를 넣어서 sql구문을 작동시킨다.

 

 

4. member.xml

	<!-- 정보수정 -->
	<select id="update" parameterType="Member">
	<![CDATA[
	UPDATE member
	set memberid=#{memberid}, password=#{password}, name=#{name}
	where no = ${no}
	]]>
	</select>

 

 

이렇게 진행 했을때

 

이와 같이 수정이 된것을 확인 할 수 있다

 

 

이로서 생성 조회 삭제 수정 (CRUD) 기능을 하나씩 모두 구현해보았다..