[Spring Boot] CRUD (create, read, update, delete)

CRUD create read update delete
01 전체조회 (read)
02 선택조회 (read)
03 추가 (create)
04 추가 (create)
05 수정(update)
06 삭제(delete)

플러그인 설치

 

DTO generator

json 코드를 pojo로 생성
POJO to JSON

Dto 객체를 포함한 pojo 객체를 json 형식으로 만들어주는 플러그인 (랜덤 값으로 채우는 기능)

 

사용법

모델(dept, emp 등)파일에서 마우스 오른쪽버튼 copy  json 클릭 후

붙여넣기(랜덤 값)

 

resources -> static 폴더에 img와 css폴더만들기
css 파일에 main폴더만들기
views common 파일에 footer, header 만들기



 

전체조회

Deptservice

package com.example.modelexam.service.exam01;

import com.example.modelexam.dao.DeptDao;
import com.example.modelexam.model.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : DeptService
 * author : GGG
 * date : 2023-10-06
 * description : 부서 업무 서비스 클래스, @Service, @Autowired,
 *               findAll()
 * 요약 :
 *     @Service : 업무 로직 담당 클래스위에 붙이는 어노테이션
 *      => 스프링 서버 가동될때 그 클래스 생성해둠(싱글톤)
 *      => 객체를 만들어서 함수를 쓸때 : new 생성자함수() 하는데
 *      => 스프링에서는 하지 않고 미리 만들어 둔 객체를 받아서 사용함
 *      (참고: IOC: 제어의 역전)
 *      기타 : @Repository , @Component 등
 *     @Autowired : 스프링에서 미리 만들어 둔 객체를 가져오기
 *       사용법 : 변수위에 또는 생성자함수 위에 붙이는 가져올 수 있음
 *      (참고: DI : 의존성 주입)
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-06         GGG          최초 생성
 */
@Service
public class DeptService {

    @Autowired
    DeptDao deptDao; // 가짜 DB에 접근하는 객체

    /**
     * 전체 조회 함수 : selectAll()(DAO 객체 함수) 호출
     * @return
     */
    public List<Dept> findAll() {
//      TODO: deptDao.selectAll() : db 조회 함수 호출
        List<Dept> list = deptDao.selectAll();

        return list;
    }

    /**
     * id(기본키)로 조회 : 상세조회(1건조회)
     * @param dno
     * @return
     */

    public Dept findById(long dno) {
//       todo: db 상세조회(1건조회) 함수 호출
//         id(기본키)로 조회
        Dept dept = deptDao.selectById(dno);

        return dept;
    }
}

DeptController

package com.example.modelexam.controller.exam01;

import com.example.modelexam.model.Dept;
import com.example.modelexam.service.exam01.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : DeptController
 * author : GGG
 * date : 2023-10-10
 * description : 부서 컨트롤러 , @Slf4j, findAll()
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
// TODO: @Slf4j - 롬북 , 로깅 라이브러리를 위한 어노테이션 ( 디자인패턴 : Facade 패턴 )
//      로깅 라이브러리 : log4j -> log4j2 , logback -> 함수호출을 일원화 시켜주는 기능
//    사용법 : 클래스 위에 붙이면 사용가능 : log.debug(값)
//        ( 간략정보 : Error -> Info -> Debug -> Warn -> Trace : 상세정보 )
//    logback 설치 :
//        1) log4jdbc.log4j2.properties, logback-spring.xml 기본 설정 파일 추가
//          - log4jdbc.log4j2.properties : sql 로그를 출력하기 위한 설정파일
//          - logback-spring.xml : logback 의 다양한 레벨 옵션 설정
@Slf4j
@Controller
@RequestMapping("/exam01")
public class DeptController {

//    TODO: MVC 의 Model(Service클래스) 객체 가져오기
    @Autowired
    DeptService deptService;

    @GetMapping("/dept")
    public String getDeptAll(Model model) {

//      TODO: Service 객체의 전체조회 함수 호출
        List<Dept> list = deptService.findAll();
        model.addAttribute("list", list);

//      TODO: 로그 찍기
        log.debug(list.toString());

        return "exam01/dept/dept_all.jsp";
    }
}

dept_all.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--todo: header.jsp --%>
<jsp:include page="../../common/header.jsp" />

<%--todo : 본문 --%>
<div class="container">
    <h3>전달 받은 객체는 ${list} 입니다.</h3>

    <%--    todo: 테이블 형태로 화면 출력 --%>
    <table class="table">
        <thead>
        <tr>
            <th scope="col">ID</th>
            <th scope="col">Name</th>
            <th scope="col">위치</th>
            <th scope="col">등록일자</th>
            <th scope="col">수정일자</th>
        </tr>
        </thead>
        <tbody>
        <c:forEach var="data" items="${list}">
            <tr>
                <td>${data.dno}</td>
                <td>${data.dname}</td>
                <td>${data.loc}</td>
                <td>${data.insertTime}</td>
                <td>${data.updateTime}</td>
            </tr>
        </c:forEach>

        </tbody>
    </table>

</div>

<script>
    let obj = "${list}";
    console.log(obj);
</script>

<%--todo: footer.jsp--%>
<jsp:include page="../../common/footer.jsp" />

</body>
</html>








결과

http://localhost:8000/exam01/dept

Memberservice

package com.example.modelexam.service.exam01;

import com.example.modelexam.dao.MemberDao;
import com.example.modelexam.model.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : MemberService
 * author : GGG
 * date : 2023-10-10
 * description : 회원 서비스 - 업무 로직
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Service
public class MemberService {

    //    todo : db 접근 함수들이 있는 객체 : memberDao
    @Autowired
    MemberDao memberDao;

    /**
     * 전체 조회
     * @return
     */
    public List<Member> findAll() {
        List<Member> list = memberDao.selectAll(); // 전체 조회

        return list;
    }

}

MemberController

package com.example.modelexam.controller.exam01;

import com.example.modelexam.model.Member;
import com.example.modelexam.service.exam01.MemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : MemberController
 * author : GGG
 * date : 2023-10-10
 * description : 멤버 컨트롤러 - 화면 & 업무로직 중간 역할 (리모콘 역할)
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Slf4j
@Controller
@RequestMapping("/exam01")
public class MemberController {

    //   todo: 서비스 객체 가져오기
    @Autowired
    MemberService memberService;

    @GetMapping("/member")
    public String getMemberAll(Model model) {

        List<Member> list = memberService.findAll();
        model.addAttribute("list", list);

//      todo: 로깅
        log.debug(list.toString());

        return "exam01/member/member_all.jsp";
    }
}

member_all.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--todo: header.jsp --%>
<jsp:include page="../../common/header.jsp" />

<%--todo : 본문 --%>
<div class="container">
    <h3>전달 받은 객체는 ${list} 입니다.</h3>

    <%--    todo: 테이블 형태로 화면 출력 --%>
    <table class="table">
        <thead>
        <tr>
            <th scope="col">사원번호</th>
            <th scope="col">사원명</th>
            <th scope="col">직위</th>
            <th scope="col">매니저</th>
            <th scope="col">등록일자</th>
            <th scope="col">수정일자</th>
        </tr>
        </thead>
        <tbody>
        <c:forEach var="data" items="${list}">
            <tr>
                <td>${data.eno}</td>
                <td>${data.ename}</td>
                <td>${data.job}</td>
                <td>${data.manager}</td>
                <td>${data.insertTime}</td>
                <td>${data.updateTime}</td>
            </tr>
        </c:forEach>

        </tbody>
    </table>

