AOP vs Interceptor
InterCeptor에서 prehandle 역할 vs AOP @Before 역할
InterCeptor에서 posthandle 역할 vs AOP @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 와 다르게 메소드 단위 조인포인트만 제공 |
(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에 넣어주기
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 역할
- @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 뒤에 이름이 맞는지 확인해주고, 시작하기
- 자동완성으로 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 를 활용하면 된다.
controller 로직을 보게 되면, vo가 return 되는데, 객체가 return 되어서HttpMessageConverter가
JsonConverter를 불러서 작동된다.
- https://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에서 실행이 된다.
- 우선 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 |