본문 바로가기
Spring

oBootMyBatis

by SSONG1521 2024. 9. 12.

 



Spring Starter Project oBootMybatis01
package resources
yml application.yml
server:
  port: 8388
# 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 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
 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.configuration
class SecurityConfig
package com.oracle.oBootMybatis01.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {
	
	//암호화 코드를 사용할 수 있는 Bean
	//이 암호와 logic 만 쓰기 위해서
	@Bean
	public BCryptPasswordEncoder encodePwd() {
		return new BCryptPasswordEncoder();
	}
	
	//얘를 써주는데, 대신 권한을 모두에게 준다.
	//update logic 시작 때 !!! 주석처리해준다.
//	@Bean
//	protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
//		http.authorizeHttpRequests()
//			.anyRequest()
//			.permitAll();
//		return http.build();
//	}
	
	@Bean
	protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
		.cors(cors-> cors.disable())
		.csrf(csrf-> csrf.disable());
		
		return http.build();
	}
}
Console
 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.configuration
class WebMvcConfiguration
package com.oracle.oBootMybatis01.configuration;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.oracle.oBootMybatis01.service.SampleInterceptor;

@Configuration

public class WebMvcConfiguration implements WebMvcConfigurer {
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		//누군가 URL / interCeptor --> SampleInterceptor() 처리해줌
		//service에 있는 SampleInterceptor
		registry.addInterceptor(new SampleInterceptor()).addPathPatterns("/interCeptor");
		//							/interCeptor가 나오면 	SampleInterceptor가 가로채기				
	}

}
Console
 

 

 

 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.configuration
class WebSocketConfig
package com.oracle.oBootMybatis01.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

import com.oracle.oBootMybatis01.handler.SocketHandler;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
	
	//소켓에서 서버역할 하는!!
	// socket 서버 -> controller랑 비슷한 역할을 하는!! (controller는 아니다!!!)
	@Autowired
	SocketHandler socketHandler;
	
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
		// 누군가 URL '/chating' 치면 --> socketHandler 발동
		//socket 세상에서는 얘가  controller 같은 역할을 해준다.
		registry.addHandler(socketHandler, "/chating");

	}

}
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;
	
	//처음 시작화면에서 list로 들어가는 것
	@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")
			//		string으로 받아온 것을 json형태로 날라와도 @RequestBody가 있으면 알아서 key, value로 넘어가진다.
	public Map<String, Object> empSerializeWrite(@RequestBody @Valid Emp emp) {
		//map 방식으로 주는 이유: 상대방이 받을 때 string 방식으로 받는 것 보다 객체 방식으로 받는게 더 편해서
//	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);
		// writeResult가 1이나 0이 왔다는 전제 하에 to string으로 
		// String followingProStr = Integer.toString(followingPro);
		
		Map<String, Object> resultMap = new HashMap<>();
		System.out.println("EmpController empSerializeWrite writeResult-> "+writeResult);
		
		//객체로 만들어준 것 (하나 이상의 값을 보내줄 수 있다)
		//map방식이면, 요구사항을 받아서 바로 해결할 수 있다.
		resultMap.put("writeResult", writeResult);
//		resultMap.put("anyResult", "anyR");
		return resultMap;
	}
	
	@RequestMapping(value = "listEmpAjaxForm2")
	public String listEmpAjaxForm2(Model model) {
		System.out.println("EmpController listEmpAjaxForm2 Start...");
		Emp emp = new Emp();
		// Parameter emp --> Page만 추가 setting
		emp.setStart(1);	//시작 시 1
		emp.setEnd(15);		//시작 시 15
		List<Emp> listEmp = es.listEmp(emp);
		System.out.println("EmpController listEmpAjaxForm2 listEmp.size()"+ listEmp.size());
		
		model.addAttribute("listEmp", listEmp);
		
		return "listEmpAjaxForm2";
	}
	
	@RequestMapping(value = "listEmpAjaxForm3")
	public String listEmpAjaxForm3(Model model) {
		System.out.println("EmpController listEmpAjaxForm3 Start...");
		Emp emp = new Emp();
		// Parameter emp --> Page만 추가 setting
		emp.setStart(1);	//시작 시 1
		emp.setEnd(15);		//시작 시 15
		List<Emp> listEmp = es.listEmp(emp);
		System.out.println("EmpController listEmpAjaxForm3 listEmp.size()"+ listEmp.size());
		
		model.addAttribute("listEmp", listEmp);
		
		return "listEmpAjaxForm3";
	}
	
	@ResponseBody
	@RequestMapping(value = "empListUpdate")
	public Map<String, Object> empListUpdate(@RequestBody @Valid List<Emp> listEmp) {
		System.out.println("EmpController empListUpdate Start...");
		int updateResult = 1;
		
		for (Emp emp : listEmp) {
			System.out.println("EmpController empListUpdate  emp-> "+emp);
			//int writeResult = kkk.listUpdateEmp(emp);
		}
		
		Map<String, Object> resultMap = new HashMap<>();
		
		resultMap.put("updateResult", updateResult);
		return resultMap;
	}
	
	@ResponseBody
	@RequestMapping(value = "transactionInsertUpdate")
	public String transactionInsertUpdate(Emp emp, Model model) {
		System.out.println("EmpController transactionInsertUpdate Start....");
		
		//memberInsert 성공과 실패
		int returnMember = es.transactionInsertUpdate();
		System.out.println("EmpController transactionInsertUpdate returnMember=> "+returnMember);
		String returnMemberString = String.valueOf(returnMember);
		
		return returnMemberString;
	}
	
}
Console
 

 

 

 

 

 

 

 



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

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

import org.springframework.ui.Model;
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.Emp;
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;
	}
	
	//결과 text로 보내지는 것
	@RequestMapping("/empnoDelete")
	public String empnoDelete(Emp emp) {
		System.out.println("EmpRestController @RestController empnoDelete START..");
		System.out.println("EmpRestController @RestController empnoDelete emp-> "+emp);
		int delStatus = es.deleteEmp(emp.getEmpno());
		String delStatusStr = Integer.toString(delStatus);
		return delStatusStr;
	}
	
	//결과 --> 객체로 전달 (객체는 DTO로 or Map으로!)
	@RequestMapping("/empnoDelete03")
	public Map<String, Object> empnoDelete03(Emp emp) {
		System.out.println("EmpRestController @RestController empnoDelete03 START..");
		System.out.println("EmpRestController @RestController empnoDelete03 emp-> "+emp);
		int delStatus = es.deleteEmp(emp.getEmpno());
//		String delStatusStr = Integer.toString(delStatus);
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("delStatus", delStatus);
		return resultMap;
	}
}
Console
 

 

 

 




Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.controller
class MemberJpaController
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
 

 

 

 




Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.controller
class SocketController
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
 

 

 

 




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
 

 

 

 




Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.dao
Interface DeptDao
package com.oracle.oBootMybatis01.dao;

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

import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.DeptVO;

public interface DeptDao {
	List<Dept> 	deptSelect();
	void 		insertDept(DeptVO deptVO);
	void 		selListDept(HashMap<String, Object> map);
}
Console
 

 

 

 

 



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

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

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

import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.DeptVO;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class DeptDaoImpl implements DeptDao {
	//Mybatis DB 연동
	private final SqlSession session;
	
	@Override
	public List<Dept> deptSelect() {
		List<Dept> deptList = null;
		System.out.println("DeptDaoImpl deptSelect Start...");
		
		try {
			deptList = session.selectList("tkSelectDept");
		} catch (Exception e) {
			System.out.println("DeptDaoImpl deptSelect e.getMessage()-> "+e.getMessage());
		}
		return deptList;
	}

	@Override
	public void insertDept(DeptVO deptVO) {
		System.out.println("DeptDaoImpl insertDept Start....");
		session.selectOne("procDeptInsert", deptVO);
		
	}

	@Override
	public void selListDept(HashMap<String, Object> map) {
		System.out.println("DeptDaoImpl selListDept Start....");
//		ResultMap은 DB 컬럼명과 DTO의 변수 명이 다를 때 사용
		session.selectOne("procDeptList", map);
		
	}

}
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
package com.oracle.oBootMybatis01.dao
Interface Member1Dao
package com.oracle.oBootMybatis01.dao;

import java.util.List;

import com.oracle.oBootMybatis01.model.Member1;

public interface Member1Dao {
	int 			memCount(String id);	//Member1의 count