</div>

<script>
    let obj = "${list}";
    console.log(obj);
</script>

<%--todo: footer.jsp--%>
<jsp:include page="../../common/footer.jsp" />

</body>
</html>








결과

선택조회

Dept02service

package com.example.modelexam.service.exam02;

import com.example.modelexam.dao.DeptDao;
import com.example.modelexam.model.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : DeptService
 * author : GGG
 * date : 2023-10-06
 * description : 부서 업무 서비스 클래스, @Service, @Autowired,
 *               findAll()
 * 요약 :
 *     @Service : 업무 로직 담당 클래스위에 붙이는 어노테이션
 *      => 스프링 서버 가동될때 그 클래스 생성해둠(싱글톤)
 *      => 객체를 만들어서 함수를 쓸때 : new 생성자함수() 하는데
 *      => 스프링에서는 하지 않고 미리 만들어 둔 객체를 받아서 사용함
 *      (참고: IOC: 제어의 역전)
 *      기타 : @Repository , @Component 등
 *     @Autowired : 스프링에서 미리 만들어 둔 객체를 가져오기
 *       사용법 : 변수위에 또는 생성자함수 위에 붙이는 가져올 수 있음
 *      (참고: DI : 의존성 주입)
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-06         GGG          최초 생성
 */
@Service
public class Dept02Service {

    @Autowired
    DeptDao deptDao; // 가짜 DB에 접근하는 객체

    /**
     * 전체 조회 함수 : selectAll()(DAO 객체 함수) 호출
     * @return
     */
    public List<Dept> findAll() {
//      TODO: deptDao.selectAll() : db 조회 함수 호출
        List<Dept> list = deptDao.selectAll();

        return list;
    }

    /**
     * id(기본키)로 조회 : 상세조회(1건조회)
     * @param dno
     * @return
     */

    public Dept findById(long dno) {
//       todo: db 상세조회(1건조회) 함수 호출
//         id(기본키)로 조회
        Dept dept = deptDao.selectById(dno);

        return dept;
    }
}

Dept02Controller

package com.example.modelexam.controller.exam02;

import com.example.modelexam.model.Dept;

import com.example.modelexam.service.exam02.Dept02Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : DeptController
 * author : GGG
 * date : 2023-10-10
 * description : 부서 컨트롤러 , @Slf4j, findAll()
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
// TODO: @Slf4j - 롬북 , 로깅 라이브러리를 위한 어노테이션 ( 디자인패턴 : Facade 패턴 )
//      로깅 라이브러리 : log4j -> log4j2 , logback -> 함수호출을 일원화 시켜주는 기능
//    사용법 : 클래스 위에 붙이면 사용가능 : log.debug(값)
//        ( 간략정보 : Error -> Info -> Debug -> Warn -> Trace : 상세정보 )
//    logback 설치 :
//        1) log4jdbc.log4j2.properties, logback-spring.xml 기본 설정 파일 추가
//          - log4jdbc.log4j2.properties : sql 로그를 출력하기 위한 설정파일
//          - logback-spring.xml : logback 의 다양한 레벨 옵션 설정
@Slf4j
@Controller
@RequestMapping("/exam02")
public class Dept02Controller {

    //    todo: MVC 의 Model(Service클래스) 객체 가져오기
    @Autowired
    Dept02Service deptService;

    @GetMapping("/dept")
    public String getDeptAll(Model model) {

//      TODO: Service 객체의 전체조회 함수 호출
        List<Dept> list = deptService.findAll();
        model.addAttribute("list", list);

//      TODO: 로그 찍기
        log.debug(list.toString());

        return "exam02/dept/dept_all.jsp";
    }

    @GetMapping("/dept/{dno}")
    public String getDeptId(@PathVariable long dno,
                            Model model
    ) {
//      todo: 서비스 상세조회 호출
        Dept dept = deptService.findById(dno);
        model.addAttribute("dept", dept);
        return "exam02/dept/dept_id.jsp";
    }

    //  todo: 연습 2)
//    Member02Service 클래스를 만들고 findById() 함수를 정의한다.
//    Member02Controller 클래스를 만들어서 getMemberId() 함수를 정의하고,
//    샘플데이터 뷰로(jsp : member_id.jsp) 전송해 보세요.
//    url : /member/{eno}
//    jsp : exam02/member/member_id.jsp
}






dept_id.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--  todo : header   --%>
<jsp:include page="../../common/header.jsp" />

<%--  todo: 본문 --%>
<div class="container">
    <%--    todo: 테이블 형태로 화면 출력 --%>
    <table class="table">
        <thead>
        <tr>
            <th scope="col">ID</th>
            <th scope="col">Name</th>
            <th scope="col">위치</th>
            <th scope="col">등록일자</th>
            <th scope="col">수정일자</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>${dept.dno}</td>
            <td>${dept.dname}</td>
            <td>${dept.loc}</td>
            <td>${dept.insertTime}</td>
            <td>${dept.updateTime}</td>
        </tr>

        </tbody>
    </table>

</div>

<script>
    let obj = "${dept}"
    console.log(obj);
</script>

<%-- todo : footer --%>
<jsp:include page="../../common/footer.jsp" />
</body>
</html>






결과

Member02service

package com.example.modelexam.service.exam02;

import com.example.modelexam.dao.MemberDao;
import com.example.modelexam.model.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : MemberService
 * author : GGG
 * date : 2023-10-10
 * description : 회원 서비스 - 업무 로직
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Service
public class Member02Service {

    //    todo : db 접근 함수들이 있는 객체 : memberDao
    @Autowired
    MemberDao memberDao;

    /**
     * 전체 조회
     * @return
     */
    public List<Member> findAll() {
        List<Member> list = memberDao.selectAll(); // 전체 조회

        return list;
    }

    /**
     * 상세조회(1건조회)
     * @param eno
     * @return
     */
    public Member findById(long eno) {
//      todo: 상세조회(1건조회)
        Member member = memberDao.selectById(eno);

        return member;
    }

}

Member02Controller

package com.example.modelexam.controller.exam02;

import com.example.modelexam.model.Member;
import com.example.modelexam.service.exam01.MemberService;
import com.example.modelexam.service.exam02.Member02Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : MemberController
 * author : GGG
 * date : 2023-10-10
 * description : 멤버 컨트롤러 - 화면 & 업무로직 중간 역할 (리모콘 역할)
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Slf4j
@Controller
@RequestMapping("/exam02")
public class Member02Controller {

    //   todo: 서비스 객체 가져오기
    @Autowired
    Member02Service memberService;

    @GetMapping("/member")
    public String getMemberAll(Model model) {

        List<Member> list = memberService.findAll();
        model.addAttribute("list", list);

//      todo: 로깅
        log.debug(list.toString());

        return "exam02/member/member_all.jsp";
    }

    @GetMapping("/member/{eno}")
    public String getMemberId(@PathVariable int eno,
                              Model model) {
//      todo: 멤버 서비스 상세조회 함수 호출
        Member member = memberService.findById(eno);
        model.addAttribute("member", member);

        return "exam02/member/member_id.jsp";
    }
}

member_id.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%-- todo: header --%>
<jsp:include page="../../common/header.jsp" />

