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에 바로 의존하지는 않는다.
- Service는 Controller에서 수행할 비즈니스 로직을 수행하는 역할을 한다.
- 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>
완성!
'국비교육(22-23)' 카테고리의 다른 글
51일차(2)/Spring(9) : 파일 업로드 기능 구현 / SmartEditor 적용 (0) | 2022.12.19 |
---|---|
51일차(1)/Spring(8) : Interceptor (0) | 2022.12.19 |
50일차(3)/Spring(6) : MyBatis / 회원정보 수정 기능 구현 (getData, update) (0) | 2022.12.18 |
50일차(2)/Spring(5) : MyBatis / 회원 추가, 삭제 기능 구현 (insert, delete) (0) | 2022.12.17 |
50일차(1)/Spring(4) : MyBatis 설치 / DB 데이터 불러오기 (getList) (0) | 2022.12.17 |