	List<Member1> 	listMem(Member1 member1);
	int 			transactionInsertUpdate();
	int 			transactionInsertUpdate3();
}
Console
 

 

 



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

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.oracle.oBootMybatis01.model.Member1;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class Member1DaoImpl implements Member1Dao {
	
	private final PlatformTransactionManager transactionManager;
	
	//My Batis 연동
	public final SqlSession session;
	
	@Override
	public int memCount(String id) {
		// Mapper --> Member1.xml
		// result = session.selectOne("memCount", id);
		System.out.println("Member1DaoImpl memCount start.....");
		int result = 0;
		try {
			result = session.selectOne("memCount", id);
			System.out.println("Member1DaoImpl memCount memCount(result)-> "+result);
		} catch (Exception e) {
			System.out.println("Member1DaoImpl memCount e.getMessage()-> "+e.getMessage());
		}
		return result;
	}

	@Override
	public List<Member1> listMem(Member1 member1) {
		List<Member1> listMem = null;
		System.out.println("Member1DaoImpl listMem start.....");
		
		try {
			listMem = session.selectList("listMember1",member1);
			System.out.println("Member1DaoImpl listMem member-> "+member1);
		} catch (Exception e) {
			System.out.println("Member1DaoImpl listMem e.getMessage()-> "+e.getMessage());
		}
		return listMem;
	}
	
	//둘 중 오류난 하나만 값이 안들어가짐
	@Override
	public int transactionInsertUpdate() {
		int result = 0;
		System.out.println("Member1DaoImpl transactionInsertUpdate Start...");
		Member1 member1 = new Member1();
		Member1 member2 = new Member1();
		
		try {
			//두 개의 transaction Test 성공과 실패
			// 결론 --> SqlSession 은 하나 실행할 때마다 자동 Commit
			member1.setId("1005");
			member1.setPassword("2345");
			member1.setName("강유6");
			
			result = session.insert("insertMember1", member1);
			System.out.println("Member1DaoImpl transactionInsertUpdate member1 result-> "+result);
			
			//같은 PK로 실패 유도
			member2.setId("1005");
			member2.setPassword("3457");
			member2.setName("이순신7");
			result = session.insert("insertMember1", member2);
			System.out.println("Member1DaoImpl transactionInsertUpdate member2 result-> "+result);
		} catch (Exception e) {
			System.out.println("Member1DaoImpl transactionInsertUpdate Exception -> "+e.getMessage());
			result = -1;
		}
		return result;
	}
	
	//하나의 method 안에 하나라도 안넣어지면 둘 다 안들어가짐 
	//(이렇게 해야한다. 하나는 들어가고 하나는 안들아가고가 아니라)
	@Override
	public int transactionInsertUpdate3() {
		int result = 0;
		System.out.println("Member1DaoImpl transactionInsertUpdate3 Start...");
		Member1 member1 = new Member1();
		Member1 member2 = new Member1();
		
		TransactionStatus txStatus = 
				transactionManager.getTransaction(new DefaultTransactionDefinition());
		
		try {
			//두 개의 transaction Test 성공과 실패
			// 결론 --> SqlSession 은 하나 실행할 때마다 자동 Commit
			//Transaction관리는 transactionManager의 getTransaction을 가지고 상태따라 설정
			member1.setId("1007");
			member1.setPassword("2345");
			member1.setName("강유6");
			
			result = session.insert("insertMember1", member1);
			System.out.println("Member1DaoImpl transactionInsertUpdate3 member1 result-> "+result);
			
			//같은 PK로 실패 유도
			member2.setId("1008");
			member2.setPassword("3457");
			member2.setName("이순신7");
			result = session.insert("insertMember1", member2);
			System.out.println("Member1DaoImpl transactionInsertUpdate3 member2 result-> "+result);
			transactionManager.commit(txStatus);
		} catch (Exception e) {
			transactionManager.rollback(txStatus);
			System.out.println("Member1DaoImpl transactionInsertUpdate3 Exception -> "+e.getMessage());
			result = -1;
		}
		return result;
	}

}
Console
 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.domain
class Member
package com.oracle.oBootMybatis01.domain;

import java.util.Date;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Entity
@Table(name = "member3")
@Getter
@Setter
@ToString
public class Member {
	@Id
	private Long 	id;
	private String 	name;
	private String 	password;
	@Column(nullable = false, columnDefinition = "date default sysdate")
	private Date 	reg_date = new Date();
}
Console
 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.handler
class SocketHandler
package com.oracle.oBootMybatis01.handler;

import java.util.HashMap;
import java.util.Iterator;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

//bean 으로 설정되어야 해서
@Component
public class SocketHandler extends TextWebSocketHandler {

	// 웹소켓 세션을 담아둘 맵 (연결될 session을 객체로 id별로 저장해두기 위한 것)
	HashMap<String, WebSocketSession> sessionMap = new HashMap<>();
	// 세션 ID--> 4fc5822c-9b80-6461-668e-5b686311d41b , Instance session1(황보)
	// 세션 ID--> 4f8144d5-8b89-ef38-e725-bf45383d356a , Instance session1(미숙)
	// 세션 ID--> 3ac9695f-2f63-5bbe-c5ee-d4fe80c33158 , Instance session1(지만)
	// 세션 ID--> 907578d7-a1e0-a074-faf4-9e47cc895a49 , Instance session1(쭈리)
	// 세션 ID--> a154971d-7049-f14e-3c53-29811dd85d4f , Instance session1(혜선)
	
	// 웹소켓 세션 ID과 Member을 담아둘 맵
	HashMap<String, String> sessionUserMap = new HashMap<>();
	// 세션 ID --> 4fc5822c-9b80-6461-668e-5b686311d41b , 황보
	// 세션 ID--> 4f8144d5-8b89-ef38-e725-bf45383d356a , 미숙
	// 세션 ID--> 3ac9695f-2f63-5bbe-c5ee-d4fe80c33158 , 지만
	// 세션 ID--> 907578d7-a1e0-a074-faf4-9e47cc895a49 , 쭈리
	// 세션 ID--> a154971d-7049-f14e-3c53-29811dd85d4f , 혜선
	
	// 웹소켓 세션 ID과 Member을 담아둘 JSONObject
	JSONObject jsonUser = null;
	
	
	// 2. handleTextMessage 메소드는 메시지를 수신하면 실행
	//메세지 보낼 때
	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		//super.handleTextMessage(session, message);
		
		// Message 수신
		String msg = message.getPayload();
		System.out.println("SocketHandler handleTextMessage msg-> "+msg);
		
