Spring 07 (23.04.14)

Jane·2023년 4월 14일
0

IT 수업 정리

목록 보기
105/124

1. 1:N 처리하기

  • EMP가 N, DEPT가 1 (DEPT 하나에 여러 개의 EMP가 붙을 수 있다.)

1-1. xml 만들어서 조인하기

DeptVO.java

package edu.global.ex.vo;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class DeptVO {
	private int deptno;
	private String dname;
	private String loc;
	
	List<EmpVO> empList;
}
  • resultMap
    • primary key의 역할을 하는 것은 id (의미의 역할. result 해도 오류는 안 난다.) / set 함수가 호출되고, 컬럼에서 갖고 오는 값이 들어가게 된다.
    • id의 property : VO에 선언된 필드의 속성과 맞춘다.
    • id의 column : 실제 DB에 있는 컬럼의 이름과 맞춰서 쓴다.
    • 나머지는 result 태그로
    • set,list,queue(컬렉션 프레임워크)는 collection으로 받고, resultMap으로 매핑한다.
    • 1:1은 association을 쓴다.
  • 조인하고자 하는 쿼리가 적힌 select 태그에 resultType이 아닌 resultMap을 추가시킨다.
  • application.properties에 패키지 선언한 상태

DeptMapper.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="edu.global.ex.mapper.DeptMapper">
	<select id="getEmpDeptOneVOList" resultType="EmpDeptVO">
	<![CDATA[
      select * from emp,dept where emp.deptno = dept.deptno
   ]]>
	</select>

	<resultMap id="empMap" type="EmpVO">
		<id property="empno" column="empno" />
		<result property="ename" column="ename" />
		<result property="job" column="job" />
		<result property="mgr" column="mgr" />
		<result property="hiredate" column="hiredate" />
		<result property="sal" column="sal" />
		<result property="comm" column="comm" />
		<result property="deptno" column="deptno" />
	</resultMap>

	<resultMap id="deptMap" type="DeptVO">
		<id property="deptno" column="deptno" />
		<result property="dname" column="dname" />
		<result property="loc" column="loc" />

		<collection property="empList" resultMap="empMap" />
	</resultMap>


	<select id="getEmpDeptList" resultMap="deptMap">
	<![CDATA[
      select * from emp,dept where emp.deptno = dept.deptno
   ]]>
	</select>
</mapper>

DeptMapper.java

package edu.global.ex.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import edu.global.ex.vo.EmpDeptVO;

@Mapper
public interface DeptMapper {
	public List<EmpDeptVO> getEmpDeptOneVOList();
	public List<DeptVO> getEmpDeptList();
}

EmpService.java

package edu.global.ex.service;

import java.util.List;

import edu.global.ex.page.Criteria;
import edu.global.ex.vo.EmpDeptVO;
import edu.global.ex.vo.EmpVO;

public interface EmpService {
	public List<EmpVO> getList();
	public EmpVO get(int bno);
	public List<EmpVO> getList(Criteria cri);
	public int getTotal();
	public List<EmpDeptVO> getEmpDeptOneVOList();
	public List<DeptVO> getEmpDeptList();
}

EmpServiceImpl.java (함수 추가)

@Override
	public List<DeptVO> getEmpDeptList() {
		
		return deptMapper.getEmpDeptList();
	}

EmpController.java (함수 추가)

	@GetMapping("/dept2")
	public String dept2(Model model) {
		log.info("view_dept2()...");
		System.out.println(empService.getEmpDeptList());
		
		return "/emp/list2";
	}

