국비교육(22-23)

50일차(4)/Spring(7) : Service 메소드 / Todo 테이블로 실습

서리/Seori 2022. 12. 18. 13:45

50일차(4)/Spring(7) : Service 메소드 / Todo 테이블로 실습

 

 

- MemberController (Service가 추가된 수정본)

package com.sy.spring02.member.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.sy.spring02.member.dto.MemberDto;
import com.sy.spring02.member.service.MemberService;

@Controller
public class MemberController {
	
	//필요한 핵심 의존 객체를 주입받는다.
	@Autowired
	private MemberService service;
	
	@RequestMapping("/member/update")
	public String update(MemberDto dto) {
		service.updateMember(dto);
		return "member/update";
	}
	
	@RequestMapping("/member/updateform")
	public ModelAndView updateform(int num, ModelAndView mView) {//ModelAndView 객체도 받을 수 있다.
		//서비스를 이용해서 회원 한명의 정보를 ModelAndView 객체에 담는다.
		service.getMember(num, mView);		
		//view page의 정보도 담아서
		mView.setViewName("member/updateform");
		//리턴해준다.
		return mView;
	}
	
	@RequestMapping("/member/delete")
	public String delete(int num) {//get 방식 전송 파라미터도 추출 가능
		//서비스를 이용해서 회원 한명의 정보 삭제
		service.deleteMember(num);
		return "redirect:/member/list";
	}	
	
	@RequestMapping("/member/insert")
	public String insert(MemberDto dto) { //폼 전송되는 name, addr이 자동으로 추출되어 MemberDto에 담겨서 전달된다.
		//서비스를 이용해서 회원 한명의 정보 추가
		service.addMember(dto);
		return "member/insert";
	}
	
	@RequestMapping("/member/insertform")
	public String insertform() {		
		// /WEB-INF/views/member/insertform.jsp로 forward 이동해서 응답
		return "member/insertform";
	}
	
	@RequestMapping("/member/list")
	public ModelAndView getList(ModelAndView mView) {
		//서비스를 이용해서 회원 전체의 목록을 ModelAndView객체에 담는다.
		service.getListMember(mView);		
		//View page 정보도 담아서
		mView.setViewName("member/list");
		
		//리턴해준다.
		return mView;
	}
}

 

 

- Service 메소드 추가

 

- spring에서는 controller가 Dao에 바로 의존하지는 않는다.

- ServiceController에서 수행할 비즈니스 로직을 수행하는 역할을 한다.

 

- Service란 Controller에서 사용하는 유틸리티라고 생각하면 된다.

- Controller에서 복잡한 비즈니스 로직 처리나 Dao등을 직접 사용하지 않고, Service에 의존해서 해당 작업을 처리한다.

- 이렇게 하면 Contoller를 좀더 간단하게 만들 수 있다.

 

- com.sy.spring02 패키지 하위에 .member.service 패키지 생성

 

MemberService (인터페이스) 생성

package com.sy.spring02.member.service;

import org.springframework.web.servlet.ModelAndView;

import com.sy.spring02.member.dto.MemberDto;

public interface MemberService {
	//회원정보를 추가해주는 메소드
	public void addMember(MemberDto dto);
	//회원정보를 수정해주는 메소드
	public void updateMember(MemberDto dto);
	//회원정보를 삭제해주는 메소드
	public void deleteMember(int num);
	//회원 한명의 정보를 인자로 전달한 ModelAndView 객체에 담아주는 메소드
	public void getMember(int num, ModelAndView mView);
	//회원 전체의 정보를 인자로 전달한 ModelAndView 객체에 담아주는 메소드
	public void getListMember(ModelAndView mView);
}

 

MemberServiceImpl 클래스생성

package com.sy.spring02.member.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import com.sy.spring02.member.dao.MemberDao;
import com.sy.spring02.member.dto.MemberDto;

//component scan 을 통해서 스프링이 관리하는 bean이 되게 하기 위해 필요한 어노테이션
@Service
public class MemberServiceImpl implements MemberService{