<%-- todo: 본문--%>
<div class="container">
    <h3>전달받은 객체는 ${member} 입니다.</h3>
    <%--    todo: 테이블 형태로 화면 출력 --%>
    <table class="table">
        <thead>
        <tr>
            <th scope="col">사원번호</th>
            <th scope="col">사원명</th>
            <th scope="col">직위</th>
            <th scope="col">매니저</th>
            <th scope="col">등록일자</th>
            <th scope="col">수정일자</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>${member.eno}</td>
            <td>${member.ename}</td>
            <td>${member.job}</td>
            <td>${member.manager}</td>
            <td>${member.insertTime}</td>
            <td>${member.updateTime}</td>
        </tr>
        </tbody>
    </table>


</div>

<script>
    let obj = "${member}"
    console.log(obj);
</script>
<%-- todo: footer --%>
<jsp:include page="../../common/footer.jsp" />
</body>
</html>




결과

추가(Add)

Dept03service

package com.example.modelexam.service.exam03;

import com.example.modelexam.dao.DeptDao;
import com.example.modelexam.model.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : DeptService
 * author : GGG
 * date : 2023-10-06
 * description : 부서 업무 서비스 클래스, @Service, @Autowired,
 *               findAll()
 * 요약 :
 *     @Service : 업무 로직 담당 클래스위에 붙이는 어노테이션
 *      => 스프링 서버 가동될때 그 클래스 생성해둠(싱글톤)
 *      => 객체를 만들어서 함수를 쓸때 : new 생성자함수() 하는데
 *      => 스프링에서는 하지 않고 미리 만들어 둔 객체를 받아서 사용함
 *      (참고: IOC: 제어의 역전)
 *      기타 : @Repository , @Component 등
 *     @Autowired : 스프링에서 미리 만들어 둔 객체를 가져오기
 *       사용법 : 변수위에 또는 생성자함수 위에 붙이는 가져올 수 있음
 *      (참고: DI : 의존성 주입)
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-06         GGG          최초 생성
 */
@Service
public class Dept03Service {

    @Autowired
    DeptDao deptDao; // 가짜 DB에 접근하는 객체

    /**
     * 전체 조회 함수 : selectAll()(DAO 객체 함수) 호출
     * @return
     */
    public List<Dept> findAll() {
//      TODO: deptDao.selectAll() : db 조회 함수 호출
        List<Dept> list = deptDao.selectAll();

        return list;
    }

    /**
     * id(기본키)로 조회 : 상세조회(1건조회)
     * @param dno
     * @return
     */
    public Dept findById(long dno) {
//       todo: db 상세조회(1건조회) 함수 호출
//          id(기본키)로 조회
        Dept dept = deptDao.selectById(dno);

        return dept;
    }

    /**
     * 부서 정보 저장 함수
     * @param dept
     * @return
     */
    public List<Dept> save(Dept dept) {
        List<Dept> list = deptDao.insert(dept);

        return list;
    }
}

Dept03Controller

package com.example.modelexam.controller.exam03;

import com.example.modelexam.model.Dept;
import com.example.modelexam.service.exam03.Dept03Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : DeptController
 * author : GGG
 * date : 2023-10-10
 * description : 부서 컨트롤러 , @Slf4j, findAll()
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
// TODO: @Slf4j - 롬북 , 로깅 라이브러리를 위한 어노테이션 ( 디자인패턴 : Facade 패턴 )
//      로깅 라이브러리 : log4j -> log4j2 , logback -> 함수호출을 일원화 시켜주는 기능
//    사용법 : 클래스 위에 붙이면 사용가능 : log.debug(값)
//        ( 간략정보 : Error -> Info -> Debug -> Warn -> Trace : 상세정보 )
//    logback 설치 :
//        1) log4jdbc.log4j2.properties, logback-spring.xml 기본 설정 파일 추가
//          - log4jdbc.log4j2.properties : sql 로그를 출력하기 위한 설정파일
//          - logback-spring.xml : logback 의 다양한 레벨 옵션 설정
@Slf4j
@Controller
@RequestMapping("/exam03")
public class Dept03Controller {

    //    todo: MVC 의 Model(Service클래스) 객체 가져오기
    @Autowired
    Dept03Service deptService;

    @GetMapping("/dept")
    public String getDeptAll(Model model) {

//      TODO: Service 객체의 전체조회 함수 호출
        List<Dept> list = deptService.findAll();
        model.addAttribute("list", list);

//      TODO: 로그 찍기
        log.debug(list.toString());

        return "exam03/dept/dept_all.jsp";
    }

    @GetMapping("/dept/{dno}")
    public String getDeptId(@PathVariable long dno,
                            Model model
    ) {
//      todo: 서비스 상세조회 호출
        Dept dept = deptService.findById(dno);
        model.addAttribute("dept", dept);
        return "exam03/dept/dept_id.jsp";
    }

    //  todo: @ResponseBody : 함수의 결과로 json 데이터를 리턴하고자
//        할때 사용하는 어노테이션
//    사용법 : 함수의 위에 붙이기
    @PostMapping("/dept")
    @ResponseBody
    public List<Dept> createDept(
            @RequestBody Dept dept
    ){
        List<Dept> list = deptService.save(dept);
        return list;
    }
    //  todo: 연습 3)
//    Member03Service 클래스를 만들고 save() 함수를 정의한다.
//    Member03Controller 클래스를 만들어서
//    createMember() 함수를 정의하고
//    Rest Client 툴로 데이터를 확인하세요
}






 

클릭

추가

결과

Member03service

package com.example.modelexam.service.exam03;

import com.example.modelexam.dao.MemberDao;
import com.example.modelexam.model.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : MemberService
 * author : GGG
 * date : 2023-10-10
 * description : 회원 서비스 - 업무 로직
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Service
public class Member03Service {

    //    todo : db 접근 함수들이 있는 객체 : memberDao
    @Autowired
    MemberDao memberDao;

    /**
     * 전체 조회
     * @return
     */
    public List<Member> findAll() {
        List<Member> list = memberDao.selectAll(); // 전체 조회

        return list;
    }

    /**
     * 상세조회(1건조회)
     * @param eno
     * @return
     */
    public Member findById(long eno) {
//      todo: 상세조회(1건조회)
        Member member = memberDao.selectById(eno);

        return member;
    }

    /**
     * 회원 저장 함수
     * @param member
     * @return
     */
    public List<Member> save(Member member) {
//      todo: db 저장
        List<Member> list = memberDao.insert(member);

        return list;
    }

}

Member03Controller

package com.example.modelexam.controller.exam03;

import com.example.modelexam.model.Member;
import com.example.modelexam.service.exam03.Member03Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : MemberController
 * author : GGG
 * date : 2023-10-10
 * description : 멤버 컨트롤러 - 화면 & 업무로직 중간 역할 (리모콘 역할)
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Slf4j
@Controller
@RequestMapping("/exam03")
public class Member03Controller {

    //   todo: 서비스 객체 가져오기
    @Autowired
    Member03Service memberService;

    @GetMapping("/member")
    public String getMemberAll(Model model) {

        List<Member> list = memberService.findAll();
        model.addAttribute("list", list);

//      todo: 로깅
        log.debug(list.toString());

        return "exam03/member/member_all.jsp";
    }

    @GetMapping("/member/{eno}")
    public String getMemberId(@PathVariable int eno,
                              Model model) {
//      todo: 멤버 서비스 상세조회 함수 호출
        Member member = memberService.findById(eno);
        model.addAttribute("member", member);

        return "exam03/member/member_id.jsp";
    }

