본문 바로가기
Spring

Day61 2024.08.19.월 #코딩일기

by SSONG1521 2024. 8. 19.


AOP  vs Interceptor

InterCeptor에서 prehandle 역할 vs AOP @Before 역할

InterCeptor에서 posthandle 역할 vs AOP @After 역할

SampleInterCeptor.java -> service(Interceptor prehandler)
SampleInterCeptor.java -> service(Interceptor posthandler)
AOP 에서 @Before / @After

 

 

 

 - interceptor는 개발자 단위로 짧게짧게

 - aop는 회사 단위(큰 단위, 조직 단위)로 빨리 업무를 수행해야할 때

   만일 실행시켰는데 모르는 method가 돌아가고 있으면 aop를 확인해보면 된다.

 

Chapter1. FrameWork

 

3. AOP (Aspect Oriented Programming)

 (1) 기능 외적인 관점의 용이한 적용을 위한 패러다임 AOP 의 개념

    ① 관점 지향 프로그램 (Aspect Oriented Programming, AOP)의 정의

        - 핵심 관심사 (Core Concerns) 에 대한 관점과 횡단 관심사 (Cross-cutting Concerns)에 대한 관점들로

          프로그램을 분해해 객체 지향 방식(OOP)에서 추구하는 모듈을 효과적으로 지원하도록 하는 

          프로그래밍 기법

    ② AOP의 등장 배경

구분 등장 배경
기능의 분산
(Scattering)
OOP의 SRP 원칙 실 세계에서 지키기 어렵다
그로 인해 객체지향으로 설계한 모듈에 보안이나 모니터링 기능이 분산해서 존재한다
코드의 혼란
(Trangling)
Infrastructure Service(Tracing, Logging, Monitoring 등)의 많은 요구로 인해 최초 OOP 방식으로 작성된 코드가 지저분한 코드로 바뀌게 된다.
OOP 코드 유지 OOP에 충실한 모듈의 구현

 

           1) 기존 OOP의 한계

              - 하나의 클래스에 핵심과 횡단 관심사가 혼재되어 프로그램의 가독성 및 재활용성에 비효율이 발생,

                 관심사를 분리 /  단순화 하여 코드의 재활용과 유지 보수의 효율성을 극대화

           2) AOP의 시스템 적용 예시

              - OOP의 구조는 계좌이체 클래스, 입출금 클래스, 이자계산 클래스로 나뉘게 되고,

                로깅, 보안, 트랜잭션 기능이 분산해서 존재

              - 타 프로젝트에서 기 구성 시스템 중 보안기능만을 분리한다고 할 경우

                기존의 OOP 방식으로는 이 보안 역할만을 별도 분리 불가

 

 

 

 (2) AOP의 특징

구분 특징
모듈화 횡단 관심사를 포괄적이고 체계적으로 모듈화
캡슐화 횡단 관심사는 Aspect라는 새로운 단위로 캡슐화하여 모듈화가 이루어짐
단순화 핵심 모듈은 더 이상 횡단 관심사의 모듈을 직접 포함하지 않으며 횡단 관심사의 모든 복잡성은 Aspect로 분리

 

 (3) AOP의 개념도 및 주요 요소

    ① AOP의 개념도

         - 핵심과 횡단의 분리를 이루고, AOP가 핵심 관심 모듈의 코드를 직접 건드리지 않고 필요한 기능을

            작동하는 데는 weaving 또는 cross-cutting 작업 필요

 

 

    ② AOP의 주요 요소

구분 특징
핵심 관심
(Core concern)
- 시스템이 추구하는 핵심 기능 및 가치
- Business 업무
횡단 관심
(Cross-cutting)
- 핵심 관심에 공통적으로 적용되는 부가적인 요구사항
- 보안, 인증, 로그작성, 정책 적용 등
- Cross-cutting Concern
Joint Point - 관심사를 구현한 코드에 끼워 넣을 수 있는 프로그램의 Event
Point-Cut - 관심사가 주 프로그램의 어디에 횡단할 것인지를 나타내는 위치
- aop:pointcutid=“pub1” expression=“within(com.oracle.sop1.St*)” />
Advice - 관심사를 구현하는 코드, 결합점에 삽입되어 동작할 수 있는 코드
- Point-cut에 의해 매칭된 joint point에 실행할 작업
- BEFORE, AROUND, AFTER의 실행 위치 지정
Aspect - 프로그램의 핵심관심사에 걸쳐 적용되는 공통 프로그램의 영역
- 특정 상황(point-cut)과 그 상황에서 수행할 작업 (advice)의 집합
- Point-cut 과 Advice를 합쳐 놓은 클래스 형태의 코드
- 특정 관심사에 관련된 코드만을 캡슐화
Weaving - Joint Point에 해당하는 Advice를 삽입하는 과정
- Aspect와 핵심 관심사를 엮는(weave)것을 의미

 

 

 

 

 (4) Spring AOP의 특징

특징 설명
표준자바 클래스 스프링의 경우 스프링 내에서 작성되는 모든 Advice는 표준 자바 클래스로 작성
Runtime 시점에서의 Advice 적용 Spring에서는 자체적으로 런타임 시에 위빙(weaving)하는 "프록시 기반의 AOP"를 지원
AOP 연맹의 표준 준수 스프링은 AOP 연맹의 인터페이스를 구현
메소드 단위 조인프인트만 제공 필드 단위의 조인포인트 등 다양한 조인포인트를 제공해주는 AspectJ 와 다르게 메소드 단위 조인포인트만 제공

 

스프링에서 AOP 구현 방법 (proxy를 이용)

 

 

  (5) Spring AOP Advice 종류 (★)

Advice 종류 XML 스키마 기반
POJO 클래스 이용
(현재 거의 사용 안함)
@Aspect
annotation  기반
설명
Before <aop:before> @Before target 객체의 메소드 호출 시 호출 전에 실행
AfterReturning <aop:after-returning> @After target 객체의 메소드가 예외 없이 실행된 후 호출
AfterThrowing <aop:after-throwing> @After Throwing target 객체의 메소드가 실행하는 중 예외가 발생한 경우에 실행
After <aop:after> @After target 객체의 메소드를 정상 또는 예외 발생 유무와 상관없이 실행
try의 finally 와 흡사
Around <aop:around> @Around target 객체의 메소드 실행 전, 후 또는 예외 발생 시점에 모두 실행해야 할 로직을 담아야 할 경우

 

 - Around는 before after 

 

     

  (6) Spring AOP 구현 예시

    1) <aop:config> 태그를 이용한 config 작성

 

 

    2) 횡단관심 Advice 구현

 

 

    3) 횡단관심 Advice 구현

 

 

 

 

 

 

 

*** js 파일 static에 넣어주기

js.zip
0.11MB

 

Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.aop
class LogAop
package com.oracle.oBootMybatis01.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.hibernate.internal.build.AllowSysOut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAop {
	
	//com.oracle.oBootMybatis01.dao package 안의 EmpDao이름을 가진 모든 것
	@Pointcut("within(com.oracle.oBootMybatis01.dao.EmpDao*)")
	private void pointcutMethod() {
		
	}
	
	@Around("pointcutMethod()")
	public Object LogAop(ProceedingJoinPoint joinPoint)throws Throwable {
		String signatureStr = joinPoint.getSignature().toShortString();
		System.out.println("LogAop >"+signatureStr + "< is start.");
		long st = System.currentTimeMillis();
		
		try {
			// 핵심 관심사 (Business(Buz)업무)
			//				proceed 단위로 왔다갔다 하면서 (totalEmp, listEmp)
			Object obj = joinPoint.proceed();
			return obj;
		} finally {
			long et = System.currentTimeMillis();
			System.out.println(signatureStr + "is finished.");
			System.out.println(signatureStr + " 경과시간 : "+(et-st));
		}
	}
	
	@Before("pointcutMethod()")
	public void beforeMethod() {
		System.out.println("LogAop beforeMethod start.");
	}
}
Console
 

 

 - aop는 aspect tag 걸어주어야 한다.

   controller, service, dao 외에는 @Component를 걸어주어야 한다.

 

 

 - com.oracle.oBootMybatis01.dao package 안의 EmpDao이름을 가진 모든 것

 

 - 

 - @Beford / @After 확인하기

     InterCeptor에서 prehandle 역할 vs AOP @Before 역할

     InterCeptor에서 posthandle 역할 vs AOP @After 역할