	@Autowired
	private MemberDao dao;
	
	@Override
	public void addMember(MemberDto dto) {
		dao.insert(dto);		
	}

	@Override
	public void updateMember(MemberDto dto) {
		dao.update(dto);		
	}

	@Override
	public void deleteMember(int num) {
		dao.delete(num);
	}

	@Override
	public void getMember(int num, ModelAndView mView) {
		//회원 한명의 정보를 얻어와서
		MemberDto dto=dao.getData(num);
		//controller에서 전달한 ModelAndView 객체에 담는다.(request scope에 담기 위해)
		mView.addObject("dto", dto);
	}

	@Override
	public void getListMember(ModelAndView mView) {
		//회원 목록을 얻어와서
		List<MemberDto> list=dao.getList();
		//Controller에서 전달한 ModelAndView 객체에 담는다.(request scope에 담기 위해)
		mView.addObject("list", list);
	}

}

- MemberServiceImpl 에서 dao 를 가져다 쓴다!

 

- bean으로 만들어주기 위해 @Service를 붙여준다.

- dao가 필요하므로 필드로 만들고 @Autowired 해준다.(dao에 의존한다)

 

- 중요한 내용은 다 만들어져있는 상태에서 채워넣는다고 생각하면 된다.

- 지금은 서비스, 컨트롤러 등등을 다 직접 만들지만 나중에는 분업화되어서 작업한다.

 

 

- 컨트롤러 수정

 

- Controller는 이제 dao에 의존하지 않는다! service를 주입받고, service 에 의존한다.

 

- num, mView 참조값만 넣어주면 회원 한명의 정보를 담아줄 수 있다.

- 인터페이스 타입이 완성되어 있다는 가정 하에 작업을 하면 된다.

 

- controller가 간단해졌다. 요청이 오면 패러미터 추출, 메소드 불러와서 이동하면 끝!

- 복잡한 비즈니스 로직은 service에서 한다.

 

- getList도 이 부분이 아예 삭제되어도 된다. 이것을 service에서 처리할 것!

 

** Controller - Service - DAO 를 비교하기

- 각각의 Annotation 적절하게 사용하기!

  (annotation을 붙여놓으면 component scan을 통해 bean이 된다.)

- session은 xml 문서에 적어두어서 bean이 되는 것이다.

→ 넷 다 container에서 관리되는 bean이다.

 

 

- controller는 service에 의존해서 injection을 받는다.

- Service는 DAO에 의존해서 주입받는다.

- DAO(sqlSession)는 Spring의 Bean Container로부터 DI받는다.

 

- 하나의 관련 카테고리 기능을 만들려면 4개의 패키지가 필요하고,

 mapper와 mapper가 추가되었다는 내용을 알려줄 configuration이 필요하다.

 


 

** Todo 테이블로 동일한 기능 만들어보기

 

- configuration에는 이것만 추가하면 된다.

 


1. 패키지 4개 만들기

com.sy.spring02.todo.controller
com.sy.spring02.todo.service
com.sy.spring02.todo.dao
com.sy.spring02.todo.dto

 

2. TodoMapper.xml 문서 만들기

 

- 만들어야 할 파일 목록

 

<java>

TodoDto
TodoDao (인터페이스) / TodoDaoImpl
TodoService (인터페이스) / TodoServiceImpl
TodoController
TodoMapper

 

<WEB-INF>

list.jsp
insertform.jsp / insert.jsp
updateform.jsp / update.jsp

delete.jsp 는 리다이렉트 이동시킬 예정이라 생성X

 



TodoDto

package com.sy.spring02.todo.dto;

public class TodoDto {

	private int num;
	private String content;
	private String regdate;
	
	public TodoDto() {}

	public TodoDto(int num, String content, String regdate) {
		super();
		this.num = num;
		this.content = content;
		this.regdate = regdate;
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getRegdate() {
		return regdate;
	}

	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}	
	
}



TodoDao (인터페이스)

package com.sy.spring02.todo.dao;

import java.util.List;