    //  todo: @ResponseBody : 함수의 리턴값을 json 데이터로 변경하는 어노테이션
    @PostMapping("/member")
    @ResponseBody
    public List<Member> createMember(
            @RequestBody Member member
    ) {
//      todo: 서비스 저장함수 호출
        List<Member> list = memberService.save(member);

        return list;
    }
}

버튼 클릭

추가

결과

추가(Create)

Dept04service

package com.example.modelexam.service.exam04;

import com.example.modelexam.dao.DeptDao;
import com.example.modelexam.model.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : DeptService
 * author : GGG
 * date : 2023-10-06
 * description : 부서 업무 서비스 클래스, @Service, @Autowired,
 *               findAll()
 * 요약 :
 *     @Service : 업무 로직 담당 클래스위에 붙이는 어노테이션
 *      => 스프링 서버 가동될때 그 클래스 생성해둠(싱글톤)
 *      => 객체를 만들어서 함수를 쓸때 : new 생성자함수() 하는데
 *      => 스프링에서는 하지 않고 미리 만들어 둔 객체를 받아서 사용함
 *      (참고: IOC: 제어의 역전)
 *      기타 : @Repository , @Component 등
 *     @Autowired : 스프링에서 미리 만들어 둔 객체를 가져오기
 *       사용법 : 변수위에 또는 생성자함수 위에 붙이는 가져올 수 있음
 *      (참고: DI : 의존성 주입)
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-06         GGG          최초 생성
 */
@Service
public class Dept04Service {

    @Autowired
    DeptDao deptDao; // 가짜 DB에 접근하는 객체

    /**
     * 전체 조회 함수 : selectAll()(DAO 객체 함수) 호출
     * @return
     */
    public List<Dept> findAll() {
//      TODO: deptDao.selectAll() : db 조회 함수 호출
        List<Dept> list = deptDao.selectAll();

        return list;
    }

    /**
     * id(기본키)로 조회 : 상세조회(1건조회)
     * @param dno
     * @return
     */
    public Dept findById(long dno) {
//       todo: db 상세조회(1건조회) 함수 호출
//          id(기본키)로 조회
        Dept dept = deptDao.selectById(dno);

        return dept;
    }

    /**
     * 부서 정보 저장 함수
     * @param dept
     * @return
     */
    public List<Dept> save(Dept dept) {

        List<Dept> list = null;
//      todo: insert 시 dno 자동 생성
//        기존 부서번호 max 찾아서 + 10
        if(dept.getDno() == null) {
//            todo: 전체조회해서 현재 배열의 크기 가져오기
            int count = deptDao.selectAll().size();
//            todo: 새로운 부서번호 생성
            int newDno = (count + 1) * 10;
//            todo: 새로운 부서번호 저장 : dept
            dept.setDno(newDno);
//            todo: db 저장
            list = deptDao.insert(dept);
        }

        return list;
    }
}

Dept04Controller

package com.example.modelexam.controller.exam04;

import com.example.modelexam.model.Dept;
import com.example.modelexam.service.exam04.Dept04Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : DeptController
 * author : GGG
 * date : 2023-10-10
 * description : 부서 컨트롤러 , @Slf4j, findAll()
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
// TODO: @Slf4j - 롬북 , 로깅 라이브러리를 위한 어노테이션 ( 디자인패턴 : Facade 패턴 )
//      로깅 라이브러리 : log4j -> log4j2 , logback -> 함수호출을 일원화 시켜주는 기능
//    사용법 : 클래스 위에 붙이면 사용가능 : log.debug(값)
//        ( 간략정보 : Error -> Info -> Debug -> Warn -> Trace : 상세정보 )
//    logback 설치 :
//        1) log4jdbc.log4j2.properties, logback-spring.xml 기본 설정 파일 추가
//          - log4jdbc.log4j2.properties : sql 로그를 출력하기 위한 설정파일
//          - logback-spring.xml : logback 의 다양한 레벨 옵션 설정
@Slf4j
@Controller
@RequestMapping("/exam04")
public class Dept04Controller {

    //    todo: MVC 의 Model(Service클래스) 객체 가져오기
    @Autowired
    Dept04Service deptService;

    @GetMapping("/dept")
    public String getDeptAll(Model model) {

//      TODO: Service 객체의 전체조회 함수 호출
        List<Dept> list = deptService.findAll();
        model.addAttribute("list", list);

//      TODO: 로그 찍기
        log.debug(list.toString());

        return "exam04/dept/dept_all.jsp";
    }

    @GetMapping("/dept/{dno}")
    public String getDeptId(@PathVariable long dno,
                            Model model
    ) {
//      todo: 서비스 상세조회 호출
        Dept dept = deptService.findById(dno);
        model.addAttribute("dept", dept);
        return "exam04/dept/dept_id.jsp";
    }

    //  todo: 부서 추가 페이지 열기 함수
    @GetMapping("/dept/addition")
    public String addDept() {
        return "exam04/dept/add_dept.jsp";
    }

    //  todo: 저장 버튼 클릭시 db 저장하기 함수
    @PostMapping("/dept/add")
    public RedirectView createDept(@ModelAttribute Dept dept) {
//      todo: 서비스 저장함수 호출
        deptService.save(dept);
//      todo: 저장 후 전체조회 url 로 강제 페이지 이동
//        사용법 : new RedirectView("강제이동될url주소")
        return new RedirectView("/exam04/dept");
    }


}






dept_all.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--todo: header.jsp --%>
<jsp:include page="../../common/header.jsp" />

<%--todo : 본문 --%>
<div class="container">
    <h3>전달 받은 객체는 ${list} 입니다.</h3>

    <%--    todo: 테이블 형태로 화면 출력 --%>
    <table class="table">
        <thead>
        <tr>
            <th scope="col">ID</th>
            <th scope="col">Name</th>
            <th scope="col">위치</th>
            <th scope="col">등록일자</th>
            <th scope="col">수정일자</th>
        </tr>
        </thead>
        <tbody>
        <c:forEach var="data" items="${list}">
            <tr>
                <td>${data.dno}</td>
                <td>${data.dname}</td>
                <td>${data.loc}</td>
                <td>${data.insertTime}</td>
                <td>${data.updateTime}</td>
            </tr>
        </c:forEach>

        </tbody>
    </table>
    <%-- todo: Add 버튼 추가 --%>
    <div class="text-center">
        <a href="/exam04/dept/addition" class="btn btn-primary">Add</a>
    </div>
</div>

<script>
    let obj = "${list}";
    console.log(obj);
</script>

<%--todo: footer.jsp--%>
<jsp:include page="../../common/footer.jsp" />

</body>
</html>








결과

(부서명 개발 부서위치 서울 추가)

Member04service

package com.example.modelexam.service.exam04;

import com.example.modelexam.dao.MemberDao;
import com.example.modelexam.model.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : MemberService
 * author : GGG
 * date : 2023-10-10
 * description : 회원 서비스 - 업무 로직
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Service
public class Member04Service {

    //    todo : db 접근 함수들이 있는 객체 : memberDao
    @Autowired
    MemberDao memberDao;

    /**
     * 전체 조회
     * @return
     */
    public List<Member> findAll() {
        List<Member> list = memberDao.selectAll(); // 전체 조회

        return list;
    }