AOP 에서 @Before / @After

 

 - @Before 메소드 확인해보기

   보게되면, @Around와 거의 비슷하게 시작!  따라서 @Around를 쓰게 되면 따로 @Before 해줄 필요 없다.

 

 

 

 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.controller
class UploadController
package com.oracle.oBootMybatis01.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.Part;
import lombok.extern.slf4j.Slf4j;

@Controller
@Slf4j
public class UploadController {
	//uploadForm 시작화면
	@RequestMapping(value = "upLoadFormStart")
	public String upLoadFormStart(Model model) {
		System.out.println("UploadController upLoadFormStart Start...");
		return "upLoadFormStart";
	}
	
	@RequestMapping(value = "uploadForm", method = RequestMethod.GET)
	public void uploadForm() {
		System.out.println("UploadController uploadForm GET Start...");
		System.out.println("");
	}
	
	@RequestMapping(value = "uploadForm", method = RequestMethod.POST)
	public String uploadForm(HttpServletRequest request, Model model)
			throws IOException, Exception {
		
		Part image = request.getPart("file1");
		//업로드할 때 쓰기 위해서 file을 InputStream으로 만들어놓는다.
		InputStream inputStream = image.getInputStream();
		
		//파일 확장자 구하기
		String fileName = image.getSubmittedFileName();
		String[] split = fileName.split("\\.");
		String originalName = split[split.length-2];
		//확장자 .을 기준으로 위 아래로 나뉘어진다
		String suffix = split[split.length-1];
		
		System.out.println("fileName-> "+ fileName);
		System.out.println("originalName -> "+ originalName);
		System.out.println("suffix -> "+ suffix);
		
		//Servlet 상속받지 못했을 때 realPath로 불러오는 방법
		String uploadPath = request.getSession().getServletContext().getRealPath("/upload/");
		
		System.out.println("UploadController uploadForm POST Start...");
		//진짜 업로드하는 logic
		String savedName = uploadFile(originalName, inputStream, uploadPath, suffix);
		//Service --> DB CRUD ----> 프로젝트 할 때 직접 연결시켜주기 (여기서는 연습)
		
		log.info("Return savedName : "+ savedName);
		model.addAttribute("savedName", savedName);
		
		return "uploadResult";
	}

	private String uploadFile(String originalName, 
							  InputStream inputStream, 
							  String uploadPath, 
							  String suffix) throws FileNotFoundException, IOException {
		
		System.out.println("UploadController uploadFile Start...");
		
		//universally unique identifier (UUID). -> 식별자를 random하게!
		//만일 업로드 파일 명을 랜덤하게 지어줄 수 있다면 안써도 되는 로직
		UUID uid = UUID.randomUUID();
		//requesPath = requestPath + "/resources/image";
		System.out.println("uploadPath-> "+uploadPath);
		
		//Directory 생성
		File fileDirectory = new File(uploadPath);
		//폴더 없으면 만들기 위한 logic
		if (!fileDirectory.exists()) {
			//신규 폴더(Directory) 생성
			fileDirectory.mkdirs();
			System.out.println("업로드용 폴더 생성 : "+uploadPath);
		}
		
		String savedName = uid.toString() + "_" + originalName +"." +suffix;
		log.info("savedName: "+savedName);
		
		//임시파일 생성 (uploadPath가 포함되어있어서 metadata까지 포함되어있음) -> 그냥 배포해도 가능
		File tempFile = new File(uploadPath+savedName);
		
		//-------------------------------------------------------------------
		//Backup File
		File tempFile3 = new File("c:/backup/"+savedName);
		FileOutputStream outputStream3 = new FileOutputStream(tempFile3);
		//-------------------------------------------------------------------
		
		//생성된 임시 파일에 요청으로 넘어온 file의 inputStream 복사
		try (FileOutputStream outputStream = new FileOutputStream(tempFile)){
			int read;
			byte[] bytes = new byte[1024];
			while ((read = inputStream.read(bytes)) != -1) {
													//-1은 파일이 끝날 때 까지 계속
				
				// Target File 에 요청으로 넘어온  file의 inputStream 복사
				outputStream.write(bytes, 0, read);
				//backup 파일에 요청으로 넘어온 file의 inputStream 복사
				outputStream3.write(bytes, 0, read);
				
			}
		} finally {
			System.out.println("UpLoad The End");
		}
		//inputStream으로 부른 것은 자동으로 close 되기 때문에!!
		outputStream3.close();
		
		return savedName;
	}
	
	@RequestMapping(value = "uploadFileDelete", method = RequestMethod.GET)
	public String uploadFileDelete(HttpServletRequest request, Model model) {
		String uploadPath = request.getSession().getServletContext().getRealPath("/upload/");
		//Backup Folder
		String uploadPath3 = "c:/backup/";
		
		String deleFile = request.getParameter("delFile");	//delFile
		
		System.out.println("UploadController uploadFileDelete GET Start...");
		String deleteFile = uploadPath + deleFile;
		String deleteFile3 = uploadPath3 + deleFile;
		System.out.println("uploadFileDelete deleteFile-> "+deleteFile);
		
		int delResult = upFileDelete(deleteFile);
		int delResult3 = upFileDelete(deleteFile3);
		model.addAttribute("deleteFile", deleteFile);
		model.addAttribute("delResult", delResult);
		
		return "uploadResult";
	}

	private int upFileDelete(String deleteFileName) {
		int result = 0;
		log.info("upFileDelete result-> "+deleteFileName);
		File file = new File(deleteFileName);
		if (file.exists()) {
			if (file.delete()) {
				System.out.println("파일 삭제 성공");
				result = 1;
			} else {
				System.out.println("파일 삭제 실패");
				result = 0;
			}
		} else {
			System.out.println("삭제할 파일이 존재하지 않습니다.");
			result = -1;
		}
		return result;
	}
	
	
	
}
Console
 

 

 - upload 해주는 controller

 - class 이름에 controller 넣어주는 것은 그저 명명한 것,  @Controller를 해주어야 한다.

 

 - 옛날에는 servlet을 상속받았지만, 여기서는 servlet을 상속받지 않고 controller로

 

 - 파일업로드를 실행하면,

   파일이 업로드 된 폴더 자동 생성해주고, 파일이 들어가져 있다.

   파일 이름은 UUID로 랜덤으로 넣어준 것!

 

 

 - 파일 삭제 logic -> jsp화면에서 지워짐 (실제로 지워진게 아님) -> 삭제 로직 껍데기만 만들어준 것

     upload 뒤에 이름이 맞는지 확인해주고, 시작하기

console 창

 

 - 자동완성으로 logic 만들어주기

 

 - 삭제 로직

 

 - 파일 delete

 

 

 

 - 지정한 폴더에 업로드 파일 올려주기!! (metadata가 아니라!!) -> 하지만 metadata를 더 많이 쓴다!!

   실행시켜준 후, 파일 새로 업로드 해주면, 2개의 경로에 다 저장되어 있다.

 

 - 지정된 폴더 로직을 delete 로직에 넣어주기 (파일 업로드 후 삭제해주면, 해당 로직을 타고 삭제된다.)

 

 

 

 

 

 