		//string으로 받은 것을 json 형태로 파싱해주는 것!! (@RequestBody와 비슷한 역할)
		JSONObject jsonObj = jsonToObjectParser(msg);
		// type을 Get하여 분기 
		String msgType = (String) jsonObj.get("type");
		System.out.println("SocketHandler handleTextMessage  msgType-> "+msgType);

		
		switch (msgType) {
		     // 전체 Message 
	        case "message":  
	        	jsonUser = new JSONObject(sessionUserMap);
	            System.out.printf( "JSONUser: %s", jsonUser);
	    		// 전송대상을 기준으로  분기 
	    		String yourName = (String) jsonObj.get("yourName");
	    		System.out.println("SocketHandler handleTextMessage  yourName->"+yourName);
	    		
	    		// 전체
	    		if (yourName.equals("ALL")) {
			     	for(String key : sessionMap.keySet()) {
							WebSocketSession wss = sessionMap.get(key);
							try {
								System.out.println("message key->"+key);
								System.out.println("message wss->"+wss);
								wss.sendMessage(new TextMessage(jsonObj.toJSONString()));
							}catch(Exception e) {
								e.printStackTrace();
							}
					}
	    			
	    		} else {  
	    			// 개인 전송 대상자(yourName은 개인 sessionID)
	    			
	    			// 상대방
		    		System.out.println("개인 전송 대상자 상대방 sessionID-->"+yourName);
		    		// 상대방의 websocket
					WebSocketSession wss1 = sessionMap.get(yourName);
					try {
						wss1.sendMessage(new TextMessage(jsonObj.toJSONString()));
					}catch(Exception e) {
						e.printStackTrace();
					}
					
		    		// 나에게도 보내줘
		    		String meName = (String) jsonObj.get("sessionId");
		    		WebSocketSession wss2 = sessionMap.get(meName);
		    		System.out.println("개인 전송 대상자 나-->"+ meName);
					try {
						wss2.sendMessage(new TextMessage(jsonObj.toJSONString()));
					} catch(Exception e) {
						e.printStackTrace();
					}
	    			
	    		}
	            break;
		
	        // sessionUserMap에 User등록 
	        case "userSave":
	            // sessionUserMap에 sessionId와  userName 등록  
	     	    String sessionId   = (String) jsonObj.get("sessionId");
	     	    String userName    = (String) jsonObj.get("userName");
	     	    String saveStatus  = (String) jsonObj.get("saveStatus");
	     	    
	     	    //    신규   등록 
	     	    if (saveStatus.equals("Create")) {
		     	    sessionUserMap.put(sessionId, userName);
		     	    System.out.println("=================================================");
		     	    System.out.println("== sessionUserMap 저장내용 조회하여 arrayJsonUser에 ==");
		     	    System.out.println("==  각각의 JSONObject jsonUser로  변환            ==");
		     	    System.out.println("== 1. type : userSave                          ==");
		     	    System.out.println("== 2. sessionId : sessionUserMap.sessionId     ==");
		     	    System.out.println("== 3. userName  : sessionUserMap.userName      ==");
		     	    System.out.println("=================================================");
	     	    	
	     	    } else {   
	     	    	// Delete
		        	System.out.println("handleTextMessage userDelete start.. ");
		        	System.out.println("handleTextMessage userDelete session.getId()->"+session.getId());
		     		// 웹소켓 종료
		     		sessionMap.remove(session.getId());
		     		// sessionUserMap 종료
		     		sessionUserMap.remove(session.getId());
		           // break;
	     	    }
	     	    
	     	    JSONArray arrayJsonUser = new JSONArray();
	     	    System.out.println("== 1. type : userSave                         ==");
	     	    Iterator<String> mapIter = sessionUserMap.keySet().iterator();
	     	    System.out.println("== 2. sessionId : sessionUserMap.sessionId    ==");
	     	    System.out.println("== 3. userName  : sessionUserMap.userName     ==");
		     	while(mapIter.hasNext()){
	     	       String key = mapIter.next();
	     	       //우선 sessionMap에 넣어두고, 후에 json으로 보내준다.
	     	       String value = sessionUserMap.get( key );
	     	       System.out.println("Key : Value -->"+key+" : "+value);
		     	   jsonUser =  new JSONObject();
		     	   jsonUser.put("type", "userSave");
		     	   jsonUser.put("sessionId",key);
		     	   jsonUser.put("userName",value);
		     	   arrayJsonUser.add(jsonUser);
	     	    }
	     	    System.out.println("====== session을 Get하여 User 내용 전송 ========");
	            System.out.printf( "arrayJsonUser: %s", arrayJsonUser);
	           
	            // 전체에 User등록을 하게 함
		     	for(String key : sessionMap.keySet()) {
						WebSocketSession wss = sessionMap.get(key);
						try {
							// 2사람 이상일 때 combobox를 만들어주기 위해서
							wss.sendMessage(new TextMessage(arrayJsonUser.toJSONString()));
						}catch(Exception e) {
							e.printStackTrace();
						}
				}
		        break;
		        
	        case "userDelete":  
	        	System.out.println("handleTextMessage userDelete start.. ");
	        	System.out.println("handleTextMessage userDelete session.getId()->"+session.getId());
	     		// 웹소켓 종료
	     		sessionMap.remove(session.getId());
	     		// sessionUserMap 종료
	     		sessionUserMap.remove(session.getId());
	            break;
		}
		
	}

	//  @SuppressWarning
	//  이건 컴파일러가 일반적으로 경고하는 내용 중	"이건 하지마" 하고 제외시킬 때 쓰임
	//	따라서 어떤 경고를 제외시킬지 옵션
	//	1. all : 모든 경고를 억제
	//	2. cast : 캐스트 연산자 관련 경고 억제
	//	3. dep-ann : 사용하지 말아야 할 주석 관련 경고 억제
	//	4. deprecation : 사용하지 말아야 할 메소드 관련 경고 억제
	//	5. fallthrough : switch문에서의 break 누락 관련 경고 억제
	//	6. finally : 반환하지 않는 finally 블럭 관련 경고 억제
	//	7. null : null 분석 관련 경고 억제
	//	8. rawtypes : 제네릭을 사용하는 클래스 매개 변수가 불특정일 때의 경고 억제
	//	9. unchecked : 검증되지 않은 연산자 관련 경고 억제
	//	10. unused : 사용하지 않는 코드 관련 경고 억제

	@SuppressWarnings("unchecked")
	// 1. 웹소켓 연결이 되면 동작
	//연결할 때
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("SocketHandler afterConnectionEstablished start...");
		// 웹소켓  연결이 되면 동작
		super.afterConnectionEstablished(session);
		// 연결 소겟을 MAP에 등록 
		sessionMap.put(session.getId(), session);

		JSONObject jsonObject = new JSONObject();
		// 대상 : Client
		jsonObject.put("type", "getId");
		jsonObject.put("sessionId", session.getId());
		System.out.println("SocketHandler afterConnectionEstablished jsonObject.toJSONString()-> "
		                    +jsonObject.toJSONString());
		
		//  session Server 등록 -->  Socket Server가 Client에게 전송 
		session.sendMessage(new TextMessage(jsonObject.toJSONString()));

	}
	
	// 3.웹소켓이 종료되면 동작
	//연결을 끊을 때 쓰는 method
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		System.out.println("SocketHandler afterConnectionClosed start...");
		// 웹소켓 종료
		sessionMap.remove(session.getId());
		super.afterConnectionClosed(session, status);

	}
	
	//내부적으로 사용되는 parsing 하는 method
	// handleTextMessage 메소드 에 JSON파일이 들어오면 파싱해주는 함수를 추가
	private static JSONObject jsonToObjectParser(String jsonStr) {
		JSONParser parser = new JSONParser();
		JSONObject jsonObj = null;
		try {
			jsonObj = (JSONObject) parser.parse(jsonStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return jsonObj;
	}	
	
}
Console
 

 

 

 



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

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Dept {
	private int deptno;
	private String dname;
	private String loc;
}
Console
 

 

 

 

 

 

 



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

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class DeptVO {
	//입력
	private int 	deptno;
	private String 	dname;
	private String 	loc;
	
	//출력
	private int 	odeptno;
	private String 	odname;
	private String 	oloc;
}
Console
 

 

 

 

 

 

 



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

import jakarta.validation.constraints.NotEmpty;
import lombok.Data;

@Data
public class Emp {
	//TBL 용
	private int empno;
	@NotEmpty(message = "이름은 필수 입니다 흑유흑유")
	private String ename;
	private String job;
	private int mgr;
	private String hiredate;
	private int sal;
	private int comm;
	private int deptno;
	
	//조회용
	private String search;
	private String keyword;	
	private String pageNum;
	private int start;
	private int end;
	
	//Page 정보
	private String currentPage;
}
Console
 

 

 

 

 

 

 



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

import lombok.Data;

@Data
public class EmpDept {
	//두 TBL이 많다는 전제하에  Join 목적으로 만든 DTO
	
	//EMP용
	private int empno;
	private String ename;
	private String job;
	private int mgr;
	private String hiredate;
	private int sal;
	private int comm;
	private int deptno;
	
	//Dept 용 (많다는 가정 하에)
	private String dname;
	private String loc;
}
Console
 

 

 

 

 

 

 



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

import java.util.Date;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Member1 {
	private String id;
	private String name;
	private String password;
	private Date reg_date;
}
Console
 

 

 

 

 

 

 



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.repository
Interface MemberJpaRepository
package com.oracle.oBootMybatis01.repository;

import java.util.List;
import java.util.Optional;

import com.oracle.oBootMybatis01.domain.Member;

public interface MemberJpaRepository {
	Member 				save(Member member);
	List<Member> 		findAll();
	Optional<Member> 	findById(Long memberId);
	void 				updateByMember(Member member);
}
Console
 

 

 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.repository
class MemberJpaRepositoryImpl
package com.oracle.oBootMybatis01.repository;

import java.util.List;
import java.util.Optional;

import org.springframework.stereotype.Repository;

import com.oracle.oBootMybatis01.domain.Member;

import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class MemberJpaRepositoryImpl implements MemberJpaRepository {
	
	private final EntityManager em;

	@Override
	public Member save(Member member) {
		System.out.println("MemberJpaRepositoryImpl save start...");
		em.persist(member);
		return member;
	}

	@Override
	public List<Member> findAll() {
		System.out.println("MemberJpaRepositoryImpl findAll start...");
		List<Member> memberList = null;
		memberList = em.createQuery("SELECT m FROM Member m",Member.class).getResultList();
		System.out.println("MemberJpaRepositoryImpl findAll memberList.size()-> "+memberList.size());
		return memberList;
	}
	

	@Override
	public Optional<Member> findById(Long memberId) {
		System.out.println("MemberJpaRepositoryImpl findById start...");
		Member member = em.find(Member.class, memberId);
		return Optional.ofNullable(member);
	}

	@Override
	public void updateByMember(Member member) {
		//1. update
		//merge --> 현재 setting 된것만 수정, 나머지는 null로 setting
		System.out.println("MemberJpaRepositoryImpl updateByMember update1 start...");
		em.merge(member);
		
		//2. update
//		System.out.println("MemberJpaRepositoryImpl updateByMember update2 start...");
//		Member member3 = em.find(Member.class, member.getId());
//		if (member3 != null) {
//			//회원저장
//			member3.setId(member.getId());
//			member3.setName(member.getName());
//			System.out.println("MemberJpaRepositoryImpl updateByMember Update...");
//		} else {
//			System.out.println("MemberJpaRepositoryImpl updateByMember No Exist..");
//		}
		System.out.println("MemberJpaRepositoryImpl updateByMember after...");
	}

}
Console
 

 

 

 

 

 



Spring Starter Project oBootMybatis01
package com.oracle.oBootMybatis01.service
Interface 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);
	int 			transactionInsertUpdate();
	
}
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;
	}

	@Override
	public int transactionInsertUpdate() {
		System.out.println("EmpServiceImpl transactionInsertUpdate Start...");
//		return md.transactionInsertUpdate();		//transaction X
		return md.transactionInsertUpdate3();		//transaction OK
	}

}
Console
 

 

 

 

 





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