    /**
     * 상세조회(1건조회)
     * @param eno
     * @return
     */
    public Member findById(long eno) {
//      todo: 상세조회(1건조회)
        Member member = memberDao.selectById(eno);

        return member;
    }

    /**
     * 회원 저장 함수
     * @param member
     * @return
     */
    public List<Member> save(Member member) {

        List<Member> list = null;

//      todo: ui(frontend) -> insert (사원번호가 없으면)
        if(member.getEno() == null) {
//          todo: 새로운 사원번호 생성
            int count = memberDao.selectAll().size(); // 전체 건수
            int newEno = count + 8000;
            member.setEno(newEno); // 새로운 사원번호 저장

            //      todo: db 저장
            list = memberDao.insert(member);
        }

        return list;
    }

}

Member04Controller

package com.example.modelexam.controller.exam04;

import com.example.modelexam.model.Member;
import com.example.modelexam.service.exam04.Member04Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : MemberController
 * author : GGG
 * date : 2023-10-10
 * description : 멤버 컨트롤러 - 화면 & 업무로직 중간 역할 (리모콘 역할)
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Slf4j
@Controller
@RequestMapping("/exam04")
public class Member04Controller {

    //   todo: 서비스 객체 가져오기
    @Autowired
    Member04Service memberService;

    @GetMapping("/member")
    public String getMemberAll(Model model) {

        List<Member> list = memberService.findAll();
        model.addAttribute("list", list);

//      todo: 로깅
        log.debug(list.toString());

        return "exam04/member/member_all.jsp";
    }

    @GetMapping("/member/{eno}")
    public String getMemberId(@PathVariable int eno,
                              Model model) {
//      todo: 멤버 서비스 상세조회 함수 호출
        Member member = memberService.findById(eno);
        model.addAttribute("member", member);

        return "exam04/member/member_id.jsp";
    }

    //  todo: 새로운 회원 추가 페이지 이동 함수
    @GetMapping("/member/addition")
    public String addMember() {
        return "exam04/member/add_member.jsp";
    }

    //  todo: db 저장 함수
    @PostMapping("/member/add")
    public RedirectView createMember(
            @ModelAttribute Member member
    ){
        memberService.save(member);
//      todo : 전체 조회 페이지
        return new RedirectView("/exam04/member");
    }
}







member_all.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--todo: header.jsp --%>
<jsp:include page="../../common/header.jsp" />

<%--todo : 본문 --%>
<div class="container">
    <h3>전달 받은 객체는 ${list} 입니다.</h3>

    <%--    todo: 테이블 형태로 화면 출력 --%>
    <table class="table">
        <thead>
        <tr>
            <th scope="col">사원번호</th>
            <th scope="col">사원명</th>
            <th scope="col">직위</th>
            <th scope="col">매니저</th>
            <th scope="col">등록일자</th>
            <th scope="col">수정일자</th>
        </tr>
        </thead>
        <tbody>
        <c:forEach var="data" items="${list}">
            <tr>
                <td>
                    <a href="/exam05/member/edition/${data.eno}">${data.eno}</a>
                </td>
                <td>${data.ename}</td>
                <td>${data.job}</td>
                <td>${data.manager}</td>
                <td>${data.insertTime}</td>
                <td>${data.updateTime}</td>
            </tr>
        </c:forEach>

        </tbody>
    </table>
    <%-- todo: Add 버튼 추가 --%>
    <div class="text-center">
        <a href="/exam05/member/addition" class="btn btn-primary">Add</a>
    </div>
</div>

<script>
    let obj = "${list}";
    console.log(obj);
</script>

<%--todo: footer.jsp--%>
<jsp:include page="../../common/footer.jsp" />

</body>
</html>








add_member.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%-- header 시작 --%>
<jsp:include page="../../common/header.jsp"/>

<%-- 본문 --%>
<div class="container">
    <form action="/exam04/member/add" method="post">
        <%--        todo: 사원명 입력양식 --%>
        <div class="mb-3">
            <label for="ename" class="form-label">사원 이름</label>
            <input type="text" class="form-control" id="ename" required name="ename">
        </div>
        <%--       todo: 직위 입력양식--%>
        <div class="mb-3">
            <label for="job" class="form-label">직위</label>
            <input type="text" class="form-control" id="job" required name="job">
        </div>
        <%--       todo: 매니저 입력양식--%>
        <div class="mb-3">
            <label for="manager" class="form-label">manager</label>
            <input type="text" class="form-control" id="manager" required name="manager">
        </div>
        <div class="mb-3">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </form>
</div>
<jsp:include page="../../common/footer.jsp"/>
</body>
</html>

결과

(사원명 도권재 직위 970918 매니저 1111 입력)

수정(update)

Dept05service

package com.example.modelexam.service.exam05;

import com.example.modelexam.dao.DeptDao;
import com.example.modelexam.model.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : DeptService
 * author : GGG
 * date : 2023-10-06
 * description : 부서 업무 서비스 클래스, @Service, @Autowired,
 *               findAll()
 * 요약 :
 *     @Service : 업무 로직 담당 클래스위에 붙이는 어노테이션
 *      => 스프링 서버 가동될때 그 클래스 생성해둠(싱글톤)
 *      => 객체를 만들어서 함수를 쓸때 : new 생성자함수() 하는데
 *      => 스프링에서는 하지 않고 미리 만들어 둔 객체를 받아서 사용함
 *      (참고: IOC: 제어의 역전)
 *      기타 : @Repository , @Component 등
 *     @Autowired : 스프링에서 미리 만들어 둔 객체를 가져오기
 *       사용법 : 변수위에 또는 생성자함수 위에 붙이는 가져올 수 있음
 *      (참고: DI : 의존성 주입)
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-06         GGG          최초 생성
 */
@Service
public class Dept05Service {

    @Autowired
    DeptDao deptDao; // 가짜 DB에 접근하는 객체

    /**
     * 전체 조회 함수 : selectAll()(DAO 객체 함수) 호출
     * @return
     */
    public List<Dept> findAll() {
//      TODO: deptDao.selectAll() : db 조회 함수 호출
        List<Dept> list = deptDao.selectAll();

        return list;
    }

    /**
     * id(기본키)로 조회 : 상세조회(1건조회)
     * @param dno
     * @return
     */
    public Dept findById(long dno) {
//       todo: db 상세조회(1건조회) 함수 호출
//          id(기본키)로 조회
        Dept dept = deptDao.selectById(dno);

        return dept;
    }

    /**
     * 부서 정보 저장 함수
     * @param dept
     * @return
     */
    public List<Dept> save(Dept dept) {

        List<Dept> list = null;
//      todo: insert 시 dno 자동 생성
//        기존 부서번호 max 찾아서 + 10
        if(dept.getDno() == null) {
//            todo: 전체조회해서 현재 배열의 크기 가져오기
            int count = deptDao.selectAll().size();
//            todo: 새로운 부서번호 생성
            int newDno = (count + 1) * 10;
//            todo: 새로운 부서번호 저장 : dept
            dept.setDno(newDno);
//            todo: db 저장
            list = deptDao.insert(dept);
        } else {
//           todo: db 수정
            list = deptDao.update(dept);
        }

        return list;
    }
}

Dept05Controller

package com.example.modelexam.controller.exam05;