Spring Starter Project oBootMybatis01
folder resources
yml application.yml
server:
  port: 8387
# Oracle Connect
spring:
  
  #File Size
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB
  
  datasource:
    driver-class-name: oracle.jdbc.driver.OracleDriver
    url: jdbc:oracle:thin:@localhost:1521/xe
    username: scott
    password: tiger
    
  #Jpa Setting
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
            # @Entity라고 설정되어 있는 것들 만 update, none, create 등등
            # release 할 때에는 none으로 바꿔주어야 한다!!!!
            
  #View Resolver
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp
      
  # gmail Transfer    
  mail:
    host: smtp.gmail.com
    port: 587
    username: kateshs0521@gmail.com
    password: pdqm xzdp imck zbql
    properties:
      mail:
        smtp:
          auth: true
          starttls.enable: true
      
# Mybatis
mybatis:
  config-location: classpath:configuration.xml
  mapper-locations: classpath:mappers/*.xml
  # classpath -> resource이다!!
Console
 

 

 - spring 밑에 datasource와 같은 줄에 작성해주기

 

 

 

 

 

 

 

 

Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
JSP upLoadFormStart.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	UpLoad Image : <img alt="UpLoad Image" src="${pageContext.request.contextPath }/upload/${saveName}">
	
	<form id="form1" action="uploadForm" method="post" enctype="multipart/form-data">
		<input type="file" name="file1"> <p>
		<input type="text" name="title"> <p>
		<input type="submit">
	</form>
</body>
</html>
Console

 

 - image나 file을 올리기 위해서 필수 사항 3가지

 

 

 

 

Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
JSP uploadResult.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	Image : ${savedName } <p>
	UpLoad Image : <img alt="UpLoad Image" src="${pageContext.request.contextPath }/upload/${savedName }">
	
	<a href="uploadFileDelete?delFile=${savedName }">upLoad 삭제 Test</a>
</body>
</html>
Console

 

 

 

 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.controller
class EmpController
package com.oracle.oBootMybatis01.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.DeptVO;
import com.oracle.oBootMybatis01.model.Emp;
import com.oracle.oBootMybatis01.model.EmpDept;
import com.oracle.oBootMybatis01.model.Member1;
import com.oracle.oBootMybatis01.service.EmpService;
import com.oracle.oBootMybatis01.service.Paging;
import com.oracle.wls.shaded.org.apache.regexp.RE;
import com.oracle.wls.shaded.org.apache.xalan.xsltc.compiler.sym;

import jakarta.mail.internet.MimeMessage;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Controller
@RequiredArgsConstructor
//logger 쓰는 것!!!
@Slf4j
public class EmpController {
	private final EmpService es;
	private final JavaMailSender mailSender;
	
	@RequestMapping(value = "listEmpStart")
	public String listEmpStart(Emp emp, Model model) {
		System.out.println("EmpController listEmpStart Start...");
		//21명 -> 3page가 있어야 한다.
		int totalEmp = es.totalEmp();
		String currentPage = "1";
		
		//Paging 작업
		Paging page = new Paging(totalEmp, currentPage);
		
		//Parameter emp --> Page만 추가 Setting
		emp.setStart(page.getStart());	//시작 시 1
		emp.setEnd(page.getEnd());		//시작 시 10
		
		List<Emp> listEmp = es.listEmp(emp);
		System.out.println("EmpController list listEmp.size()-> "+listEmp.size());
		
		model.addAttribute("totalEmp", totalEmp);
		model.addAttribute("listEmp",listEmp);
		model.addAttribute("page",page);
		System.out.println("EmpController listEmpStart End...");
		
		// ViewResolver에 의해 list.jsp로 이동
		return "list";
	}
	
	@RequestMapping(value = "listEmp")
	public String listEmp(Emp emp, Model model) {
		System.out.println("EmpController listEmp Start...");
		//21명 -> 3page가 있어야 한다.
		int totalEmp = es.totalEmp();
		
		//Paging 작업
		Paging page = new Paging(totalEmp, emp.getCurrentPage());
		
		//Parameter emp --> Page만 추가 Setting
		emp.setStart(page.getStart());	//시작 시 1
		emp.setEnd(page.getEnd());		//시작 시 10
		
		List<Emp> listEmp = es.listEmp(emp);
		System.out.println("EmpController list listEmp.size()-> "+listEmp.size());
		
		model.addAttribute("totalEmp", totalEmp);
		model.addAttribute("listEmp",listEmp);
		model.addAttribute("page",page);
		System.out.println("EmpController listEmp End...");
		
		// ViewResolver에 의해 list.jsp로 이동
		return "list";
	}
	
	@GetMapping(value = "detailEmp")
	public String detailEmp(Emp emp1, Model model) {
		System.out.println("EmpController Start detailEmp...");
//		1. EmpService안에 detailEmp method 선언
//		   1) parameter : empno
//		   2) Return      Emp
//
//		2. EmpDao   detailEmp method 선언 
////		                    mapper ID   ,    Parameter
//		emp = session.selectOne("tkEmpSelOne",    empno);
//		System.out.println("emp-> "+emp1);
		
		Emp emp = es.detailEmp(emp1.getEmpno());
		
		System.out.println("emp-> "+emp1);
		model.addAttribute("emp", emp);	
		System.out.println("EmpController End detailEmp...");
		
		return "detailEmp";
	}
	
	@GetMapping(value = "updateFormEmp")
	public String updateFormEmp(Emp emp1, Model model) {
		//							emp1에 empno가 들어가진다.
		System.out.println("EmpController Start updateFormEmp...");
		Emp emp = es.detailEmp(emp1.getEmpno());
		System.out.println("EmpController updateFormEmp emp-> "+emp);
		// 문제 
		// 1. DTO  String hiredate
		// 2.View : 단순조회 OK ,JSP에서 input type="date" 문제 발생
		// 3.해결책  : 년월일만 짤라 넣어 주어야 함
		
		String hiredate="";
		if(emp.getHiredate() != null) {
			hiredate = emp.getHiredate().substring(0,10);
			emp.setHiredate(hiredate);
		}
		
		System.out.println("hiredate-> "+hiredate);
		
		model.addAttribute("emp", emp);	
		System.out.println("EmpController End updateFormEmp...");
		return "updateFormEmp";
	}
	
	@PostMapping(value = "updateEmp")
	public String updateEmp(Emp emp, Model model) {
		log.info("EmpController updateEmp Start....");
		int updateCount = es.updateEmp(emp);
//      1. EmpService안에 updateEmp method 선언
//      1) parameter : Emp
//      2) Return      updateCount (int)
//
//   2. EmpDao updateEmp method 선언
//	                              mapper ID   ,    Parameter
//   updateCount = session.update("tkEmpUpdate",   emp);
		System.out.println("EmpController es.updateEmp updateCount--> "+updateCount);
		model.addAttribute("uptCnt",updateCount);		//Test Controller 간 Data 전달
		model.addAttribute("kk3","Message Test");		//Test Controller 간 Data 전달
		System.out.println("EmpController addAttribute After....");
		log.info("EmpController updateEmp End....");
		
		//redirect: 같은 controller 안에 있는 listEmp로 돌아간다는 의미!!!!
		return "forward:listEmp";
//		return "redirect:listEmp";
			
	}
	
	@RequestMapping(value = "writeFormEmp")
	public String writeFormEmp(Model model) {
		System.out.println("EmpController writeFormEmp Start...");
		
		
		//관리자 사번만 Get
		List<Emp> empList = es.listManager();
		System.out.println("EmpController writeForm empList.size()-> "+ empList.size());
		model.addAttribute("empMngList", empList);	//emp Manager List
		
		// 1. service -> listManager
		// 2. Dao     -> listManager
		// 3. mapper  -> tkSelectManager
		
		//부서(코드, 부서명)
		List<Dept> deptList = es.deptSelect();
		model.addAttribute("deptList", deptList);	//dept
		System.out.println("EmpController writeForm deptList.size()-> "+deptList.size());
		
		System.out.println("EmpController writeFormEmp End...");
		
		return "writeFormEmp";
	}
	
	@PostMapping(value = "writeEmp")
	public String writeEmp(Emp emp, Model model) {
		System.out.println("EmpController start writeEmp...");
		
		// Service, Dao , Mapper명[insertEmp] 까지 -> insert
		int insertResult = es.insertEmp(emp);
		if (insertResult > 0) return "redirect:listEmp";
		else {
			model.addAttribute("msg", "입력 실패! 확인해보세요");
			return "forward:writeFormEmp";
		}

	}
	
	@GetMapping(value = "confirm")
	public String confirm(Emp emp1, Model model) {
		Emp emp = es.detailEmp(emp1.getEmpno());
		model.addAttribute("empno", emp1.getEmpno());
		if (emp != null) {
			System.out.println("EmpController confirm 중복된 사번..");
			model.addAttribute("msg", "중복된 사번입니다.");
//			return "forward:writeFormEmp";
		} else {
			System.out.println("EmpController confirm 사용 가능한 사번..");
			model.addAttribute("msg", "사용 가능한 사번입니다.");
//			return "forward:writeFormEmp";
		}
		return "forward:writeFormEmp";
	}
	
	@RequestMapping(value = "deleteEmp")
	public String deleteEmp(Emp emp, Model model) {
		System.out.println("EmpController Start deleteEmp...");
		// Controller -->  deleteEmp    1.parameter : empno
		// name -> Service, dao , mapper
		// return -> listEmp
		int result = es.deleteEmp(emp.getEmpno());
		return "redirect:listEmp";
	}
	
	@RequestMapping(value = "writeFormEmp3")
	public String writeFormEmp3(Model model) {
		System.out.println("EmpController writeFormEmp3 Start...");
		
		
		//관리자 사번만 Get
		List<Emp> empList = es.listManager();
		System.out.println("EmpController writeForm empList.size()-> "+ empList.size());
		model.addAttribute("empMngList", empList);	//emp Manager List
		
		// 1. service -> listManager
		// 2. Dao     -> listManager
		// 3. mapper  -> tkSelectManager
		
		//부서(코드, 부서명)
		List<Dept> deptList = es.deptSelect();
		model.addAttribute("deptList", deptList);	//dept
		System.out.println("EmpController writeForm deptList.size()-> "+deptList.size());
		
		System.out.println("EmpController writeFormEmp3 End...");
		
		return "writeFormEmp3";
	}
	
	// Validation시 참조
	@PostMapping(value = "writeEmp3")
	public String writeEmp3(@ModelAttribute("emp") @Valid Emp emp
							, BindingResult result
							, Model model) {
		System.out.println("EmpController start writeEmp3...");
		
		// Validation 오류시 Result
		if (result.hasErrors()) {
			System.out.println("EmpController writeEmp3 hasErrors...");
			model.addAttribute("msg", "BindingResult 입력 실패 확인해보세요");
			return "forward:writeFormEmp3";
		}
		
		// Service, Dao , Mapper명[insertEmp] 까지 -> insert
		int insertResult = es.insertEmp(emp);
		if (insertResult > 0) return "redirect:listEmp";
		else {
			model.addAttribute("msg", "입력 실패! 확인해보세요");
			return "forward:writeFormEmp3";
		}

	}
	
	@RequestMapping(value = "listSearch3")
	public String listSearch3(Emp emp, Model model) {
		System.out.println("EmpController listSearch3 Start...");
		System.out.println("EmpController listSearch3 emp-> "+emp);
		
		//Emp 전체 count
		int totalEmp = es.condTotalEmp(emp);
		System.out.println("EmpController listSearch3 totalEmp-> "+totalEmp);
		
		//Paging 작업
		Paging page = new Paging(totalEmp, emp.getCurrentPage());
		
		//Parameter emp --> Page 만 추가 Setting
		emp.setStart(page.getStart());	//시작 시 1
		emp.setEnd(page.getEnd());		//시작 시 10
		System.out.println("EmpController listSearch3 page-> "+page);
		
		List<Emp> listSearchEmp = es.listSearchEmp(emp);
		System.out.println("EmpController listSearch3 listSearchEmp.size()-> "+listSearchEmp.size());
		
		model.addAttribute("totalEmp", totalEmp);
		//왜 listEmp로 보내주냐면, list.jsp로 가보면 listEmp로 되어있기 때문에 (재활용 위해서)
		model.addAttribute("listEmp", listSearchEmp);
		model.addAttribute("page", page);
		
		
		return "list";
	}
	
	@GetMapping(value = "listEmpDept")
	public String listEmpDept(Model model) {
		System.out.println("EmpController listEmpDept start...");
		// Service ,DAO -> listEmpDept
		// Mapper만 ->EmpDept.xml(tkListEmpDept)
		List<EmpDept> listEmpDept = es.listEmpDept();
		model.addAttribute("listEmpDept", listEmpDept);
		
		System.out.println("EmpController listEmpDept End...");
		return "listEmpDept";
	}
	
	@RequestMapping(value = "mailTransport")
	public String mailTransport(HttpServletRequest request, Model model) {
		System.out.println("mailSending...");
		String tomail = "kate__@naver.com";							//받는 사람 이메일
		System.out.println(tomail);
		String setfrom = "kateshs0521@gmail.com";
		String title = "mailTransport 입니다";		//제목
		
		try {
			// MIME(영어: Multipurpose Internet Mail Extensions)는 전자 우편을 위한 인터넷 표준 포맷
			MimeMessage message = mailSender.createMimeMessage();
			//값을 세팅하기 위해서 Helper를 이용해야 한다.
			MimeMessageHelper messageHelper = new MimeMessageHelper(message, true,"UTF-8");
			messageHelper.setFrom(setfrom);		//보내는 사람 생략하거나 하면 정삭작동을 안함
			messageHelper.setTo(tomail);		//받는 사람 이메일
			messageHelper.setSubject(title);	//메일 제목은 생략이 가능하다
			
			String tempPassword = (int) (Math.random() * 999999) +1 +"";
			messageHelper.setText("임시 비밀번호입니다 : "+tempPassword);		//메일 내용
			System.out.println("임시 비밀번호입니다 : "+tempPassword);
			
			mailSender.send(message);
			model.addAttribute("check", 1);		//정상 전달
			
			//DB Logic
			
			
			
		} catch (Exception e) {
			System.out.println("mailTransport e.getMessage()-> "+e.getMessage());
			model.addAttribute("check", 2);	//메일 전달 실패
		}
		
		return "mailResult";
	}
	
	// Procedure Test 입력화면
	@RequestMapping(value = "writeDeptIn")
	public String writeDeptIn(Model model) {	
		System.out.println("writeDeptIn Start.,..");
		
		System.out.println("writeDeptIn End....");
		return "writeDept3";
	}
	
	//Procedure 통한 Dept 입력 후 VO 전달
	@PostMapping(value = "writeDept")
	public String writeDept(DeptVO deptVO, Model model) {
		es.insertDept(deptVO);
		if (deptVO == null) {
			System.out.println("deptVO NULL");
		} else {
			System.out.println("deptVO.getOdeptno()"+deptVO.getOdeptno());
			System.out.println("deptVO.getOdname()"+deptVO.getOdname());
			System.out.println("deptVO.getOloc()"+deptVO.getOloc());
			model.addAttribute("msg", "정상 입력 되었습니다. ^^");
			model.addAttribute("dept", deptVO);
		}
		return "writeDept3";
	}
	
	//Map 적용
	@GetMapping(value = "writeDeptCursor")
	public String writeDeptCursor(Model model) {
		System.out.println("EmpController writeDeptCursor Start...");
		// 부서범위 조회
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("sDeptno", 10);
		map.put("eDeptno", 55);
		
		//call by reference map
		es.selListDept(map);
		List<Dept> deptLists = (List<Dept>)map.get("dept");
		for(Dept dept : deptLists) {
			System.out.println("writeDeptCursor dept -> "+dept);
			System.out.println("dept.getDname()-> "+dept.getDname());
			System.out.println("dept.getLoc()-> "+dept.getLoc());
		}
		System.out.println("deptList Size-> "+deptLists.size());
		model.addAttribute("deptList", deptLists);
		
		return "writeDeptCursor";
	}
	
	//interCeptor 시작 화면
	@RequestMapping(value = "interCeptorForm")
	public String interCeptorForm() {
		System.out.println("EmpController interCeptorForm start...");
		return "interCeptorForm";
	}
	
	// 2. interCeptor Number2
	@RequestMapping(value = "interCeptor")
	public String interCeptor(Member1 member1, Model model) {
		System.out.println("EmpController interCeptor Test Start");
		System.out.println("EmpController interCeptor id-> "+member1.getId());
		// 존재 : 1, 비존재 : 0
		int memCnt = es.memCount(member1.getId());
		
		System.out.println("EmpController interCeptor memCnt -> "+memCnt);
		
		model.addAttribute("id", member1.getId());
		model.addAttribute("memCnt", memCnt);
		System.out.println("EmpController interCeptor Test End");
		
		return "interCeptor";	//User 존재하면 User 이용 조회 Page
	}
	
	//SampleInterCeptor 내용을 받아 처리
	@RequestMapping(value = "doMemberWrite")
	public String doMemberWrite(Model model, HttpServletRequest request) {
		String ID = (String) request.getSession().getAttribute("ID");
		System.out.println("doMemberWrite 부터 하세요");
		model.addAttribute("id", ID);
		return "doMemberWrite";
	}
	
	//interCeptor 진행 Test
	@RequestMapping(value = "doMemberList")
	public String doMemberList(Model model, HttpServletRequest request) {
		System.out.println("EmpController doMemberList Start...");
		String ID = (String) request.getSession().getAttribute("ID");
		System.out.println("doMemberList Test Start ID -> "+ID);
		Member1 member1 = null;
		// 로그인 한 사람만 보여주고 싶은 페이지일 때!!
		// Member1 List Get Service
		// Service, DAO --> listMem
		// Mapper --> listMember1
		// Member1 모든 Row Get
		List<Member1> listMem = es.listMem(member1);
		model.addAttribute("ID", ID);
		model.addAttribute("listMem", listMem);
		
		System.out.println("EmpController doMemberList End...");
		return "doMemberList";	//User 존재하면 User 이용 조회 Page
	}
	
	//	ajaxForm Test 입력하면
	@RequestMapping(value = "ajaxForm")
	public String ajaxForm(Model model) {
		System.out.println("ajaxForm Start...");
		return "ajaxForm";
	}
	
	@ResponseBody
	@RequestMapping(value = "getDeptName")
	public String getDeptName(Dept dept, Model model) {
		System.out.println("EmpController getDeptName Start...");
		System.out.println("deptno-> "+dept.getDeptno());
		String deptName = es.deptName(dept.getDeptno());
		System.out.println("deptName-> "+deptName);
		//mapper --> EmpDept(tkDeptName)
		System.out.println("EmpController getDeptName End...");
		return deptName;
	}
	
	//Ajax List Test (ajax를 수행하기 위한 준비 화면 -> @ResponseBody 안붙혀도 된다.)
	@RequestMapping(value = "listEmpAjaxForm")
	public String listEmpAjaxForm(Model model) {
		Emp emp = new Emp();
		System.out.println("EmpController listEmpAjaxForm Start...");
		
		//Parameter emp --> Page만 추가 Setting
		emp.setStart(1);	//시작 시 1
		emp.setEnd(10);		//시작 시 10
		
		List<Emp> listEmp = es.listEmp(emp);
		System.out.println("EmpController listEmpAjaxForm listEmp.size()-> "+listEmp.size());
		model.addAttribute("result", "kkk");
		model.addAttribute("listEmp", listEmp);
		
		return "listEmpAjaxForm";
	}
	
	@ResponseBody
	@RequestMapping(value = "empSerializeWrite")
	public Map<String, Object> empSerializeWrite(@RequestBody @Valid Emp emp) {
//	public Map<String, Object> empSerializeWrite(@Valid Emp emp) {
		System.out.println("EmpController empSerializeWrite Start...");
		System.out.println("EmpController empSerializeWrite emp-> "+emp);
		int writeResult = 1;
		// int writeResult = kkk.writeEmp(emp);
		// String followingProStr = Integer.toString(followingPro);
		
		Map<String, Object> resultMap = new HashMap<>();
		System.out.println("EmpController empSerializeWrite writeResult-> "+writeResult);
		
		resultMap.put("writeResult", writeResult);
		System.out.println("EmpController empSerializeWrite writeResult-> "+writeResult);
		return resultMap;
	}
}
Console
 

 

 - ajax 매우 중요!!!

 



 

Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.controller
class EmpRestController
package com.oracle.oBootMybatis01.controller;

import java.util.List;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.SampleVO;
import com.oracle.oBootMybatis01.service.EmpService;

import lombok.RequiredArgsConstructor;

//@Controller + @ResponseBody
@RestController
@RequiredArgsConstructor
public class EmpRestController {
	
	private final EmpService es;
	
	@RequestMapping("/helloText")
	public String helloText() {
		System.out.println("EmpRestController helloText Start...");
		String hello = "안녕";
		//	   StringConverter
		return hello;
	}
	
	// http://jsonviewer.stack.hu/
	@RequestMapping(value = "/sample/sendVO2")
	public SampleVO sendVO2(Dept dept) {
		System.out.println("EmpRestController SampleVO Start....");
		System.out.println("@RestController SampleVO dept.getDeptno()-> "+dept.getDeptno());
		SampleVO vo = new SampleVO();
		vo.setFirstName("길동");
		vo.setLastName("홍");
		vo.setMno(dept.getDeptno());
		
		System.out.println("EmpRestController SampleVO End....");
		//객체가 return
		return vo;
	}
	
	@RequestMapping("/sendVO3")
	public List<Dept> sendVO3() {
		System.out.println("EmpRestController @RestController sendVO3 START..");
		List<Dept> deptList = es.deptSelect();
		return deptList;
	}
}
Console
 

 

 - Ajax ★★★★★

 - RestController로 지정해준다.

   @RestController -> api 만들기 or ajax 만들 때 사용한다. (2가지 목적)

   @RestController = @Controller + @ResponseBody

 

 

 - StringConverter가 작동되면, -> helloText

    Controller라도 @ResponseBody가 있으면, (원래는 viewResolver로 return 하는데, prefix, suffix로 )

    @ResponseBody가 있으면, HttpMessageConverter가 String이면 String Converter

                                                                                          Object이면 Json Converter를 부른다.

 

 

 

 - SampleVO를 위해서 model에서 SampleVO 만들어주기!

   request.addattribute로 불러올 수도 있지만, 객체로 불러와줄 수도 있다. deptno를 보냈으므로, deptno가 있는 DTO 를 활용하면 된다.

ajaxForm.jsp
EmpRestController

 

 

   controller 로직을 보게 되면, vo가 return 되는데, 객체가 return 되어서HttpMessageConverter가

                                                 JsonConverter를 불러서 작동된다.

 - https://jsonviewer.stack.hu/

 

Online JSON Viewer and Formatter

 

jsonviewer.stack.hu

JSON 사이트로, 실행시켜서 나온 값을  해당 사이트에 입력한 후, viewer 해주면!! 아래와 같이 정리되어서 나온다.

 

 

 - sendVO3 -> 이미 만들어놓은 logic 이용하기!!

    마찬가지로 JSON 사이트에서 상세 내용 정리된 것 확인해보기 ( 간단한 걸 쓸 때에는 postman보다 유용)

 

 

 

 - 값은 다 들어가는데, 실행 안되는 이유?

 

   EmpController에서 return 되는 값이 string이기 때문에, responsebody를 찾는 것

       -> @ResponseBody를 넣어주어야

  여기까지는 ajax 연습!!


이제부터 ajax 시작 (controller 이어서)

 - ajax List Test

 

 

 

 

 

 

 

 

 

Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.model
class SampleVO
package com.oracle.oBootMybatis01.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class SampleVO {
	private Integer mno;
	private String 	firstName;
	private String 	lastName;
}
Console
 

 

 

 

 

 

Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.service
implement EmpService
package com.oracle.oBootMybatis01.service;

import java.util.HashMap;
import java.util.List;

import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.DeptVO;
import com.oracle.oBootMybatis01.model.Emp;
import com.oracle.oBootMybatis01.model.EmpDept;
import com.oracle.oBootMybatis01.model.Member1;

public interface EmpService {
	int 			totalEmp();
	List<Emp>  		listEmp(Emp emp);
	Emp 			detailEmp(int empno);
	int 			updateEmp(Emp emp);
	List<Emp> 		listManager();
	List<Dept> 		deptSelect();
	int 			insertEmp(Emp emp);
	int 			deleteEmp(int empno);
	int 			condTotalEmp(Emp emp);
	List<Emp> 		listSearchEmp(Emp emp);
	List<EmpDept> 	listEmpDept();
	void 			insertDept(DeptVO deptVO);
	void 			selListDept(HashMap<String, Object> map);
	int 			memCount(String id);
	List<Member1> 	listMem(Member1 member1);
	String 			deptName(int deptno);
	
}
Console
 

 

 

 

 

 

 

Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.service
class EmpServiceImpl
package com.oracle.oBootMybatis01.service;

import java.util.HashMap;
import java.util.List;

import org.springframework.stereotype.Service;

import com.oracle.oBootMybatis01.dao.DeptDao;
import com.oracle.oBootMybatis01.dao.EmpDao;
import com.oracle.oBootMybatis01.dao.Member1Dao;
import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.DeptVO;
import com.oracle.oBootMybatis01.model.Emp;
import com.oracle.oBootMybatis01.model.EmpDept;
import com.oracle.oBootMybatis01.model.Member1;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class EmpServiceImpl implements EmpService {
	
	//interface가 각각 하나라면, 여러개의 dao를 만들 수 있다.
	//if EmpDao interface에 JPA dao가 하나 더 연결(implement)되어 있으면, 기존의 myBatis는 annotation 없애주어야 한다.
	private final EmpDao ed;
	private final DeptDao dd;
	private final Member1Dao md;

	@Override
	public int totalEmp() {
		System.out.println("EmpServiceImpl totalEmp start...");
		int totEmpCnt = ed.totalEmp();
		System.out.println("EmpServiceImpl totalEmp totEmpCnt->"+totEmpCnt);
		return totEmpCnt;
	}

	@Override
	public List<Emp> listEmp(Emp emp) {
		List<Emp> empList = null;
		System.out.println("EmpServiceImpl listManager Start...");
		empList = ed.listEmp(emp);
		System.out.println("EmpServiceImpl listEmp empList.size()-> "+empList.size());
		return empList;
	}

	@Override
	public Emp detailEmp(int empno) {
		System.out.println("EmpServiceImpl detailEmp start...");
		Emp emp = ed.detailEmp(empno);
		System.out.println("EmpServiceImpl detailEmp emp-> "+emp);
//		1. EmpService안에 detailEmp method 선언
//		   1) parameter : empno
//		   2) Return      Emp
		return emp;
	}

	@Override
	public int updateEmp(Emp emp) {
//      1. EmpService안에 updateEmp method 선언
//      1) parameter : Emp
//      2) Return      updateCount (int)
		System.out.println("EmpServiceImpl updateEmp Start...");
		int updateCount = 0;
		updateCount = ed.updateEmp(emp);
		System.out.println("EmpServiceImpl updateEmp updateCount-> "+updateCount);
		System.out.println("EmpServiceImpl updateEmp ed.updateEmp After...");
		return updateCount;
	}

	@Override
	public List<Emp> listManager() {
		System.out.println("EmpServiceImpl listManager Start...");
		List<Emp> empList = null;
		empList = ed.listManager();
		System.out.println("EmpServiceImpl listManager empList.size()-> "+empList.size());
		System.out.println("EmpServiceImpl listManager ed.listManager After...");
		
		return empList;
	}

	@Override
	public List<Dept> deptSelect() {
		System.out.println("EmpServiceImpl deptSelect Start...");
		List<Dept> deptList = null;
		deptList = dd.deptSelect();
		
		System.out.println("EmpServiceImpl deptSelect deptList.size()-> "+deptList.size());
		System.out.println("EmpServiceImpl deptSelect dd.deptSelect After...");
		//tkSelectDept
		return deptList;
	}

	@Override
	public int insertEmp(Emp emp) {
		System.out.println("EmpServiceImpl insertEmp Start...");
		int result = ed.insertEmp(emp);
		
		System.out.println("EmpServiceImpl insertEmp result-> "+result);
		System.out.println("EmpServiceImpl insertEmp ed.insertEmp After...");
		
		return result;
	}

	@Override
	public int deleteEmp(int empno) {
		System.out.println("EmpServiceImpl deleteEmp Start...");
		int result = ed.deleteEmp(empno);

		System.out.println("EmpServiceImpl insertEmp result-> "+result);
		System.out.println("EmpServiceImpl insertEmp ed.insertEmp After...");
		
		return result;
	}

	@Override
	public int condTotalEmp(Emp emp) {
		System.out.println("EmpServiceImpl condTotalEmp Start...");
		int totEmpCnt = ed.condTotalEmp(emp);
		System.out.println("EmpServiceImpl condTotalEmp totEmpCnt -> "+totEmpCnt);
		return totEmpCnt;
	}

	@Override
	public List<Emp> listSearchEmp(Emp emp) {
		System.out.println("EmpServiceImpl listSearchEmp Start...");
		List<Emp> empList = null;
		// 1. DAO  ed.empSearchList3(emp);
        // 2. Mapper selectList("tkEmpSearchList3", emp);
		empList = ed.empSearchList3(emp);
		System.out.println("EmpServiceImpl listSearchEmp empList -> "+empList);
		return empList;
	}

	@Override
	public List<EmpDept> listEmpDept() {
		System.out.println("EmpServiceImpl listEmpDept Start...");
		List<EmpDept> listEmpDept = null;
		
		listEmpDept = ed.listEmpDept();
		System.out.println("EmpServiceImpl listEmpDept listEmpDept.size() -> "+listEmpDept.size());
		return listEmpDept;
	}

	@Override
	public void insertDept(DeptVO deptVO) {
		System.out.println("EmpServiceImpl insertDept Start...");
		dd.insertDept(deptVO);
		
	}

	@Override
	public void selListDept(HashMap<String, Object> map) {
		System.out.println("EmpServiceImpl selListDept Start...");
		dd.selListDept(map);
		
	}

	@Override
	public int memCount(String id) {
		System.out.println("EmpServiceImpl memCount Start...");
		System.out.println("EmpServiceImpl memCount id -->"+id);
		
		return md.memCount(id);
	}

	@Override
	public List<Member1> listMem(Member1 member1) {
		List<Member1> listMem = null;
		System.out.println("EmpServiceImpl listMem Start...");
		System.out.println("EmpServiceImpl listMem.size() -->"+listMem.size());
		listMem = md.listMem(member1);
		return listMem;
	}

	@Override
	public String deptName(int deptno) {
		System.out.println("EmpServiceImpl deptName Start...");
		String deptName = null;
		deptName = ed.deptName(deptno);
		System.out.println("EmpServiceImpl deptName -->"+deptName);
		
		return deptName;
	}

}
Console
 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.dao
interface EmpDao
package com.oracle.oBootMybatis01.dao;

import java.util.List;

import com.oracle.oBootMybatis01.model.Emp;
import com.oracle.oBootMybatis01.model.EmpDept;

public interface EmpDao {
	int totalEmp();
	List<Emp> 		listEmp(Emp emp);
	Emp 			detailEmp(int empno);
	int 			updateEmp(Emp emp);
	List<Emp> 		listManager();
	int 			insertEmp(Emp emp);
	int 			deleteEmp(int empno);
	int 			condTotalEmp(Emp emp);
	List<Emp> 		empSearchList3(Emp emp);
	List<EmpDept> 	listEmpDept();
	String 			deptName(int deptno);	
}
Console
 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.dao
class EmpDaoImpl
package com.oracle.oBootMybatis01.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

import com.oracle.oBootMybatis01.model.Emp;
import com.oracle.oBootMybatis01.model.EmpDept;

import lombok.RequiredArgsConstructor;

@Repository
//final 끌고 들어와준다.
@RequiredArgsConstructor

public class EmpDaoImpl implements EmpDao {
	//Mybatis DB 연동 (DI 작업)
	private final SqlSession session;

	@Override
	public int totalEmp() {
		int totEmpCount = 0;
		System.out.println("EmpDaoImpl Start totalEmp...");
		
		try {
			//.으로 이름 넣어주는 이유 : id가 많기 때문에!!
			//현재 logic을 통해 나온 totEmpCount는 COUNT(*)이다!
			totEmpCount = session.selectOne("com.oracle.oBootMyBatis01.EmpMapper.empTotal");
			System.out.println("EmpDaoImpl totalEmp totEmpCount-> "+totEmpCount);
		} catch (Exception e) {
			System.out.println("EmpDaoImpl totalEmp e.getMessage()->"+e.getMessage());
		}

		return totEmpCount;
	}

	@Override
	public List<Emp> listEmp(Emp emp) {
		List<Emp> empList = null;
		System.out.println("EmpDaoImpl listEmp Start...");
		try {
			//ID가 unique여야한다. (PK처럼 생각해야한다.)
			//								Map ID		parameter
			empList = session.selectList("tkEmpListAll", emp);
			System.out.println("EmpDaoImpl listEmp empList.size()-> "+empList.size());
		} catch (Exception e) {
			System.out.println("EmpDaoImpl listEmp e.getMessage()-> "+e.getMessage());
		}
		return empList;
	}

	@Override
	public Emp detailEmp(int empno) {
//		2. EmpDao   detailEmp method 선언 
////    mapper ID   ,    Parameter
		//emp = session.selectOne("tkEmpSelOne",    empno);
		//System.out.println("emp-> "+emp1);
		
		Emp emp = new Emp();
		System.out.println("EmpDaoImpl detailEmp Start...");
		try {
			emp = session.selectOne("tkEmpSelOne", empno);
			System.out.println("EmpDaoImpl detailEmp emp-> "+emp);
		} catch (Exception e) {
			System.out.println("EmpDaoImpl detailEmp e.getMessage()-> "+e.getMessage());
		}
		return emp;
	}

	@Override
	public int updateEmp(Emp emp) {
//   2. EmpDao updateEmp method 선언
									//	    mapper ID   ,    Parameter
			//updateCount = session.update("tkEmpUpdate",   emp);
		int updateCount = 0;
		try {
			updateCount = session.update("tkEmpUpdate", emp);
			System.out.println("EmpDaoImpl updateEmp updateCount-> "+updateCount);
		} catch (Exception e) {
			System.out.println("EmpDaoImpl updateEmp e.getMessage()-> "+e.getMessage());
		}
		return updateCount;
	}

	@Override
	public List<Emp> listManager() {
		List<Emp> empList = null;
		System.out.println("EmpDaoImpl listManager Start...");
		try {
			// emp 관리자만 select				Naming Rule
			empList = session.selectList("tkSelectManager");
			System.out.println("EmpDaoImpl listManager empList-> "+empList);
		} catch (Exception e) {
			System.out.println("EmpDaoImpl listManager e.getMessage()-> "+e.getMessage());
		}
		
		return empList;
	}

	@Override
	public int insertEmp(Emp emp) {
		int result = 0;
		System.out.println("EmpDaoImpl insertEmp Start...");
		try {
			result = session.insert("insertEmp", emp);
		} catch (Exception e) {
			System.out.println("EmpDaoImpl insertEmp e.getMessage()-> "+e.getMessage());
		}
		return result;
	}

	@Override
	public int deleteEmp(int empno) {
		int result = 0;
		System.out.println("EmpDaoImpl deleteEmp Start...");
		System.out.println("EmpDaoImpl deleteEmp empno-> "+empno);
		try {
			result = session.delete("deleteEmp", empno);
			result = session.delete("EmpDaoImpl deleteEmp result-> "+result);
		} catch (Exception e) {
			System.out.println("EmpDaoImpl deleteEmp e.getMessage()-> "+e.getMessage());
		}
		return result;
	}

	@Override
	public int condTotalEmp(Emp emp) {
		int totEmpCount = 0;
		System.out.println("EmpDaoImpl condTotalEmp Start...");
		try {
			totEmpCount = session.selectOne("condEmpTotal", emp);
			System.out.println("EmpDaoImpl condTotalEmp totEmpCount-> "+totEmpCount);
		} catch (Exception e) {
			System.out.println("EmpDaoImpl condTotalEmp e.getMessage()-> "+e.getMessage());
		}
		
		return totEmpCount;
	}

	@Override
	public List<Emp> empSearchList3(Emp emp) {
		List<Emp> empList = null;
		System.out.println("EmpDaoImpl empSearchList3 Start...");
		try {
			empList = session.selectList("tkEmpSearchList3", emp);
			System.out.println("EmpDaoImpl empSearchList3 empList-> "+empList);
		} catch (Exception e) {
			System.out.println("EmpDaoImpl empSearchList3 e.getMessage()-> "+e.getMessage());
		}
		return empList;
	}

	@Override
	public List<EmpDept> listEmpDept() {
		List<EmpDept> listEmpDept = null;
		System.out.println("EmpDaoImpl listEmpDept Start...");
		try {
			listEmpDept = session.selectList("tkListEmpDept");
			System.out.println("EmpDaoImpl listEmpDept listEmpDept size()-> "+listEmpDept.size());
		} catch (Exception e) {
			System.out.println("EmpDaoImpl listEmpDept e.getMessage()-> "+e.getMessage());
		}
		return listEmpDept;
	}


	@Override
	public String deptName(int deptno) {
		System.out.println("EmpDaoImpl deptName Start...");
		String resultStr = "";
		
		try {
			System.out.println("EmpDaoImpl deptName deptno-> "+deptno);
			resultStr = session.selectOne("tkDeptName", deptno);
			System.out.println("EmpDaoImpl deptName resultStr-> "+resultStr);
		} catch (Exception e) {
			System.out.println("EmpDaoImpl deptName Exception-> "+e.getMessage());
		}
		return resultStr;
	}

}
Console
 

 

 

 

 



Spring Starter Project oBootMybatis01
folder resources.mappers
xml EmpDept.xml
<?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="com.oracle.oBootMyBatis01.EmpDeptMapper">
	<select id="tkListEmpDept" resultType="EmpDept">
		SELECT e.empno, e.ename, e.job, e.deptno, d.loc
		FROM emp e, dept d
		WHERE e.deptno = d.deptno(+)
		ORDER BY empno
	</select>
	
	<select id="tkListEmpDept3" resultType="EmpDept">
		SELECT e.empno, e.ename, e.job, e.deptno, d.loc
		FROM emp e, dept d
		WHERE e.deptno = d.deptno
		ORDER BY empno
	</select>
	
	<select id="tkListEmpDept4" resultType="EmpDept">
		SELECT e.empno, e.ename, e.job, e.deptno, d.loc
		FROM emp e, dept d
		WHERE e.deptno(+) = d.deptno
		ORDER BY empno
	</select>
	
	<select id="tkDeptName" parameterType="int" resultType="java.lang.String">
		SELECT dname
		FROM dept
		WHERE deptno = #{deptno}
	</select>
	
</mapper>
Console
 

 

 - dept mapper 에 써도 되고 EmpDept에 써도 된다.

 

 

 

 

 

 

 

Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
JSP ajaxForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>다양한 Ajax Test</h1>
	<a href="/helloText">helloText</a><p>
	<a href="/sample/sendVO2?deptno=123">sample/sendVO2(객체)</a><p>
	<a href="/sendVO3">sendVO3</a><p>
	<a href="/getDeptName?deptno=10">getDeptName(EmpController)</a><p>
	<a href="/listEmpAjaxForm">listEmpAjaxForm(aJax JSP 연동)</a><p>
	<a href="/listEmpAjaxForm2">listEmpAjaxForm2(aJax JSP 객체리스트 Get)</a><p>
	<a href="/listEmpAjaxForm3">listEmpAjaxForm3(aJax List를 Controller로 전송)</a><p>
</body>
</html>
Console

 

 - ajax는 프로젝트에 무조건 써주어야 한다!!!!! 매우 중요

 

 



 

 

Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
JSP listEmpAjaxForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
	function getDeptName(pDeptno) {
		console.log(pDeptno);
		//alert("pDeptno-> "+pDeptno);
		// 행동강령 : Ajax로 부서번호 보내고 부서명 받음
		$.ajax(
				{
					url:"<%=request.getContextPath()%>/getDeptName",
					//parameter 명칭(반드시 DTO에 정의된 명칭): parameter 값
					//여러개의 값을 넘겨주기 위해서, {deptno : pDeptno, dname : pDname}
					data:{deptno : pDeptno},
					dataType:'text',
					// function에 들어가는 deptName의 dataType이라는 뜻 -> text
					success:function(deptName){
						//		명칭은 뭘 써도 상관 없지만, 아래에 일관되게 같은 parameter 명이어야 한다.
						//alert("success ajax Data-> "+deptName);
						$('#deptName').val(deptName);	/* input Tag */
						$('#msg').html(deptName);		/* span id Tag */
					}
				}
		);
	}
	
	function getDept(pDeptno) {
		alert("pDeptno-> "+pDeptno);
		// sample/sendVO2
		// id : RestDept 결과 값 넣어주기
		
		$.ajax(
				{
					 url:"sample/sendVO2",
					 data:{deptno : pDeptno},
					 dataType:'json',
					 success:function(sampleVo){
						 //json은 객체명.dto명 -> 값을 불러와준다.
						 resultStr = sampleVo.firstName + " " + sampleVo.lastName + " " + sampleVo.mno;
						 alert("ajax getDept resultStr-> "+resultStr);
						 $('#RestDept').val(resultStr);		// input tag
					 }
				}
		);
	}
	
	function empWriteBtn() {
		var empno = $('#empno').val();
		
		//var sendData = JSON.stringify($('#empTrans').serialize());
		//alert('sendData-->'+sendData);
		
		//	 empTrans id를 전부 serializeArray로 배열값으로 넣어주겠다는 의미
		var sendData = $('#empTrans').serializeArray();
		
		//		JSON Data Conversion
		//sendData3가 아래 jsonParse에서 받아온 obj (객체로 넘어온 값)
		sendData3 = jsonParse(sendData);
		alert('sendData3-->'+sendData3);
		console.log('sendData3-->'+sendData3);
		
 		$.ajax({
			url: 'empSerializeWrite',
			type: 'POST',
			contentType: 'application/json;charset=UTF-8',
			//sendData3를 json 형태의 string data로 만들어서 보내주겠다는 의미
			//이렇게 되면, 상대방은 parsing만 해주면 data를 편하게 쓸 수 있다.
			data: JSON.stringify(sendData3),
			dataType:'json',
			success: function(response) {
				if(response.writeResult > 0) {
					alert("성공");
				}
			}
		}); 
	}
	
	function jsonParse(sendData2) {
		obj = {};
		if (sendData2) {
			
			jQuery.each(sendData2, function() {
				//name과 value를 obj 객체로 setting을 해준 후
				obj[this.name] = this.value;
				alert('this.name->' + this.name, ', this.value->' + this.value);
			});
		}
			return obj;
	}