import java.util.List;
import java.util.Optional;

import org.springframework.stereotype.Service;

import com.oracle.oBootMybatis01.domain.Member;
import com.oracle.oBootMybatis01.repository.MemberJpaRepository;

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
@Transactional
public class MemberJpaService {
	private final MemberJpaRepository memberJpaRepository;

	public void join(Member member) {
		System.out.println("MemberJpaService join start...");
		System.out.println("MemberJpaService join member-> "+member);
		memberJpaRepository.save(member);
		
	}

	public List<Member> getListAllMember() {
		System.out.println("MemberJpaService getListAllMember start...");
		List<Member> listMember = null;
		listMember = memberJpaRepository.findAll();
		return listMember;
	}

	public Optional<Member> findById(Long memberId) {
		System.out.println("MemberJpaService findById Start....");
		//controller에서 optional로 보내주었기 때문에 똑같이 선언해주어야 한다.
		Optional<Member> member = memberJpaRepository.findById(memberId);
		return member;
	}

	public void memberUpdate(Member member) {
		System.out.println("MemberJpaService memberUpdate Start....");
		memberJpaRepository.updateByMember(member);
		System.out.println("MemberJpaService memberUpdate after....");
		
	}
	
}
Console
 

 

 

 

 





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

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Paging {
	private int currentPage = 1;
	private int rowPage = 10;
	private int pageBlock = 10;
	private int start;
	private int end;
	private int startPage;
	private int endPage;
	private int total;
	private int totalPage;
	
	public Paging(int total, String currentPage1) {
		this.total = total;
		if (currentPage1 != null) {
			this.currentPage = Integer.parseInt(currentPage1);	//2
		}			
		//			1				10
		start = (currentPage-1) * rowPage + 1; //시작 시 1		11
		end = start + rowPage -1;					//시작 시 10 		20
//											21			10
		totalPage = (int) Math.ceil((double)total / rowPage);	//시작 시 3 (ceil 올림)
//						1				1											
		startPage = currentPage - (currentPage-1) % pageBlock;	//시작 시 1
		endPage = startPage + pageBlock -1;	//10
		
//				10		14
		if (endPage> totalPage) {
			endPage = totalPage;
		}
	}
	
}
Console
 

 

 

 

 





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

import java.lang.reflect.Method;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class SampleInterceptor implements HandlerInterceptor {
	public SampleInterceptor() {
		// TODO Auto-generated constructor stub
	}
	
	//3번
	@Override
	public void postHandle(HttpServletRequest request, 
						   HttpServletResponse response, 
						   Object handler,
						   ModelAndView modelAndView) throws Exception {
		
		System.out.println("post handler.....................");
		//model만 꺼낼 수 있고, 그 안에서 id만 꺼낼 수 있다.
		String ID = (String) modelAndView.getModel().get("id");
		//model만 꺼낼 수 있고, 그 안에서 memCnt만 꺼낼 수 있다.
		int memCnt = (Integer) modelAndView.getModel().get("memCnt");
		System.out.println("SampleInterceptor post handle memCnt: "+memCnt);
		
		if (memCnt < 1) {
			System.out.println("memCnt Not exists");
			request.getSession().setAttribute("ID", ID);
			//User가 존재하지 않으면 User interCeptor Page(회원등록) 이동
			response.sendRedirect("doMemberWrite");
		} else {	//정상 Login User
			System.out.println("memCnt exists");
			request.getSession().setAttribute("ID", ID);
			//User가 존재하면, User interCeptor Page( 회원List) 이동
			//여기가 진짜로 이동할 페이지
			response.sendRedirect("doMemberList");
		}
		
	}
	
	//1번
	@Override
	public boolean preHandle(HttpServletRequest request, 
							 HttpServletResponse response, 
							 Object handler) throws Exception {
		System.out.println("pre handle.........................");
		HandlerMethod method = (HandlerMethod) handler;
		Method methodObj = method.getMethod();
		System.out.println("Bean: "+method.getBean());
		System.out.println("Method: "+methodObj);
		return true;
	}
	
	

}
Console
 

 

 

 



Spring Starter Project oBootMybatis01
package resources/static
xml configuration.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
	<typeAliases>
												<!-- model 에 있는 Emp class에서 복사해옴 -->
		<typeAlias alias="Emp" type="com.oracle.oBootMybatis01.model.Emp"/>
		<typeAlias alias="Dept" type="com.oracle.oBootMybatis01.model.Dept"/>	
		<typeAlias alias="EmpDept" type="com.oracle.oBootMybatis01.model.EmpDept"/>	
		<typeAlias alias="DeptVO" type="com.oracle.oBootMybatis01.model.DeptVO"/>	
		<typeAlias alias="Member1" type="com.oracle.oBootMybatis01.model.Member1"/>	
	</typeAliases>
</configuration>
Console
 

 

 





Spring Starter Project oBootMybatis01
package resources/mappers
xml Dept.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.DeptMapper">

	<resultMap type="Dept" id="DeptResult">
		<result property="deptno" 	column="deptno"/>
		<result property="dname" 	column="dname"/>
		<result property="loc" 		column="loc"/>
	</resultMap>

	<!-- deptSelect -->
	<select id="tkSelectDept" resultType="Dept">
		SELECT *
		FROM dept
	</select>
	
	
	<select id="procDeptInsert" parameterType="DeptVO" statementType="CALLABLE">
		{
			call Dept_Insert3(
						 #{deptno,	mode=IN	, jdbcType=INTEGER}
						,#{dname, 	mode=IN	, jdbcType=VARCHAR}
						,#{loc, 	mode=IN	, jdbcType=VARCHAR}
						,#{odeptno, mode=OUT, jdbcType=INTEGER}
						,#{odname, 	mode=OUT, jdbcType=VARCHAR}
						,#{oloc, 	mode=OUT, jdbcType=VARCHAR}
			)
		}
	</select>
	
	<select id="procDeptList" parameterType="java.util.Map" statementType="CALLABLE">
		{
			call Dept_Cursor3(
								 #{sDeptno, mode=IN,  jdbcType=INTEGER}
								,#{eDeptno, mode=IN,  jdbcType=INTEGER}
								,#{dept,	mode=OUT, jdbcType=CURSOR
													, javaType=java.sql.ResultSet
													, resultMap=DeptResult}
								)
		}
	</select>
</mapper>
Console
 

 

 

 

 