(ToString : deptno 기준으로 배열 형태로 출력)
[DeptVO(deptno=10, dname=ACCOUNTING, loc=NEW YORK,
empList=[EmpVO(empno=7839, ename=KING, job=PRESIDENT, mgr=0, hiredate=Tue Nov 17 00:00:00 KST 1981, sal=5000, comm=0, deptno=10),
EmpVO(empno=7782, ename=CLARK, job=MANAGER, mgr=7839, hiredate=Tue Jun 09 00:00:00 KST 1981, sal=2450, comm=0, deptno=10),
EmpVO(empno=7934, ename=MILLER, job=CLERK, mgr=7782, hiredate=Sat Jan 23 00:00:00 KST 1982, sal=1300, comm=0, deptno=10)]),
DeptVO(deptno=20, dname=RESEARCH, loc=DALLAS,
empList=[EmpVO(empno=7902, ename=FORD, job=ANALYST, mgr=7566, hiredate=Thu Dec 03 00:00:00 KST 1981, sal=3000, comm=0, deptno=20),
EmpVO(empno=7369, ename=SMITH, job=CLERK, mgr=7902, hiredate=Wed Dec 17 00:00:00 KST 1980, sal=800, comm=0, deptno=20),
EmpVO(empno=7566, ename=JONES, job=MANAGER, mgr=7839, hiredate=Thu Apr 02 00:00:00 KST 1981, sal=2975, comm=0, deptno=20)]),
DeptVO(deptno=30, dname=SALES, loc=CHICAGO,
empList=[EmpVO(empno=7900, ename=JAMES, job=CLERK, mgr=7698, hiredate=Thu Dec 03 00:00:00 KST 1981, sal=950, comm=0, deptno=30),
EmpVO(empno=7844, ename=TURNER, job=SALESMAN, mgr=7698, hiredate=Tue Sep 08 00:00:00 KST 1981, sal=1500, comm=0, deptno=30),
EmpVO(empno=7654, ename=MARTIN, job=SALESMAN, mgr=7698, hiredate=Mon Sep 28 00:00:00 KST 1981, sal=1250, comm=1400, deptno=30),
EmpVO(empno=7521, ename=WARD, job=SALESMAN, mgr=7698, hiredate=Sun Feb 22 00:00:00 KST 1981, sal=1250, comm=500, deptno=30),
EmpVO(empno=7499, ename=ALLEN, job=SALESMAN, mgr=7698, hiredate=Fri Feb 20 00:00:00 KST 1981, sal=1600, comm=300, deptno=30),
EmpVO(empno=7698, ename=BLAKE, job=MANAGER, mgr=7839, hiredate=Fri May 01 00:00:00 KST 1981, sal=2850, comm=0, deptno=30)])]

(2중 for 문 형태)

1-2. jsp 만들어서 뿌리기

EmpController.java (내용 수정)

	@GetMapping("/dept2")
	public String dept2(Model model) {
		log.info("view_dept2()...");
		System.out.println(empService.getEmpDeptList());
		model.addAttribute("empDeptList", empService.getEmpDeptList());
		return "/emp/empDept";
	}
  • emp 폴더 밑에 empDept.jsp 만들기
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>list2</title>
</head>
<body>
	<table width="500" cellpadding="0" cellspacing="0" border="1">
		<tr>
			<th>EMPNO</th>
			<th>ENAME</th>
			<th>DNAME</th>
			<th>LOC</th>
		</tr>
		<c:forEach var="deptList" items="${empDeptList}">
			<!-- DeptVO 3개 -->
			<c:forEach var="emp" items="${deptList.empList}">
				<!-- DeptVO와 조인된 EmpVO -->
				<tr>
					<td>${ emp.empno }</td>
					<td>${ emp.ename }</td>
					<td>${ deptList.dname }</td>
					<td>${ deptList.loc }</td>
				</tr>
			</c:forEach>
		</c:forEach>

	</table>

</body>
</html>


  • BoardMapper.xml getList 부분 주석처리
  • BoardMapper 부분을 다음과 같이 수정
@Select("select * from mvc_board order by bgroup desc, bstep asc")
	public List<BoardVO> getList();
  • 짧은 것은 상관 없지만, 서브쿼리 구문이 들어가거나 긴 쿼리는 쓰기 힘들다.
    (그래서 그냥 xml에 모아서 쓰는 경우가 많다.)

2. Restful 처리하기 (MyBatis 3.0버전 이상부터 지원)

  • 기존의 URI (Get? Post?)
    • 게시판 수정 (update?bid=1) -> GET
    • 게시판 삭제 (delete?bid=1) -> GET
  • Restful 처리 : URI와 URL을 활용하기 (/boards/20)
  • PUT, DELETE 등 사용 (form 태그에서는 지원이 안됨) > AJAX로 우회

2-1. Restful 다루는 Controller 만들기

RestBoardController.java

package edu.global.ex.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

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

import edu.global.ex.service.BoardService;
import edu.global.ex.vo.BoardVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequestMapping("/rboard/*")
@RequiredArgsConstructor
@RestController // 기존 컨트롤러의 문법과는 완전히 달라진다
public class RestBoardController {

	@Autowired
	private BoardService boardService;

	@GetMapping("/")
	public String rboard() {
		return "<h1>restful</h1>";
	}

	@GetMapping("/list")
	public List<BoardVO> rboard_list() {
		log.info("list()...");
		return boardService.getList();
	}
}
  • return 할 때 jsp가 아닌 return 안의 내용이 보여진다.
  • service의 함수를 호출하면 json 파일이 나온다.
    (크롬 확장 프로그램 'JSON Viewer' 설치하면 json 파일이 깔끔하게 보여진다.)
  • ajax는 내용을 객체 형태로 받는다.