</script>
</head>
<body>
	<h2>회원 정보</h2>
	<table>
		<tr>
			<th>사번</th>
			<th>이름</th>
			<th>업무</th>
			<th>부서</th>
			<th>근무지</th>
		</tr>
		<c:forEach var="emp" items="${listEmp}">
			<tr>
				<td>${emp.empno }</td>
				<td>${emp.ename }</td>
				<td>${emp.job }</td>
				<td>${emp.deptno} 
				    <input type="button" id="btn_idCheck" value="부서명" onmouseover="getDeptName(${emp.deptno })">
				</td>
				<td>${empDept.loc }</td>
			</tr>
		</c:forEach>
	</table><p>

	deptName:  <input type="text" id="deptName"  readonly="readonly"><p>
    Message :  <span id="msg"></span><p>
    
    RestController sendVO2: <input type="text" id="RestDept"    readonly="readonly"><p>
	RestController sendVO2: sendVO2<input type="button" id="btn_Dept"  value="부서명"  
	                                      onclick="getDept(10)"><p>
	                                      
	<h2>Serialize Test</h2>
    <form  name="empTrans"   id="empTrans">
    		<input type="hidden"  id="empno"  name="empno"    value="1234">
    		<input type="hidden"  id="ename"  name="ename"    value="시리얼">
    		<input type="hidden"  id="sal"    name="sal"      value="1000">
        <input type="button"  value="Ajax Serialize 확인" onclick="empWriteBtn()">
     </form>