import com.sy.spring02.todo.dto.TodoDto;

public interface TodoDao {
	public void insert(TodoDto dto);
	public void update(TodoDto dto);
	public void delete(int num);
	public TodoDto getData(int num);
	public List<TodoDto> getList();
}

 

TodoDaoImpl

package com.sy.spring02.todo.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.sy.spring02.todo.dto.TodoDto;

@Repository
public class TodoDaoImpl implements TodoDao {

	@Autowired
	private SqlSession session;
	
	@Override
	public void insert(TodoDto dto) {
		session.insert("todo.insert", dto);		
	}

	@Override
	public void update(TodoDto dto) {
		session.update("todo.update", dto);		
	}

	@Override
	public void delete(int num) {
		session.delete("todo.delete", num);		
	}

	@Override
	public TodoDto getData(int num) {
	  /*
       * mapper's namespace => todo
       * sql's id => getData
       * parameterType => int
       * 
       * - selectOne() 메소드를 호출하면 mapper xml의 resultType이 바로 메소드의 return type이 된다.
       * resultType => TodoDto
       * return Type => TodoDto
       */
		TodoDto dto=session.selectOne("todo.getData", num);
		return dto;
	}

	@Override
	public List<TodoDto> getList() {
		List<TodoDto> list=session.selectList("todo.getlist");
		return list;
	}

}


TodoService (인터페이스)

package com.sy.spring02.todo.service;

import org.springframework.web.servlet.ModelAndView;

import com.sy.spring02.todo.dto.TodoDto;

public interface TodoService {
	//회원정보를 추가해주는 메소드
	public void addTodo(TodoDto dto);
	//회원정보를 수정해주는 메소드
	public void updateTodo(TodoDto dto);
	//회원정보를 삭제해주는 메소드
	public void deleteTodo(int num);
	//회원 한명의 정보를 인자로 전달한 ModelAndView 객체에 담아주는 메소드
	public void getTodo(int num, ModelAndView mView);
	//회원 전체의 정보를 인자로 전달한 ModelAndView 객체에 담아주는 메소드
	public void getListTodo(ModelAndView mView);
}


TodoServiceImpl

package com.sy.spring02.todo.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import com.sy.spring02.todo.dao.TodoDao;
import com.sy.spring02.todo.dto.TodoDto;

@Service
public class TodoServiceImpl implements TodoService{

	@Autowired
	private TodoDao dao;
	
	@Override
	public void addTodo(TodoDto dto) {
		dao.insert(dto);		
	}

	@Override
	public void updateTodo(TodoDto dto) {
		dao.update(dto);		
	}

	@Override
	public void deleteTodo(int num) {
		dao.delete(num);		
	}

	@Override
	public void getTodo(int num, ModelAndView mView) {
		TodoDto dto=dao.getData(num);
		mView.addObject("dto", dto);	
	}

	@Override
	public void getListTodo(ModelAndView mView) {
		List<TodoDto> list=dao.getList();
		mView.addObject("list", list);		
	}

}


TodoController

package com.sy.spring02.todo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.sy.spring02.todo.dto.TodoDto;
import com.sy.spring02.todo.service.TodoService;

@Controller
public class TodoController {

	@Autowired
	private TodoService service;
	
	@RequestMapping("/todo/update")
	public String update(TodoDto dto) {
		service.updateTodo(dto);		
		return("todo/update");
	}
	
	@RequestMapping("/todo/updateform")
	public ModelAndView updateform(int num, ModelAndView mView) {
		//숫자, 데이터 담기		
		service.getTodo(num, mView);
		mView.setViewName("todo/updateform");		
		return mView;
	}
	
	@RequestMapping("/todo/delete")
	public String delete(int num) {
		service.deleteTodo(num);
		return("redirect:/todo/list");
	}
	
	@RequestMapping("/todo/insert")
	public String insert(TodoDto dto) {
		service.addTodo(dto);		
		return("todo/insert");
	}
	
	@RequestMapping("/todo/insertform")
	public String insertform() {
		
		return("todo/insertform");
	}
	