import com.example.modelexam.model.Dept;
import com.example.modelexam.service.exam05.Dept05Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : DeptController
 * author : GGG
 * date : 2023-10-10
 * description : 부서 컨트롤러 , @Slf4j, findAll()
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
// TODO: @Slf4j - 롬북 , 로깅 라이브러리를 위한 어노테이션 ( 디자인패턴 : Facade 패턴 )
//      로깅 라이브러리 : log4j -> log4j2 , logback -> 함수호출을 일원화 시켜주는 기능
//    사용법 : 클래스 위에 붙이면 사용가능 : log.debug(값)
//        ( 간략정보 : Error -> Info -> Debug -> Warn -> Trace : 상세정보 )
//    logback 설치 :
//        1) log4jdbc.log4j2.properties, logback-spring.xml 기본 설정 파일 추가
//          - log4jdbc.log4j2.properties : sql 로그를 출력하기 위한 설정파일
//          - logback-spring.xml : logback 의 다양한 레벨 옵션 설정
@Slf4j
@Controller
@RequestMapping("/exam05")
public class Dept05Controller {

    //    todo: MVC 의 Model(Service클래스) 객체 가져오기
    @Autowired
    Dept05Service deptService;

    @GetMapping("/dept")
    public String getDeptAll(Model model) {

//      TODO: Service 객체의 전체조회 함수 호출
        List<Dept> list = deptService.findAll();
        model.addAttribute("list", list);

//      TODO: 로그 찍기
        log.debug(list.toString());

        return "exam05/dept/dept_all.jsp";
    }

    @GetMapping("/dept/{dno}")
    public String getDeptId(@PathVariable long dno,
                            Model model
    ) {
//      todo: 서비스 상세조회 호출
        Dept dept = deptService.findById(dno);
        model.addAttribute("dept", dept);
        return "exam05/dept/dept_id.jsp";
    }

    //  todo: 부서 추가 페이지 열기 함수
    @GetMapping("/dept/addition")
    public String addDept() {
        return "exam05/dept/add_dept.jsp";
    }

    //  todo: 저장 버튼 클릭시 db 저장하기 함수
    @PostMapping("/dept/add")
    public RedirectView createDept(@ModelAttribute Dept dept) {
//      todo: 서비스 저장함수 호출
        deptService.save(dept);
//      todo: 저장 후 전체조회 url 로 강제 페이지 이동
//        사용법 : new RedirectView("강제이동될url주소")
        return new RedirectView("/exam05/dept");
    }

//  todo: 수정 페이지 열기 : 화면이 보일때 데이터도 화면에 미리 출력해야함
    @GetMapping("/dept/edition/{dno}")
    public String editDept(@PathVariable long dno, Model model) {
        Dept dept = deptService.findById(dno); //
        model.addAttribute("dept", dept);
        return "exam05/dept/update_dept.jsp";
    }

// todo: 수정 저장 : 리다이렉트(강제 이동) : 전체조회페이지로 이동
    @PutMapping("/dept/edit/{dno}")
    public RedirectView updateDept(@PathVariable long dno,
                                   @ModelAttribute Dept dept) {
//        todo: 수정 저장 함수 호출
        deptService.save(dept);
        return new RedirectView("/exam05/dept");
    }

}






dept_all.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--todo: header.jsp --%>
<jsp:include page="../../common/header.jsp" />

<%--todo : 본문 --%>
<div class="container">
    <h3>전달 받은 객체는 ${list} 입니다.</h3>

    <%--    todo: 테이블 형태로 화면 출력 --%>
    <table class="table">
        <thead>
        <tr>
            <th scope="col">ID</th>
            <th scope="col">Name</th>
            <th scope="col">위치</th>
            <th scope="col">등록일자</th>
            <th scope="col">수정일자</th>
        </tr>
        </thead>
        <tbody>
        <c:forEach var="data" items="${list}">
            <tr>
                <td>
                    <a href="/exam05/dept/edition/${data.dno}">${data.dno}</a>
                </td>
                <td>${data.dname}</td>
                <td>${data.loc}</td>
                <td>${data.insertTime}</td>
                <td>${data.updateTime}</td>
            </tr>
        </c:forEach>

        </tbody>
    </table>
    <%-- todo: Add 버튼 추가 --%>
    <div class="text-center">
        <a href="/exam05/dept/addition" class="btn btn-primary">Add</a>
    </div>
</div>

<script>
    let obj = "${list}";
    console.log(obj);
</script>

<%--todo: footer.jsp--%>
<jsp:include page="../../common/footer.jsp" />

</body>
</html>








update_dept.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--header --%>
<jsp:include page="../../common/header.jsp"/>
<%--본문--%>
<div class="container">
    <form action="/exam05/dept/edit/${dept.dno}" method="post">
        <%-- TODO: 1) springboot 에서 아래와 같이 hidden 값을 전송하면 :  put 방식으로 인식해서 연결해줌    --%>
        <%--       2) application.propeties : spring.mvc.hiddenmethod.filter.enabled=true --%>
        <input type="hidden" name="_method" value="put"/>
        <%--     todo: 부서번호 : 화면에서 숨김 --%>
        <input type="hidden" name="dno" value="${dept.dno}"/>
        <%--     todo: 부서이름 입력양식   --%>
        <div class="mb-3">
            <label for="dname" class="form-label">부서 이름</label>
            <input type="text"
                   class="form-control"
                   id="dname"
                   required
                   name="dname"
                   value="${dept.dname}"
            >
        </div>
        <%--     todo: 부서위치 입력양식--%>
        <div class="mb-3">
            <label for="loc" class="form-label">부서 위치</label>
            <input type="text"
                   class="form-control"
                   id="loc"
                   required
                   name="loc"
                   value="${dept.loc}"
            >
        </div>
        <%--     todo: 수정 버튼--%>
        <div class="mb-3">
            <button type="submit" class="btn btn-primary">Update</button>
        </div>
    </form>
</div>
<%--footer --%>
<jsp:include page="../../common/footer.jsp"/>

</body>
</html>

결과

Member05service

package com.example.modelexam.service.exam05;

import com.example.modelexam.dao.MemberDao;
import com.example.modelexam.model.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : MemberService
 * author : GGG
 * date : 2023-10-10
 * description : 회원 서비스 - 업무 로직
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Service
public class Member05Service {

    //    todo : db 접근 함수들이 있는 객체 : memberDao
    @Autowired
    MemberDao memberDao;

    /**
     * 전체 조회
     * @return
     */
    public List<Member> findAll() {
        List<Member> list = memberDao.selectAll(); // 전체 조회

        return list;
    }

    /**
     * 상세조회(1건조회)
     * @param eno
     * @return
     */
    public Member findById(long eno) {
//      todo: 상세조회(1건조회)
        Member member = memberDao.selectById(eno);

        return member;
    }

    /**
     * 회원 저장 함수
     * @param member
     * @return
     */
    public List<Member> save(Member member) {

        List<Member> list = null;

//      todo: ui(frontend) -> insert (사원번호가 없으면)
        if(member.getEno() == null) {
//          todo: 새로운 사원번호 생성
            int count = memberDao.selectAll().size(); // 전체 건수
            int newEno = count + 8000;
            member.setEno(newEno); // 새로운 사원번호 저장

            //      todo: db 저장
            list = memberDao.insert(member);
        } else {
//            todo: db 수정 저장
            list = memberDao.update(member);
        }

        return list;
    }

}

Member05Controller

package com.example.modelexam.controller.exam05;