</body>
</html>
Console

 파란색 부서명을 클릭하면 

 

 - jQuery가 선언되어 있으면 $.ajax를 쓸 수 있다.

 

    무수히 많은 경로와 view가 생기기 때문에, 서버에서 getDeptName을 못가져올 수도 있기 때문에,

     getDeptName을 가져오기 위해서!!

 

 - jQuery와 ajax는 한 몸

 

 - 아래 ajax를 실행하면, controller에서 실행이 된다.

EmpRestController.java 실행

 

 

 

 

 - 우선 ajax 부르기 전에 통째로 serialize 하면 어떻게 되는지

   실행하게 되면,

 

 

 - 파싱을 해주고 나면, 값이 정리되어서 나오게 된다.

 

 

 

 - @RequestBody 없으면, 안된다.

   Json 형태로 받게 되면, @RequestBody로 그대로 옮겨주어야 한다.

 

 

'Spring' 카테고리의 다른 글

Day63 2024.08.21.수 #코딩일기  (0) 2024.08.21
Day62 2024.08.20.화 #코딩일기  (0) 2024.08.20
Day60 2024.08.14.수 #코딩일기  (0) 2024.08.14
Day59 2024.08.13.화 #코딩일기  (0) 2024.08.13
Day58 2024.08.12.월 #코딩일기  (0) 2024.08.12