Spring Starter Project oBootMybatis01
package resources/mappers
xml Emp.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.EmpMapper">
							<!-- return 값이 2개 이상이면 DTO를 써야한다. -->
	<select id="empTotal" resultType="int">
		SELECT COUNT(*) FROM emp
	</select>
	
	
	
	<select id="tkEmpListAll" parameterType="Emp" resultType="Emp">
	
		<![CDATA[
			SELECT * 
			FROM (
					SELECT ROWNUM rn, a.* 
					FROM (
							SELECT * FROM emp ORDER BY empno
						  ) a
				 )
			WHERE rn >= #{start}
			AND	  rn <= #{end}
		]]>
	
	</select>
	
	
	
	<select id="tkEmpListAll3" parameterType="Emp" resultType="Emp">
		SELECT * 
		FROM (
				SELECT ROWNUM rn, a.* 
				FROM (
						SELECT * FROM emp ORDER BY empno
					  ) a
			 )
		WHERE rn BETWEEN #{start} AND #{end}
	</select>
	
	
	
	<!-- detail Emp							resultType가 여러개의 값이면 무조건 DTO로!! -->
	<select id="tkEmpSelOne" parameterType="int" resultType="Emp">
		SELECT *
		FROM emp
		WHERE empno=#{empno}
	</select>
	
	
	
	<update id="tkEmpUpdate" parameterType="Emp">
		UPDATE  emp 
		SET		ename=#{ename}, job=#{job}, sal=#{sal}, 
		    	hiredate=#{hiredate},
		    	<if test="#{comm}!=null"> comm=#{comm},</if>
		    	mgr=#{mgr}, deptno=#{deptno}
		WHERE 	empno=#{empno}
					   
	</update>
	
	
	
	<select id="tkSelectManager" resultType="Emp">
		SELECT 	*
		FROM 	emp
		WHERE 	empno IN (SELECT mgr FROM emp)
	</select>
	
	
	
	<insert id="insertEmp" parameterType="Emp">
		INSERT INTO emp(empno, ename, job, sal, hiredate, comm, mgr, deptno)
		VALUES(#{empno}, #{ename}, #{job}, #{sal}, #{hiredate}, #{comm}, #{mgr}, #{deptno})
	</insert>
	
	
	
	<delete id="deleteEmp" parameterType="int">
		DELETE FROM emp
		WHERE empno=#{empno}
	</delete>
	
	
	
	<select id="condEmpTotal" parameterType="Emp" resultType="int">
		SELECT 	COUNT(*)
		FROM 	emp
		<choose>
			<when test="search == 's_job'">
				WHERE job LIKE '%' || #{keyword} || '%'
			</when>
			<when test="search == 's_ename'">
				WHERE ename LIKE '%' || #{keyword} || '%'
			</when>
			<otherwise>
				WHERE job LIKE '%'
			</otherwise>
		</choose>
	</select>
	
	
	<select id="tkEmpSearchList3" parameterType="Emp" resultType="Emp">
		SELECT *
		FROM (
				SELECT ROWNUM rn, a.*
				FROM (
						SELECT *
						FROM emp
						<choose>
							<when test="search == 's_job'">
							WHERE job LIKE '%' || #{keyword} || '%'
							</when>
							<when test="search == 's_ename'">
								WHERE ename LIKE '%' || #{keyword} || '%'
							</when>
							<otherwise>
								WHERE job LIKE '%'
							</otherwise>
						</choose>
						ORDER BY empno
						) a
				)
		WHERE rn BETWEEN #{start} AND #{end}
	</select>
	
</mapper>
Console
 

 

 

 

 

Spring Starter Project oBootMybatis01
package 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
 

 

 

 

 

Spring Starter Project oBootMybatis01
package resources/mappers
xml Member1.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.Member1Mapper">
	<select id="memCount" parameterType="java.lang.String" resultType="int">
		SELECT	COUNT(*)
		FROM	member1
		WHERE 	id=#{id}
	</select>
	
	<select id="listMember1" parameterType="Member1" resultType="Member1">
		SELECT *
		FROM member1
	</select>
	
	<insert id="insertMember3" parameterType="Member1">
		INSERT INTO Member1(id, password, name)
		VALUES (#{id}, #{password}, #{name})
	</insert>
	
	<insert id="insertMember1" parameterType="Member1">
		INSERT INTO Member1(id, password, name)
		VALUES (#{id}, #{password}, #{name, jdbcType=VARCHAR})
	</insert>
</mapper>
Console
 

 

 

 



Spring Starter Project oBootMybatis01
folder resources/static/css
css board.css
@CHARSET "UTF-8";
body {	font-family: 굴림체; text-align: center;	}
table { border: 1px solid pink; width: 100%; 
         }
tr { height: 30px; background: yellow; }
/* th {	background: #C9BFED;	} */
th {	background: #b9b973;	}
td {	background: #f9f3b3;	}
Console
 

 

 

 



Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp header.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<link href="css/board.css" rel="stylesheet" type="text/css">
Console
 

 

 

 

 



Spring Starter Project oBootMybatis01
folder resources/static
html index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>회원 관리</h1>
	<a href="/listEmpStart">회원 목록(기본 CRUD)</a><p>
	<a href="/listEmpDept">직원부서조회(Join/Mail전송)</a><p>
	<a href="/writeDeptIn">PL/SQL(부서입력) </a><p>
	<a href="/writeDeptCursor">PL/SQL(부서조회 Cursor) </a><p>
	<a href="/memberJpa/new">JPA Member(CRUD) </a><p>
	<a href="/interCeptorForm">interCeptor(가로채기) </a><p>
	<a href="/upLoadFormStart">UpLoad(이미지 올리기) </a><p>
	<a href="/ajaxForm">Ajax Form Test </a><p>
	<a href="/transactionInsertUpdate">Transaction Test</a><p>
	<a href="/chat">Chating </a><p>
</body>
</html>
Console

 

 



Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp list.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>
</head>
<body>
	<h1>회원관리</h1>
	
	<a href="writeFormEmp">writeFormEmp 입력</a><p>
	<a href="writeFormEmp3">writeFormEmp3 입력(Validation)</a>
	
	<h3>사원수 : ${totalEmp }</h3>
	<p>uptCnt 수정 시 전달 Message : ${uptCnt }<p>
	<p>kk3    수정 시 전달 Message : ${kk3 }<p>
	
	<form action="listSearch3">
		<select name="search">
			<option value="s_job">업무 조회</option>
			<option value="s_ename">이름 조회</option>
		</select>
		
		<input type="text" name="keyword" placeholder="keyword를 입력하세요">
		<button type="submit">keyword 검색</button><p>
	</form>
	
	<c:set var="num" value="${page.total-page.start+1 }"></c:set>
	
	<table>
		<tr>
			<th>번호</th>
			<th>사번</th>
			<th>이름</th>
			<th>업무</th>
			<th>급여</th>
		</tr>
		<c:forEach var="emp" items="${listEmp }">
			<tr>
				<td>${num }</td>
				<td>${emp.empno }</td>
				<td><a href="detailEmp?empno=${emp.empno }">${emp.ename }</a></td>
				<td>${emp.job }</td>
				<td>${emp.sal }</td>
			</tr>
			<c:set var="num" value="${num-1 }"></c:set>
		</c:forEach>
	</table>
	
	<c:if test="${page.startPage > page.pageBlock }">
		<a href="listEmp?currentPage=${page.startPage-page.pageBlock }">[이전]</a>
	</c:if>
	<c:forEach var="i" begin="${page.startPage }" end="${page.endPage }">
		<a href="listEmp?currentPage=${i }">[${i }]</a>
	</c:forEach>
	<c:if test="${page.endPage < page.totalPage }">
		<a href="listEmp?currentPage=${page.startPage+page.pageBlock }">[다음]</a>
	</c:if>
</body>
</html>
Console

 

 

 



 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp detailEmp.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>
</head>
<body>
	<h2>직원정보</h2>
	<table>
		<tr><th>사번</th><td>${emp.empno }</td></tr>
		<tr><th>이름</th><td>${emp.ename }</td></tr>
		<tr><th>업무</th><td>${emp.job }</td></tr>
		<tr><th>급여</th><td>${emp.sal }</td></tr>
		<tr><th>입사일</th><td>${emp.hiredate }</td></tr>
		<tr><th>보너스</th><td>${emp.comm }</td></tr>
		<tr><th>관리자사번</th><td>${emp.mgr }</td></tr>
		<tr><th>부서코드</th><td>${emp.deptno }</td></tr>
		<tr>
			<td colspan="2">
				<input type="button" value="목록"
					onclick="location.href='listEmp'">
				<input type="button" value="수정"
					onclick="location.href='updateFormEmp?empno=${emp.empno }'">
				<input type="button" value="삭제"
					onclick="location.href='deleteEmp?empno=${emp.empno}'">
			</td>
		</tr>
	</table>
</body>
</html>
Console

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp updateFormEmp.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>
</head>
<body>
	<h2>직원 정보</h2>
	<form action="updateEmp" method="post">
		<input type="hidden" name="empno" value="${emp.empno }">
		<table>
			<tr>
				<th>사번</th>
				<td>${emp.empno }</td>
			</tr>
			<tr>
				<th>이름</th>
				<td><input type="text" name="ename" required="required" value="${emp.ename }"></td>
			</tr>
			<tr>
				<th>업무</th>
				<td><input type="text" name="job" required="required" value="${emp.job }"></td>
			</tr>
			<tr>
				<th>급여</th>
				<td><input type="number" name="sal" required="required" value="${emp.sal }"></td>
			</tr>
			<tr>
				<th>입사일</th>
				<td><input type="date" name="hiredate" id="hiredate" value="${emp.hiredate }"></td>
			</tr>
			<tr>
				<th>보너스</th>
				<td><input type="number" name="comm" required="required" value="${emp.comm }"></td>
			</tr>
			<tr>
				<th>관리자사번</th>
				<td><input type="number" name="mgr" value="${emp.mgr }"></td>
			</tr>
			<tr>
				<th>부서코드</th>
				<td><input type="number" name="deptno" required="required" value="${emp.deptno }"></td>
			</tr>
			<tr>
				<td colspan="2">
					<input type="submit" value="확인">
				</td>
			</tr>
		</table>
	</form>
</body>
</html>
Console

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp writeFormEmp.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">
	function chk() {
		if (!frm.empno.value) {
			alert("사번을 입력한 후에 확인하세요");
			frm.empno.focus();
			return false;
		} else location.href="confirm?empno="+frm.empno.value;
	}
</script>
</head>
<body>
	<h2>직원정보 입력</h2>
	<c:if test="${msg!=null }">${msg }</c:if><p>
	<form action="writeEmp" method="post" name="frm">
		<table>
			<tr>
				<th>사번</th>
				<td><input type="number" name="empno" required="required" 
										 maxlength="4" value="${empno }">
					<input type="button" value="중복확인" onclick="chk()">
				</td>
			</tr>
			<tr>
				<th>이름</th>
				<td><input type="text" name="ename" required="required"></td>
			</tr>
			<tr>
				<th>업무</th>
				<td><input type="text" name="job" required="required"></td>
			</tr>
			<tr>
				<th>급여</th>
				<td><input type="number" name="sal" required="required"></td>
			</tr>
			<tr>
				<th>입사일</th>
				<td><input type="date" name="hiredate" required="required"></td>
			</tr>
			<tr>
				<th>보너스</th>
				<td><input type="number" name="comm" required="required"></td>
			</tr>
			<tr>
				<th>관리자사번</th>
				<td><select name="mgr">
					<c:forEach var="emp" items="${empMngList }">
						<option value="${emp.empno }">${emp.ename }</option>
					</c:forEach>
				</select></td>
			</tr>
			<tr>
				<th>부서코드</th>
				<td><select name="deptno">
					<c:forEach var="dept" items="${deptList }">
						<option value="${dept.deptno }">${dept.dname }</option>
					</c:forEach>
				</select></td>
			</tr>
			<tr>
				<td colspan="2"><input type="submit" value="확인"></td>
			</tr>
		</table>
	</form>
</body>
</html>
Console

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp writeFormEmp3.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>

<!-- Validation check -->
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	function chk() {
		if (!frm.empno.value) {
			alert("사번을 입력한 후에 확인하세요");
			frm.empno.focus();
			return false;
		} else location.href="confirm?empno="+frm.empno.value;
	}
</script>
</head>
<body>
		<h2>직원정보 입력(Validation check 용도)</h2>
	<c:if test="${msg!=null }">${msg }</c:if><p>
	<form:form action="writeEmp3" method="post" name="frm" modelAttribute="emp">
		<table>
			<tr>
				<th>사번</th>
				<td><input type="number" name="empno" required="required" 
										 maxlength="4" value="${empno }">
					<input type="button" value="중복확인" onclick="chk()">
				</td>
			</tr>
			<tr>
				<th>이름</th>
				<td>
					<input type="text" name="ename">
					<form:errors path="ename"/>
				</td>
			</tr>
			<tr>
				<th>업무</th>
				<td><input type="text" name="job" required="required"></td>
			</tr>
			<tr>
				<th>급여</th>
				<td><input type="number" name="sal" required="required"></td>
			</tr>
			<tr>
				<th>입사일</th>
				<td><input type="date" name="hiredate" required="required"></td>
			</tr>
			<tr>
				<th>보너스</th>
				<td><input type="number" name="comm" required="required"></td>
			</tr>
			<tr>
				<th>관리자사번</th>
				<td><select name="mgr">
					<c:forEach var="emp" items="${empMngList }">
						<option value="${emp.empno }">${emp.ename }</option>
					</c:forEach>
				</select></td>
			</tr>
			<tr>
				<th>부서코드</th>
				<td><select name="deptno">
					<c:forEach var="dept" items="${deptList }">
						<option value="${dept.deptno }">${dept.dname }</option>
					</c:forEach>
				</select></td>
			</tr>
			<tr>
				<td colspan="2"><input type="submit" value="확인"></td>
			</tr>
		</table>
	</form:form>
</body>
</html>
Console

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp listEmpDept.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>
</head>
<body>
	<h2>회원 부서정보</h2>
	<a href="mailTransport">Mail Test(SMTP)</a>
	<p>Simple Mail Transfer Protocol -> OSI 전송계층</p>
	<table>
		<tr>
			<th>사번</th>
			<th>이름</th>
			<th>업무</th>
			<th>부서</th>
			<th>근무지</th>
		</tr>
		<c:forEach var="empDept" items="${listEmpDept }">
			<tr>
				<td>${empDept.empno }</td>
				<td>${empDept.ename }</td>
				<td>${empDept.job }</td>
				<td>${empDept.deptno }</td>
				<td>${empDept.loc }</td>
			</tr>
		</c:forEach>
	</table>
</body>
</html>
Console

 

 

 

 

 

 

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp mailResult.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>
</head>
<body>
	<h1>Mail 전송 결과</h1>
	<c:if test="${check==1 }">성공적으로 전송되었습니다.</c:if>
	<c:if test="${check !=1 }">메일전송이 실패되었습니다.</c:if>
	<c:if test="${check==null }">메일전송이 실패되었습니다. --> null</c:if>
</body>
</html>
Console

 

 

 

 

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp writeDept3.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%><%@ include file="header.jsp" %>
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	function chk() {
/* 		if (!frm.empno.value) {
			alert("사번을 입력한 후에 확인하세요");
			frm.empno.focus();
			return false;
		} else location.href="confirm.do?empno="+frm.empno.value; */
	}
</script>
</head>
<body>

 <h2>부서정보 입력</h2>
 <c:if test="${msg!=null}">${msg}</c:if>
	<form action="writeDept" method="post" name="frm">
		<table>
			<tr>
				<th>부서번호</th>
				<td><input type="number" name="deptno" 
							required="required" maxlength="2" >
					<input type="button" value="중복확인:미구현" onclick="chk()">
				</td>
			</tr>
			<tr>
				<th>부서이름</th>
				<td><input type="text" name="dname" 
							required="required">
				</td>
			</tr>
			<tr>
				<th>부서위치</th>
				<td><input type="text" name="loc" 
							required="required">
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<input type="submit" value="확인">
				</td>
			</tr>
		</table>
		입력된 부서번호 :<c:if test="${dept.odeptno!=null}">${dept.odeptno}</c:if><p>
	         입력된 부서명   :<c:if test="${dept.odname!=null}">${dept.odname}</c:if><p> 
	         입력된 부서위치 :<c:if test="${dept.oloc!=null}">${dept.oloc}</c:if><p> 
	        <%-- ${deptVO.Oloc} --%>
	        
	   <h2>부서 정보 List</h2>
	   <table>
		<tr><th>부서명</th><th>부서이름</th><th>근무지</th></tr>
		<c:forEach var="listDept" items="${listDept}">
			<tr><td>${listDept.odeptno }</td>
			    <td>${listDept.odname }</td>
				<td>${listDept.oloc }</td>
			</tr>
		</c:forEach>
	   </table>     
	        
	</form>   
	
</body>
</html>
Console

 

 

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp writeDeptCursor.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>
</head>
<body>
	<h2>부서정보 Procedure Cursor List</h2>
	<table>
		<tr>
			<th>부서명</th>
			<th>부서이름</th>
			<th>근무지</th>
		</tr>
		<c:forEach var="listDept" items="${deptList }">
			<tr>
				<td>${listDept.deptno }</td>
				<td>${listDept.dname }</td>
				<td>${listDept.loc }</td>
			</tr>
		</c:forEach>
	</table>
</body>
</html>
Console

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views/memberJpa
jsp createMemberForm.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>Mybatis JPA 회원 등록</h1>
	<div class="container">
		<form action="${pageContext.request.contextPath }/memberJpa/save" method="post">
			ID : <input type="text" id="id" name="id" required="required"><p>
			이름 : <input type="text" id="name" name="name" placeholder="이름을 입력하세요"><p>
			PW : <input type="text" id="pw" name="password" placeholder="PW를 입력하세요"><p>
			<button type="submit">등록</button>
		</form>
		<a href="/members">JPA Member List 조회</a><p>
	</div> <!--/container -->
</body>
</html>
Console

 

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views/memberJpa
jsp memberList.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>
</head>
<body>
	<h2>JPA 직원(member) 목록</h2><a href="memberJpa/new">입력</a>
	<c:set var="num" value="1"></c:set>
		<c:if test="${message != null }">
			${message }
		</c:if>
	
	<table>
		<tr>
			<th>번호</th>
			<th>사번</th>
			<th>이름</th>
			<th>비번</th>
		</tr>
		<c:forEach var="member" items="${members }">
			<tr>
				<td>${num }</td>
				<td>${member.id }</td>
				<td><a href="memberJpa/memberUpdateForm?id=${member.id }">${member.name }</a></td>
				<td>${member.password }</td>
				<c:set var="num" value="${num + 1 }"></c:set>
			</tr>
		</c:forEach>
	</table>
</body>
</html>
Console

 

 

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views/memberJpa
jsp memberModify.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>
</head>
<body>
	<h2>회원정보(JPA) 수정</h2>
	<form action="<%=request.getContextPath()%>/memberJpa/memberUpdate" method="get">
		<input type="hidden" name="id" value="${member.id }">
		
		<table>
			<tr>
				<th>회원번호</th>
				<td>${member.id }</td>
			</tr>
			<tr>
				<th>이름</th>
				<td>
					<input type="text" name="name" required="required" value="${member.name }">
				</td>
			</tr>
			<%-- <tr>
				<th>비밀번호</th>
				<td>
					<input type="text" name="password" value="${member.password }">
				</td>
			</tr> --%>
			<tr>
				<td colspan="2">
					<input type="submit" value="확인">
				</td>
			</tr>
		</table>
	</form>
</body>
</html>
Console

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp interCeptorForm.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>
</head>
<body>
	<h2>직원정보 조회</h2>
	<c:if test="${msg!=null }">${msg }</c:if>
	<form action="interCeptor" name="frm">
		<table>
			<tr>
				<th>사번</th>
				<td><input type="text" name="id" required="required"></td>
			</tr>
			<tr>
				<td><input type="submit" value="확인"></td>
			</tr>
		</table>
	</form>
</body>
</html>
Console

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp interCeptor.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>interCepter</title>
</head>
<body>
    id        : ${id} <p>
    memcnt    : ${memCnt}
    

</body>
</html>
Console
 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp doMemberWrite.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>doMemberWrite</title>
</head>
<body>

	<h2>직원정보 입력</h2>
	<form action="" method="post" name="frm">
	<table>
		<tr><th>사번</th><td><input type="text" name="id" 
			required="required" maxlength="4" value="${id}">
			<input type="button" value="중복확인" 
			onclick="chk()"> </td></tr>
		<tr><th>비밀번호</th><td><input type="text" name="password" 
			required="required"> </td></tr>
		<tr><th>이름</th><td><input type="text" name="name" 
			required="required"></td></tr>
	
		<tr><td colspan="2"><input type="submit" value="확인"></td></tr>
	</table>
</form>

</body>
</html>
Console

 

 

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp doMemberList.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>
</head>
<body>
	<h2>회원 정보</h2>
	조회자 ID : ${ID }
	<table>
		<tr>
			<th>ID</th>
			<th>이름</th>
			<th>비밀번호</th>
			<th>등록일</th>
		</tr>
		<c:forEach var="listMem" items="${listMem }">
			<tr>
				<td>${listMem.id }</td>
				<td>${listMem.name }</td>
				<td>${listMem.password }</td>
				<td>${listMem.reg_date }</td>
			</tr>
		</c:forEach>
	</table>
</body>
</html>
Console
 

 

 

 

 




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

 

 

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp .jsp

 

Console
 

 

 

 




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 }">
	
	<p><a href="uploadFileDelete?delFile=${savedName }">upLoad 삭제 Test</a>
</body>
</html>
Console

 

 

 




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

 

 

 




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

 

 

 




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="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
	function getListDept() {
		alert("getListDept Run....");
		var str = "";
		var str2 = "";
		
		$.ajax(
				{
					url:"/sendVO3",
					dataType:'json',
					success:function(deptList) {
						var jsonStr = JSON.stringify(deptList);
						alert("jsonStr->" +jsonStr);
						$('#dept_list_str').append(jsonStr);
						str += "<select name='dept'>";
						$(deptList).each(
							function(){
								str2 = "<option value='"+this.deptno +"'> "+this.dname+"</option>";
								str += str2;
							}
						)
						str += "</select><p>"
						alert("combobox str-> "+str);
						$('#dept_list_combobox').append(str);
					}
				}

		);
	}
	
	function getEmpnoDelete(pIndex) {
		alert("getDeptDelete Run....");
		// url    -> empnoDelete(EmpRestController)
		// parm   -> empno : selEmpno 
		//	empno만 넘겨주면 되는데, parameter 2개 넘겨주는 거 연습하기 위해서 ename까지
		// 성공하면  ->  Delete Tag
		var selEmpno = $("#empno"+pIndex).val();
		var selEname = $("#ename"+pIndex).val();
		
/* 		$.ajax(
				{
					url:"/empnoDelete",
					data:{empno : selEmpno,
						  ename : selEname},
					dataType:'text',
					success:function(data){
						alert(".ajax getDeptDelete data-> "+data);
						if (data =='1') {
							//성공하면 아래라인 수행 --> Delete Tag
							$('#emp'+pIndex).remove();
						}
					}
				}
		);
*/
		//결과를 객체로 받음
		$.ajax(
				{
					url:"/empnoDelete03",
					//위: 물리적 삭제
					//아래: 화면 단(view) 삭제
					data:{empno : selEmpno,
						  ename : selEname},
					dataType:'json',
					success:function(response){
						alert(".ajax getDeptDelete response.delStatus-> "+response.delStatus);
						if (response.delStatus =='1') {
							//성공하면 아래라인 수행 --> Delete Tag
							$('#emp'+pIndex).remove();
						}
					}
				}
		);
	}
</script>
</head>
<body>
	<h2>회원 정보</h2>
	<table>
		<tr>
			<th>번호</th>
			<th>사번</th>
			<th>이름</th>
			<th>업무</th>
			<th>부서</th>
		</tr>
		<c:forEach var="emp" items="${listEmp }" varStatus="status">
			<tr id="emp${status.index }">
				<td>emp${status.index }</td>
				<td>
					<input type="hidden" id="deptno${status.index }" value="${emp.deptno }">
					<input type="text" id="empno${status.index }" value="${emp.empno }">
				</td>
				<td>
					<input type="text" id="ename${status.index }" value="${emp.ename }">
				</td>
				<td>${emp.job }</td>
				<td>${emp.deptno }
					<input type="button" id="btn_idCheck2" value="사원 Row Delete"
									onclick="getEmpnoDelete(${status.index})">
				</td>
			</tr>
		</c:forEach>
	</table>
	
	RestController LISTVO3: <input  type="button" 
									id="btn_Dept3"
                                    value="부서명 LIST"  
                                    onclick="getListDept()"><p>
                                   
	dept_list_str:	<div id="dept_list_str"></div><p>

	dept_list_combobox:
	<div id="dept_list_combobox"></div>
	
	<h1>The End </h1>
</body>
</html>
Console

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp listEmpAjaxForm3.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="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">

	// listEmpAjaxForm3.jsp 에서 수정 전 작업 sample
	function getEmpListUpdateTest() {
		alert("getEmpListUpdateTest Run....")
		// Group 번호 가져오기
		var arr = new Array();
		var item;
		
		<c:forEach items="${listEmp}" var="item">
			arr.push({
						empno:"${item.empno}",
						ename:"${item.ename}",
						deptno:"${item.deptno}"
			});
		</c:forEach>
		
		for (var i=0 ; i<arr.length;) {
			alert("arr.empno-> "+i+" :  "+arr[i].empno + ", arr.ename-> "+i+" :  "+arr[i].ename);
			i++;
			if (i > 2) return;
		}
	}
	
	// listEmpAjaxForm3.jsp 에서 수정 후 작업 sample
	//JavaScript에서 empList를 수정한 Data를 JSON 데이터로 전환 empController로 보내기 예제
	function getEmpListUpdate() {
		alert("getEmpListUpdate Run....")
		
		let empList = [];
		
		const inputs = document.querySelectorAll('input[name="empno"], input[name="ename"], input[name="deptno"]');
		for (let i=0; i< inputs.length; i += 3) {
			const empno = inputs[i+1].value;
			const ename = inputs[i+2].value;
			const deptno = inputs[i+3].value;
			//불러온 값들을 JSON 객체 형태로 만든다.
			const empItem = {
							"empno":empno,
							"ename":ename,
							"deptno":deptno
							};
			//alert("ename-> "+ename);
			// JSON 객체를 배열 안에 넣어둔다.
			empList.push(empItem);
			if(i>5) break;
		}
		//수정 후의 list
		alert("JSON.stringify(empList)-> "+JSON.stringify(empList));
		
		if (empList.length > 0) {
			$.ajax({
					url: 'empListUpdate',
					contentType: 'application/json',
					data: JSON.stringify(empList),	//JSON 객체를 불러와서 stringify() 함수 안에 배열
					method: 'POST',
					// 위 까지가 서버프로
					//아래가 return
					dataType: 'json',
					success: function(response) {
						console.log(response.updateResult);
					}
			});
			alert("Ajax empListUpdate 수행...");
		}
		
		
	}
</script>
</head> 
<body>
	<h2>회원 정보3</h2>
	<table  id="empList">
		<tr>
			<th>번호</th>
			<th>사번</th>
			<th>이름</th>
			<th>업무</th>
			<th>부서</th>
		</tr>
	 	<c:forEach var="emp" items="${listEmp}" varStatus="status">
			<tr id="empListRow"><td>emp${status.index}</td>
		     	
			    <td>
			        <input type="hidden" class="deptno"   id="deptno" name="deptno" value="${emp.deptno }">
			        <input type="text"   class="empno"   id="empno"  name="empno"  value="${emp.empno }">${emp.empno }
			    </td>
			    <td>
			    	<input type="text"   class="ename"   id="ename"  name="ename"  value="${emp.ename }">${emp.ename }
			    </td>
				<td>${emp.job }</td>
				<td>${emp.deptno }</td>
			</tr>    
	     
	     </c:forEach>
	</table><p>
	RestController LISTVO3: <input  type="button" id="btn_Dept3"
                                   value="empLISTTest 전송 "  
                                   onclick="getEmpListUpdateTest()"><p>
    RestController LISTVO3: <input  type="button" id="btn_Dept3"
                                   value="empLIST 전송 "  
                                   onclick="getEmpListUpdate()"><p>
                                   

	
	<h1>The End </h1>
</body>
</html>
Console

 




Spring Starter Project oBootMybatis01
folder src/main/webapp/WEB-INF/views
jsp chatView.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>
<script  src="http://code.jquery.com/jquery-latest.min.js"></script>
	<style>
		*{
			margin:0;
			padding:0;
		}
		.container{
			width: 500px;
			margin: 0 auto;
			padding: 25px
		}
		.container h1{
			text-align: left;
			padding: 5px 5px 5px 15px;
			color: #FFBB00;
			border-left: 3px solid #FFBB00;
			margin-bottom: 20px;
		}
		.chating{
			background-color: #000;
			width: 500px;
			height: 500px;
			overflow: auto;
		}
		.chating .me{
			color: #F6F6F6;
			text-align: right;
		}
		.chating .others{
			color: #FFE400;
			text-align: left;
		}
		input{
			width: 330px;
			height: 25px;
		}
		#yourMsg{
			display: none;
		}
		#yourNameDel{
			display: none;
		}
	</style>
</head>
<script type="text/javascript">
    // web Socket
	var ws;

	function wsOpen(){
		console.log("wsOpen  location.host: " + location.host);
        var wsUri  = "ws://" + location.host + "${pageContext.request.contextPath}/chating";
        // WebSocket 프로토콜을 사용하여 통신하기 위해서는 WebSocket객체를 생성. 
        // 객체는 자동으로 서버로의 연결
 		ws = new WebSocket(wsUri);
		wsEvt();
 		
	}

    function  wsEvt() {
		console.log("wsEvt  start... ");
        alert("wsEvt  start...");
        
        //소켓이 열리면 동작
		ws.onopen = function(data){
			console.log("wsEvt  소켓이 열리면 초기화 세팅하기..");
		}	
		//메시지를 받으면 동작
       ws.onmessage = function(data) {
			var msg = data.data;
			var memberSave = false;
			alert("ws.onmessage->"+msg)
			if(msg != null && msg.trim() != ''){
				memberSave = false;
				// JSON 오브젝트를 자바스크립트 오브젝트로 변환
			    var jsonMsg = JSON.parse(msg);
				// msg가 배열이고, 2개이상의 Count이면 , member 등록 대상 
                if (Array.isArray(jsonMsg)) {
                	if (Object.keys(jsonMsg).length > 1) {
                    	memberSave = true;
                       	alert("JSONArray jsonMsg Count->"+ Object.keys(jsonMsg).length);
                	}
                }			
			}
			
			// 파싱한 객체의 type값을 확인하여 getId값이면 초기 설정된 값이므로 채팅창에 값을 입력하는게 아니라
			// 추가한 태그 sessionId에 값을 세팅
			if(jsonMsg.type == "getId"){
				alert("jsonMsg.type->getId");
				var sid = jsonMsg.sessionId != null ? jsonMsg.sessionId : "";
				if(sid != ''){
					$("#sessionId").val(sid); 
					// session User 등록 수행
					sendUser('Create');
				}
				
				
			}else if(jsonMsg.type == "message"){
				alert("jsonMsg.type->message");
				// type이 message인 경우엔 채팅이 발생한 경우.
                // 상대방과 자신을 구분하기 위해 여기서 sessionId값을 사용
                // 최초 이름을 입력하고 연결되었을때, 발급받은 sessionId값을 비교하여 같다면 자기 자신이 발신한
                // 메시지이므로 오른쪽으로 정렬하는 클래스를 처리하고 메시지를 출력.     
                // 비교하여 같지 않다면 타인이 발신한 메시지이므로 왼쪽으로 정렬하는 클래스를 처리하고 메시지를 출력
				if(jsonMsg.sessionId == $("#sessionId").val()){
					$("#chating").append("<p class='me'>나 :" + jsonMsg.msg + "</p>");	
				}else{
					$("#chating").append("<p class='others'>" + jsonMsg.userName + " :" + jsonMsg.msg + "</p>");
				}
				
			}
			
			// Session에 변동이 일어 날때 
			if(memberSave == true){
					alert("userSave");
					$('#member_sub').remove();
					//  memberSave = true 면  -->	User 등록/삭제 일경우
					// div로 감싸주면 재정의시 삭제(Refresh)후 다시 생성 
					//var str = " <div id='member_sub' class='member_sub'> ";
					var str = " ";
					str  += " <select name='member' id='member_sub' class='member_sub'> ";
					str  += " <option value='ALL'>전체 </option> "; 
					$(jsonMsg).each(
						function(){
							var str2 = "";
				            // User를 선택하여 message전송 가능토록 member에 등록 
				            alert("내 sessionId->"+ $("#sessionId").val())
				            alert("this.sessionId->"+ this.sessionId)
							if(this.sessionId == $("#sessionId").val()){
								alert("내꺼임"+ $("#sessionId").val())
							} else {  // 타인 session일 경우 추가 등록 
								str2 += " <option value='"+this.sessionId + "'> "+this.userName  + "</option> "; 
								str  += str2 ;
							}
						}
					);
					str += " </select>"
					str += " </div><p>"
					$('#member').append(str);	
					memberSave = false;
					
			}else{
					console.warn("unknown type!");
			}
		}
	   	document.addEventListener("keypress", function(e){
			if(e.keyCode == 13){ //enter press
				send();
			}
		});		
	}
     
    // User 등록  Message 전송       saveStatus --> Create / Delete
    function sendUser(saveStatus) {
		var userOption ={
				type       : "userSave",
				sessionId  : $("#sessionId").val(),
				userName   : $("#userName").val(),
				saveStatus : saveStatus
			}
		alert("sendUser Start..")  	
		// 자바스크립트의 값을 JSON 문자열로 변환
		// Client --> Server (ws.send로 보내준다.)
		ws.send(JSON.stringify(userOption));

		//자기자신 창을 닫습니다.
		if(saveStatus == "Delete") {
			alert("sendUser saveStatus-->"+saveStatus);
			//window.open('','_self').close(); 
			 window.open(location.href, "_self", "");
			 window.close()
		}
}
    
    

    function chatName(){
    	alert("chatName Start..");
		var userName = $("#userName").val();
		console.log("chatName  userName: " + userName);
		if(userName == null || userName.trim() == ""){
			alert("사용자 이름을 입력해주세요.");
			$("#userName").focus();
		}else{
			wsOpen();
			$("#meName").append('나의이름:'+userName); 
			$("#yourName").hide();
			$("#yourMsg").show();
		//	$("#yourNameDel").show();
		}   	
    	
    }

	// 전체 Message 전송 
	function send() {
		var option ={
			type: "message",
			sessionId : $("#sessionId").val(),
			userName : $("#userName").val(),
			yourName : $("#member_sub").val(),
			msg : $("#sendMsg").val()
		}
		// 자바스크립트의 값을 JSON 문자열로 변환
		ws.send(JSON.stringify(option));
		$('#sendMsg').val("");
	}   
    

</script>
<body>
	<div id="container" class="container">
		<h1>채팅</h1>
		<input type="hidden" id="sessionId" value="">
		<div id="meName"></div>
		<div id="chating" class="chating">
		</div>
		<div id="member" class="member">
		</div>
		
		<div id="yourName">
			<table class="inputTable">
				<tr>
					<th>사용자명</th>
					<th><input type="text" name="userName" id="userName"></th>
					<th><button onclick="chatName()" id="startBtn">이름 등록</button></th>
				</tr>
			</table>
		</div>
		<div id="yourNameDel">
			<table class="deleteTable">
				<tr>
					<th>사용자명 삭제</th>
					<!-- <th><input type="text" name="userName" id="userName"></th> -->
					<th><button onclick="sendUser('Delete')" id="startBtn">이름 삭제</button></th>
				</tr>
			</table>
		</div>
		<div id="yourMsg">
			<table class="inputTable">
				<tr>
					<th>메시지</th>
					<th><input id="sendMsg" placeholder="보내실 메시지를 입력하세요."></th>
					<th><button onclick="send()" id="sendBtn">보내기</button></th>
				</tr>
			</table>
		</div>
	</div>
</body>
</html>
Console
 

 

 

'Spring' 카테고리의 다른 글

oBootJpaApi01  (0) 2024.09.12
Day63 2024.08.21.수 #코딩일기  (0) 2024.08.21
Day62 2024.08.20.화 #코딩일기  (0) 2024.08.20
Day61 2024.08.19.월 #코딩일기  (0) 2024.08.19
Day60 2024.08.14.수 #코딩일기  (0) 2024.08.14