import com.example.modelexam.model.Member;
import com.example.modelexam.service.exam05.Member05Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : MemberController
 * author : GGG
 * date : 2023-10-10
 * description : 멤버 컨트롤러 - 화면 & 업무로직 중간 역할 (리모콘 역할)
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
@Slf4j
@Controller
@RequestMapping("/exam05")
public class Member05Controller {

    //   todo: 서비스 객체 가져오기
    @Autowired
    Member05Service memberService;

    @GetMapping("/member")
    public String getMemberAll(Model model) {

        List<Member> list = memberService.findAll();
        model.addAttribute("list", list);

//      todo: 로깅
        log.debug(list.toString());

        return "exam05/member/member_all.jsp";
    }

    @GetMapping("/member/{eno}")
    public String getMemberId(@PathVariable int eno,
                              Model model) {
//      todo: 멤버 서비스 상세조회 함수 호출
        Member member = memberService.findById(eno);
        model.addAttribute("member", member);

        return "exam05/member/member_id.jsp";
    }

    //  todo: 새로운 회원 추가 페이지 이동 함수
    @GetMapping("/member/addition")
    public String addMember() {
        return "exam05/member/add_member.jsp";
    }

    //  todo: db 저장 함수
    @PostMapping("/member/add")
    public RedirectView createMember(
            @ModelAttribute Member member
    ){
        memberService.save(member);
//      todo : 전체 조회 페이지
        return new RedirectView("/exam05/member");
    }

    //  todo: 회원 수정 페이지 열기 함수 : 상세조회 필요
    @GetMapping("/member/edition/{eno}")
    public String editMember(@PathVariable long eno, Model model) {
        Member member = memberService.findById(eno); // 상세조회
        model.addAttribute("member", member);

        return "exam05/member/update_member.jsp";
    }

    //  todo: db 수정 저장 함수 : 수정 후 전체조회페이지로 강제 이동(리다이렉트)
    @PutMapping("/member/edit/{eno}")
    public RedirectView updateMember(@PathVariable int eno,
                                     @ModelAttribute Member member) {
//        todo: db 수정 저장
        memberService.save(member);

        return new RedirectView("/exam05/member");
    }
}







member_all.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--todo: header.jsp --%>
<jsp:include page="../../common/header.jsp" />

<%--todo : 본문 --%>
<div class="container">
    <h3>전달 받은 객체는 ${list} 입니다.</h3>

    <%--    todo: 테이블 형태로 화면 출력 --%>
    <table class="table">
        <thead>
        <tr>
            <th scope="col">사원번호</th>
            <th scope="col">사원명</th>
            <th scope="col">직위</th>
            <th scope="col">매니저</th>
            <th scope="col">등록일자</th>
            <th scope="col">수정일자</th>
        </tr>
        </thead>
        <tbody>
        <c:forEach var="data" items="${list}">
            <tr>
                <td>
                    <a href="/exam05/member/edition/${data.eno}">${data.eno}</a>
                </td>
                <td>${data.ename}</td>
                <td>${data.job}</td>
                <td>${data.manager}</td>
                <td>${data.insertTime}</td>
                <td>${data.updateTime}</td>
            </tr>
        </c:forEach>

        </tbody>
    </table>
    <%-- todo: Add 버튼 추가 --%>
    <div class="text-center">
        <a href="/exam05/member/addition" class="btn btn-primary">Add</a>
    </div>
</div>

<script>
    let obj = "${list}";
    console.log(obj);
</script>

<%--todo: footer.jsp--%>
<jsp:include page="../../common/footer.jsp" />

</body>
</html>








update_member.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--header --%>
<jsp:include page="../../common/header.jsp"/>
<%--본문--%>
<div class="container">
    <form action="/exam05/member/edit/${member.eno}" method="post">
        <%-- TODO: 1) springboot 에서 아래와 같이 hidden 값을 전송하면 :  put 방식으로 인식해서 연결해줌    --%>
        <%--       2) application.propeties : spring.mvc.hiddenmethod.filter.enabled=true --%>
        <input type="hidden" name="_method" value="put"/>
        <%--     todo: 부서번호 : 화면에서 숨김 --%>
        <input type="hidden" name="eno" value="${member.eno}"/>
        <%--     todo: 사원명 입력양식   --%>
        <div class="mb-3">
            <label for="ename" class="form-label">사원 이름</label>
            <input type="text"
                   class="form-control"
                   id="ename"
                   required
                   name="ename"
                   value="${member.ename}"
            >
        </div>
        <%--     todo: 직위 입력양식--%>
        <div class="mb-3">
            <label for="job" class="form-label">직위</label>
            <input type="text"
                   class="form-control"
                   id="job"
                   required
                   name="job"
                   value="${member.job}"
            >
        </div>
        <%--     todo: 매니저 입력양식--%>
        <div class="mb-3">
            <label for="manager" class="form-label">매니저</label>
            <input type="text"
                   class="form-control"
                   id="manager"
                   required
                   name="manager"
                   value="${member.manager}"
            >
        </div>
        <%--     todo: 수정 버튼--%>
        <div class="mb-3">
            <button type="submit" class="btn btn-primary">Update</button>
        </div>
    </form>
</div>
<%--footer--%>
<jsp:include page="../../common/footer.jsp"/>

</body>
</html>

결과

삭제 (delete)

Dept06Service

package com.example.modelexam.service.exam06;

import com.example.modelexam.dao.DeptDao;
import com.example.modelexam.model.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName : com.example.modelexam.service.exam01
 * fileName : DeptService
 * author : GGG
 * date : 2023-10-06
 * description : 부서 업무 서비스 클래스, @Service, @Autowired,
 *               findAll()
 * 요약 :
 *     @Service : 업무 로직 담당 클래스위에 붙이는 어노테이션
 *      => 스프링 서버 가동될때 그 클래스 생성해둠(싱글톤)
 *      => 객체를 만들어서 함수를 쓸때 : new 생성자함수() 하는데
 *      => 스프링에서는 하지 않고 미리 만들어 둔 객체를 받아서 사용함
 *      (참고: IOC: 제어의 역전)
 *      기타 : @Repository , @Component 등
 *     @Autowired : 스프링에서 미리 만들어 둔 객체를 가져오기
 *       사용법 : 변수위에 또는 생성자함수 위에 붙이는 가져올 수 있음
 *      (참고: DI : 의존성 주입)
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-06         GGG          최초 생성
 */
@Service
public class Dept06Service {

    @Autowired
    DeptDao deptDao; // 가짜 DB에 접근하는 객체

    /**
     * 전체 조회 함수 : selectAll()(DAO 객체 함수) 호출
     * @return
     */
    public List<Dept> findAll() {
//      TODO: deptDao.selectAll() : db 조회 함수 호출
        List<Dept> list = deptDao.selectAll();

        return list;
    }

    /**
     * id(기본키)로 조회 : 상세조회(1건조회)
     * @param dno
     * @return
     */
    public Dept findById(long dno) {
//       todo: db 상세조회(1건조회) 함수 호출
//          id(기본키)로 조회
        Dept dept = deptDao.selectById(dno);

        return dept;
    }