	@RequestMapping("/todo/list")
	public ModelAndView getList(ModelAndView mView) {
		service.getListTodo(mView);
		mView.setViewName("todo/list");
		return mView;
	}
}


TodoMapper

<?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="todo">

	<select id="getlist" resultType="com.sy.spring02.todo.dto.TodoDto">
		SELECT num, content, TO_CHAR(regdate, 'YYYY-MM-DD') AS regdate
		FROM todo
		ORDER BY num ASC		
	</select>
	
	<select id="insert" resultType="com.sy.spring02.todo.dto.TodoDto">
		INSERT INTO todo
		(num, content, regdate)
		VALUES(todo_seq.NEXTVAL, #{content}, sysdate)
	</select>	
	
	<select id="delete" resultType="com.sy.spring02.todo.dto.TodoDto">
		DELETE FROM todo
		WHERE num=#{num}
	</select>
	
	<select id="getData" parameterType="int" resultType="com.sy.spring02.todo.dto.TodoDto">
		SELECT num, content, TO_CHAR(regdate, 'YYYY-MM-DD') AS regdate
		FROM todo
		WHERE num=#{num}
	</select>
	
	<select id="update" parameterType="com.sy.spring02.todo.dto.TodoDto">
		UPDATE todo
		SET content=#{content}
		WHERE num=#{num}
	</select>
</mapper>

 


 

list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/views/todo/list.jsp</title>
</head>
<body>
	<div class="container">
		<a href="${pageContext.request.contextPath}/todo/insertform">할일추가</a>
		<h1>할일 목록입니다.</h1>
		<table>
			<thead>
				<tr>
					<th>번호</th>
					<th>할일</th>
					<th>등록일</th>
					<th>수정</th>
					<th>삭제</th>					
				</tr>
			</thead>
			<tbody>
				<c:forEach var="tmp" items="${list }">
					<tr>
						<td>${tmp.num }</td>
						<td>${tmp.content }</td>
						<td>${tmp.regdate }</td>
						<td><a href="updateform?num=${tmp.num }">수정</a></td>
						<td><a href="delete?num=${tmp.num }">삭제</a></td>
					</tr>
				</c:forEach>
			</tbody>
		</table>
	</div>
</body>
</html>

 

insertform.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/todo/insertform.jsp</title>
</head>
<body>
	<div class="container">
		<h1>할일 추가 폼</h1>
		<form action="${pageContext.request.contextPath}/todo/insert" method="post">
			<div>
				<label for="content">할일</label>
				<input type="text" name="content" id="content" />
			</div>			
			<button type="submit">추가</button>
		</form>
	</div>
</body>
</html>


insert.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/todo/insert.jsp</title>
</head>
<body>
	<div class="container">
		<h3>알림</h3>
		<p>
			할일을 추가했습니다.
			<a href="${pageContext.request.contextPath}/todo/list">확인</a>
		</p>
	</div>
</body>
</html>


updateform.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/todo/updateform.jsp</title>
</head>
<body>
	<div class="container">
		<h1>할일 수정 폼</h1>
		<form action="update" method="post">
			<input type="hidden" name="num" value="${dto.num }" />
			<input type="hidden" name="regdate" value="${dto.regdate }" />
			<div>
				<label for="num">번호</label>
				<input type="text" id="num" value="${dto.num }" readonly />
			</div>
			<div>
				<label for="content">이름</label>
				<input type="text" name="content" value="${dto.content }" />				
			</div>
			<div>
				<label for="regdate">주소</label>
				<input type="text" name="regdate" value="${dto.regdate }" readonly />				
			</div>
			<button type="submit">수정확인</button>
			<button type="reset">취소</button>
		</form>
	</div>
</body>
</html>


update.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/todo/update.jsp</title>
</head>
<body>
	<div class="container">
		<h3>알림</h3>
		<p>
			할일을 수정했습니다.
			<a href="${pageContext.request.contextPath}/todo/list">확인</a>
		</p>
	</div>
</body>
</html>

 

완성!