2-2. ajax 파일 다루기

  • src/main/resource > static : 정적 이미지 (html, 이미지) 등을 넣는 곳
  • static 폴더 안에 rest_list.html 생성

rest_list.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
	$(document).ready(function() {

		$.ajax({
			type : "GET",
			url : "/rboard/list/",
			success : function(result) {

				console.log(result);

			},
			error : function(e) {
				console.log(e);
			}
		});

	});
</script>
</head>
<body>
	<table id="list-table" width="500" cellpadding="0" cellspacing="0"
		border="1">
	</table>
</body>
</html>

$.ajax({
url : '서비스 주소'
, data : '서비스 처리에 필요한 인자값'
, type : 'HTTP방식' (POST/GET 등)
, dataType : 'return 받을 데이터 타입' (json, text 등)
, success : function('결과값'){
// 서비스 성공 시 처리 할 내용
}, error : function('결과값'){
// 서비스 실패 시 처리 할 내용
}
});


rest_list.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>RestBoard</title>
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
	$(document).ready(
			function() {

				$.ajax({
					type : "GET",
					url : "/rboard/list/",
					success : function(result) {

						console.log(result);

						var htmls = "";

						$("#list-table").html(""); // 테이블 초기화

						$(
								"<tr>",
								{
									html : "<th>" + "번호" + "</th>" + "<th>"
											+ "이름" + "</th>" + "<th>" + "제목"
											+ "</th>" + "<th>" + "날짜" + "</th>"
											+ "<th>" + "히트" + "</th>" + "<th>" + "삭제" + "</th>"
								}).appendTo("#list-table"); // 이것을 테이블에 붙임
						
								
						if(result.length < 1){
				            htmls.push("등록된 댓글이 없습니다.");
				         } else {

				                    $(result).each(function(){                                                          
				                       htmls += '<tr>';
				                       htmls += '<td>'+ this.bid + '</td>';
				                       htmls += '<td>'+ this.bname + '</td>';
				                       htmls += '<td>'
				                     for(var i=0; i < this.bindent; i++) { //for 문은 시작하는 숫자와 종료되는 숫자를 적고 증가되는 값을 적어요. i++ 은 1씩 증가 i+2 는 2씩 증가^^
				                        htmls += '-'   
				                    }
				                       htmls += '<a href="/rest_content_view.html?bid=' + this.bid + '">' + this.btitle + '</a></td>';
				                      htmls += '<td>'+ this.bdate + '</td>'; 
				                       htmls += '<td>'+ this.bhit + '</td>';
				                       htmls += '<td>'+ '<input id=' + this.bid + " type='button' class='btn_delete' value='삭제'>" + '</td>';
				                       htmls += '</tr>';                                                      
				                   });   //each end

				                   htmls+='<tr>';
				                   htmls+='<td colspan="5"> <a href="/write_view">글작성</a> </td>';                         
				                   htmls+='</tr>';
				                   
				         }

				         $("#list-table").append(htmls);
					},
					error : function(e) {
						console.log(e);
					}
				});

			});
</script>

</head>
<body>
	<table id="list-table" border="1">
	</table>
</body>
</html>

2-3. 삭제 버튼 구현

  • 버튼 : <input id=' + this.bid + " type='button' class='btn_delete' value='삭제'>
  • ajax 가 있는 스크립트 밑에 스크립트 추가
  <script type="text/javascript">
	$(document).ready(function(){
		$(document).on("click", "#list-table .btn_delete", function(){
			console.log($(this).attr("id"));
		});
	});
</script>
  • 누르면 id 가 잘 출력되는지 확인하고 진행한다.
<script type="text/javascript">
	$(document).ready(function(){
		$(document).on("click", "#list-table .btn_delete", function(){
			// console.log($(this).attr("id"));
			
			var id = $(this).attr("id");
			
	            $.ajax({
	                type : "DELETE",
	                url : "/rboard/" + id,
	                success: function (result) {       
	                   console.log(result);      
	         
	                },
	                error: function (e) {
	                    console.log(e);
	                }
	            });
			
		});
	});
</script>

RestController.java (함수 추가)

	@DeleteMapping("/{bid}")
	public int rboard_delete(BoardVO board) {
		log.info("delete()...");
		
		return boardService.remove(board);
	}
profile
velog, GitHub, Notion 등에 작업물을 정리하고 있습니다.

0개의 댓글