    /**
     * 부서 정보 저장 함수
     * @param dept
     * @return
     */
    public List<Dept> save(Dept dept) {

        List<Dept> list = null;
//      todo: insert 시 dno 자동 생성
//        기존 부서번호 max 찾아서 + 10
        if(dept.getDno() == null) {
//            todo: 전체조회해서 현재 배열의 크기 가져오기
            int count = deptDao.selectAll().size();
//            todo: 새로운 부서번호 생성
            int newDno = (count + 1) * 10;
//            todo: 새로운 부서번호 저장 : dept
            dept.setDno(newDno);
//            todo: db 저장
            list = deptDao.insert(dept);
        } else {
//           todo: db 수정
            list = deptDao.update(dept);
        }

        return list;
    }

    /**
     * 부서번호로 삭제하는 함수
     * @param dno
     * @return
     */
    public boolean removeById(int dno) {
//        삭제 함수 호출 : 리턴값 : (삭제된 건수)
        int iCount = deptDao.deleteById(dno);

        return (iCount > 0)? true : false;
    }
}


Dept06Controller

package com.example.modelexam.controller.exam06;

import com.example.modelexam.model.Dept;
import com.example.modelexam.service.exam06.Dept06Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;

import java.util.List;

/**
 * packageName : com.example.modelexam.controller.exam01
 * fileName : DeptController
 * author : GGG
 * date : 2023-10-10
 * description : 부서 컨트롤러 , @Slf4j, findAll()
 * 요약 :
 * <p>
 * ===========================================================
 * DATE            AUTHOR             NOTE
 * —————————————————————————————
 * 2023-10-10         GGG          최초 생성
 */
// TODO: @Slf4j - 롬북 , 로깅 라이브러리를 위한 어노테이션 ( 디자인패턴 : Facade 패턴 )
//      로깅 라이브러리 : log4j -> log4j2 , logback -> 함수호출을 일원화 시켜주는 기능
//    사용법 : 클래스 위에 붙이면 사용가능 : log.debug(값)
//        ( 간략정보 : Error -> Info -> Debug -> Warn -> Trace : 상세정보 )
//    logback 설치 :
//        1) log4jdbc.log4j2.properties, logback-spring.xml 기본 설정 파일 추가
//          - log4jdbc.log4j2.properties : sql 로그를 출력하기 위한 설정파일
//          - logback-spring.xml : logback 의 다양한 레벨 옵션 설정
@Slf4j
@Controller
@RequestMapping("/exam06")
public class Dept06Controller {

//    todo: MVC 의 Model(Service클래스) 객체 가져오기
    @Autowired
    Dept06Service deptService;

    @GetMapping("/dept")
    public String getDeptAll(Model model) {

//      TODO: Service 객체의 전체조회 함수 호출
        List<Dept> list = deptService.findAll();
        model.addAttribute("list", list);

//      TODO: 로그 찍기
        log.debug(list.toString());

        return "exam06/dept/dept_all.jsp";
    }

    @GetMapping("/dept/{dno}")
    public String getDeptId(@PathVariable long dno,
                            Model model
                            ) {
//      todo: 서비스 상세조회 호출
        Dept dept = deptService.findById(dno);
        model.addAttribute("dept", dept);
        return "exam06/dept/dept_id.jsp";
    }

//  todo: 부서 추가 페이지 열기 함수
    @GetMapping("/dept/addition")
    public String addDept() {
        return "exam06/dept/add_dept.jsp";
    }

//  todo: 저장 버튼 클릭시 db 저장하기 함수
    @PostMapping("/dept/add")
    public RedirectView createDept(@ModelAttribute Dept dept) {
//      todo: 서비스 저장함수 호출
        deptService.save(dept);
//      todo: 저장 후 전체조회 url 로 강제 페이지 이동
//        사용법 : new RedirectView("강제이동될url주소")
        return new RedirectView("/exam06/dept");
    }

//  todo: 수정 페이지 열기 : 화면이 보일때 데이터도 화면에 미리 출력해야함
    @GetMapping("/dept/edition/{dno}")
    public String editDept(@PathVariable long dno, Model model) {
//      todo: 1) 상세 조회
        Dept dept = deptService.findById(dno); //
        model.addAttribute("dept", dept);
        return "exam06/dept/update_dept.jsp";
    }

//  todo: 수정 저장 : 리다이렉트(강제 이동) : 전체조회페이지로 이동
    @PutMapping("/dept/edit/{dno}")
    public RedirectView updateDept(@PathVariable long dno,
                                   @ModelAttribute Dept dept) {
//        todo: 수정 저장 함수 호출
        deptService.save(dept);
        return new RedirectView("/exam06/dept");
    }

//  todo: 삭제 함수 : 삭제 후 전체 조회로 리다이렉트(강제 이동)
    @DeleteMapping("/dept/delete/{dno}")
    public RedirectView deleteDept(@PathVariable int dno) {
        deptService.removeById(dno); // db 삭제

        return new RedirectView("/exam06/dept"); // 전체조회 강제이동
    }


//  todo: 연습 6)
//    Member06Service 클래스를 만들고 removeById() 함수를 정의한다.
//    Member06Controller 클래스를 만들어서 deleteMember() 함수를 정의
//    update_member.jsp 삭제버튼과 url 를 추가한다.
//    editMember()
//    - url : /member/delete/{eno}
//    - redirect url : /exam06/member

}








update_dept.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 lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<%--header --%>
<jsp:include page="../../common/header.jsp"/>
<%--본문--%>
<div class="container">
    <form action="/exam06/dept/edit/${dept.dno}" method="post">
<%-- TODO: 1) springboot 에서 아래와 같이 hidden 값을 전송하면 :  put 방식으로 인식해서 연결해줌    --%>
<%--       2) application.propeties : spring.mvc.hiddenmethod.filter.enabled=true --%>
        <input type="hidden" name="_method" value="put"/>
<%--     todo: 부서번호 : 화면에서 숨김 --%>
        <input type="hidden" name="dno" value="${dept.dno}"/>
<%--     todo: 부서이름 입력양식   --%>
        <div class="mb-3">
            <label for="dname" class="form-label">부서 이름</label>
            <input type="text"
                   class="form-control"
                   id="dname"
                   required
                   name="dname"
                   value="${dept.dname}"
            >
        </div>
<%--     todo: 부서위치 입력양식--%>
        <div class="mb-3">
            <label for="loc" class="form-label">부서 위치</label>
            <input type="text"
                   class="form-control"
                   id="loc"
                   required
                   name="loc"
                   value="${dept.loc}"
            >
        </div>
<%--     todo: 수정 버튼--%>
        <div class="mb-3">
            <button type="submit" class="btn btn-primary">Update</button>
        </div>
    </form>

    <form id="delete-form" action="/exam06/dept/delete/${dept.dno}" method="post">
        <%--    TODO: springboot 에서 아래와 같이 hidden 값을 전송하면 :  delete 방식으로 인식해서 연결해줌    --%>
        <input type="hidden" name="_method" value="delete"/>
        <button type="submit" class="btn btn-danger">Delete</button>
    </form>
</div>
<%--footer --%>
<jsp:include page="../../common/footer.jsp"/>

</body>
</html>


결과

※주의사항

buildgradle 있는 폴더에서 인텔리제이 실행 상위폴더에서는 x

콘트롤러에서 API 버튼 눌러서 실행시 Content-Type과 대괄호 사이 한줄 띄워야함

'Spring Boot' 카테고리의 다른 글

[Spring Boot]JPAExam  (1) 2023.10.16
[Spring boot] 파라메터  (0) 2023.10.05
[Spring boot]스프링 부트 프로젝트  (1) 2023.10.04