전체 조회 : 부서명 like 기능 있음
데이터베이스(SQL&Docker) 활용
작업 순서: model -> dao -> mappers(xml) -> service -> Controller -> views(jsp)
페이징 처리 : 시작 페이지부터 끝 페이지까지 반복하며 각 페이지 번호를 생성
페이지 조회 : 현재 페이지 페이지 0, 크기 3
Dept 클래스 ( schema.sql 참고 )
DeptDao 클래스 findByEnameContaining()
Dept.xml 클래스
DeptService 클래스를 만들고 findByEnameContaining() 함수를 정의한다.
DeptController 클래스를 만들어서 getEmpAll() 함수를 정의하고,
샘플데이터를 뷰로(dept_all.html) 전송
resources 파일 이전 글 참고 [Spring Boot] - [SpringBoot] 데이터베이스(SQL&Docker)이용한 연결 환경 설정
[SpringBoot] 데이터베이스(SQL&Docker 이용) 연결 환경 설정
프로젝트 생성 1. 종속성 설정 2. dependencies 빌드 3. 파일 인코딩 변경 : UTF-8 4. resources 폴더 application.properties 설정 5. resources 폴더 실습용 환경 파일 추가 6. Java 리소스 폴더 만들기(jsp용) 7. 환경 설
soaked.tistory.com
제목입력부서 클래스 == 부서 테이블 유사
vo(Value Object) : 테이블과 동일하게 만듬
dto(Data Transfer Object) : 테이블 + 가공컬럼(속성)
extends BaseTimeEntity
@Setter
@Getter
@ToString
@NoArgsConstructo
@AllArgsConstructor
더보기
package com.example.mybatisexam.model.vo;
import com.example.mybatisexam.model.common.BaseTimeEntity;
import lombok.*;
/**
* packageName : com.example.mybatisexam.model.vo
* fileName : Dept
* author : L.DH
* date : 2023-10-12
* description : 부서 클래스 == 부서 테이블 유사
* 요약 :
* TODO : vo(Value Object) : 테이블과 동일하게 만듬
* TODO : dto(Data Transfer Object) : 테이블 + 가공컬럼(속성)
* <p>
* ===========================================================
* DATE AUTHOR NOTE
* ———————————————————————————————
* 2023-10-12 L.DH 최초 생성
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Dept extends BaseTimeEntity {
private Integer dno; // 부서번호
private String dname; // 부서명
private String loc; // 부서위치
}
Db 접속 함수들이(CRUD) 있는 클래스(mybatis mapper(=dao) 클래스)
interface 함수만 정의
@Mapper
@Param("속성명") 변수명 : sql 의 매개변수로 전달됨
더보기
package com.example.mybatisexam.dao;
import com.example.mybatisexam.model.common.PageReq;
import com.example.mybatisexam.model.vo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* packageName : com.example.mybatisexam.dao
* fileName : DeptDao
* author : L.DH
* date : 2023-10-12
* description : Db 접속 함수들이(CRUD) 있는 클래스(mybatis mapper(=dao) 클래스)
* 요약 :
* TODO : interface 함수만 정의
* @Mapper : 인터페이스 위에 달고, mybatis에서 사용할 인터페이스라는 것을 알림
* 서버 시작시 자동으로 객체가 생성됨
* @Param("속성명") 변수명 : sql 의 매개변수로 전달됨
*
* TODO : xml
* pageReq.size : 1 페이지당 개수
* pageReq.page : 현재 페이지 번호
* (oracle 12 버전 이상만 OFFSET 가능)
* OFFSET #{pageReq.page} * #{pageReq.size} ROWS FETCH FIRST #{pageReq.size} ROWS ONLY
* 예) (1 페이지당 개수)size = 10, 현재 페이지 번호(page) = 2
* 2 * 10 = 20 (db 건수 20개 건너뛰고)
* 10 10 (10 개를 화면에 출력하세요.)
* <p>
* ===========================================================
* DATE AUTHOR NOTE
* ———————————————————————————————
* 2023-10-12 L.DH 최초 생성
*/
@Mapper
public interface DeptDao {
/** 전체 조회 : 부서명 like 기능 있음 */
public List<Dept> findByDnameContaining(@Param("dname") String dname,
PageReq pageReq
);
/** 전체 테이블 개수 세기 함수 */
long countByDname(String dname);
}
Mybatis 작업 폴더 생성
Backend\03_MybatisExam\MybatisExam\src\main\resources\mappers
.xml OFFSET #{pageReq.page} * #{pageReq.size} ROWS FETCH FIRST #{pageReq.size} ROWS ONLY
pageReq.size : 1 페이지당 개수 pageReq.page : 현재 페이지 번호 (oracle 12 버전 이상만 OFFSET 가능)
OFFSET #{pageReq.page}#{pageReq.size} ROWS FETCH FIRST #{pageReq.size} ROWS ONLY 예)
(1 페이지당 개수)size = 10, 현재 페이지 번호(page) = 2
2 * 10 = 20 (db 건수 20개 건너뛰고) 10 10 (10 개를 화면에 출력)
더보기
<?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.example.mybatisexam.dao.DeptDao">
<select id="findByDnameContaining" parameterType="PageReq" resultType="Dept">
SELECT DNO
, DNAME
, LOC
, INSERT_TIME
, UPDATE_TIME
FROM TB_DEPT
WHERE DNAME LIKE '%' || #{dname} || '%'
OFFSET #{pageReq.page} * #{pageReq.size} ROWS FETCH FIRST #{pageReq.size} ROWS ONLY
</select>
<select id="countByDname" parameterType="String" resultType="long">
SELECT COUNT(dno)
FROM TB_DEPT
WHERE DNAME LIKE '%' || #{dname} || '%'
</select>
</mapper>
부서 서비스 클래스(업무 로직)
페이징 처리 로직
@Service
@Autowired
더보기
package com.example.mybatisexam.service.exam01;
import com.example.mybatisexam.dao.DeptDao;
import com.example.mybatisexam.model.common.PageReq;
import com.example.mybatisexam.model.common.PageRes;
import com.example.mybatisexam.model.vo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* packageName : com.example.mybatisexam.service.exam01
* fileName : DeptService
* author : L.DH
* date : 2023-10-12
* description : 전체 조회 : like 기능
* 요약 : 부서 서비스 클래스(업무 로직)
* <p>
* ===========================================================
* DATE AUTHOR NOTE
* ———————————————————————————————
* 2023-10-12 L.DH 최초 생성
*/
@Service
public class DeptService {
@Autowired
DeptDao deptDao; // db crud 함수들이 있는 클래스
/** dname like 함수 */
public PageRes<Dept> findByDnameContaining(String dname,
PageReq pageReq) {
// TODO : 전체 조회 (like 됨)
List<Dept> list = deptDao.findByDnameContaining(dname, pageReq);
// TODO : 페이징 처리 로직
// 1) 총 테이블 개수 :
long totalCount = deptDao.countByDname(dname);
// TODO : 생성자 페이지 결과 객체(PageRes)
PageRes pageRes = new PageRes(
list, // 검색 결과(부서) 배열
pageReq.getPage(), // 현재 페이지 번호
totalCount, // 총 테이블 건수
pageReq.getSize() // 1 페이지당 개수
);
return pageRes;
}
}
부서 컨트롤러 : jsp 연동 : @Controller
서비스 객체 가져오기
전체 조회 : dname like 기능
페이징 요청 객체에 정보 저장
전체 조회 함수 호출
jsp 정보전달(부서배열, 페이징정보)
※ 로그 출력 테스트 해보기
@Slf4j
@Controller
@RequestMapping
@Autowired
@RequestParam - url?변수=값&변수2=값2(쿼리스트링 방식)
@GetMapping
더보기
package com.example.mybatisexam.controller.exam01;
import com.example.mybatisexam.model.common.PageReq;
import com.example.mybatisexam.model.common.PageRes;
import com.example.mybatisexam.model.vo.Dept;
import com.example.mybatisexam.service.exam01.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* packageName : com.example.mybatisexam.controller.exam01
* fileName : DeptController
* author : L.DH
* date : 2023-10-12
* description : 전체 조회 : like 기능
* 요약 : 부서 컨트롤러 : jsp 연동 : @Controller
* <p>
* ===========================================================
* DATE AUTHOR NOTE
* ———————————————————————————————
* 2023-10-12 L.DH 최초 생성
*/
@Slf4j
@Controller
@RequestMapping("/exam01")
public class DeptController {
@Autowired
DeptService deptService; // 서비스 객체 가져오기
/** 전체 조회 : dname like 기능(+) */
// todo: @RequestParam - url?변수=값&변수2=값2(쿼리스트링 방식)
@GetMapping("/dept")
public String getDeptAll(
@RequestParam(defaultValue = "") String dname
, @RequestParam(defaultValue = "0") int page
, @RequestParam(defaultValue = "3") int size
, Model model
){
// todo: 페이징 요청 객체에 정보 저장
// page : 현재페이지 번호, size : 1 페이지당 개수
PageReq pageReq = new PageReq(page, size);
// todo: 전체 조회 함수 호출
PageRes<Dept> pageRes
= deptService.findByDnameContaining(dname, pageReq);
// todo: jsp 정보전달(부서배열, 페이징정보)
model.addAttribute("dept", pageRes.getContent()); // 부서배열
model.addAttribute("currentPage", pageRes.getNumber()); // 현재 페이지 번호
model.addAttribute("totalItems", pageRes.getTotalElements()); // 전체 테이블 건수
model.addAttribute("totalPages", pageRes.getTotalPages()); // 전체 페이지 개수
model.addAttribute("startPage", pageRes.getStartPage()); // 현재 시작 페이지 번호
model.addAttribute("endPage", pageRes.getEndPage()); // 현재 끝 페이지 번호
log.debug(model.toString()); // 로그 출력
return "exam01/dept/dept_all.jsp";
}
}
dept_all.jsp
form 안에 input 태그의 value 값들이 -> springboot 함수로 전달됨
startPage : 1부터 시작
currentPage : 0부터 시작
더보기
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<%-- header --%>
<jsp:include page="../../common/header.jsp"/>
<div class="container">
<%-- TODO: 검색어 시작 --%>
<%-- form 안에 input 태그의 value 값들이 -> springboot 함수로 전달됨--%>
<form class="row g-3 justify-content-center" action="/exam01/dept">
<div class="col-auto">
<%-- TODO: 부서명 라벨--%>
<label for="dname" class="visually-hidden">Dname</label>
<%-- TODO: 검색창--%>
<input type="text" class="form-control" id="dname" placeholder="dname" name="dname">
<%-- TODO: hidden(숨김) -> 백엔드로 날라감 page = 0, size = 3--%>
<input type="hidden" class="form-control" id="page" name="page" value="0">
<input type="hidden" class="form-control" id="size" name="size" value="3">
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary mb-3">Search</button>
</div>
</form>
<%-- TODO: 검색어 끝 --%>
<%-- TODO : 테이블 반복문 시작 --%>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">위치</th>
<th scope="col">등록일자</th>
<th scope="col">수정일자</th>
</tr>
</thead>
<tbody>
<c:forEach var="data" items="${dept}">
<tr>
<td>${data.dno}</td>
<td>${data.dname}</td>
<td>${data.loc}</td>
<td>${data.insertTime}</td>
<td>${data.updateTime}</td>
</tr>
</c:forEach>
</tbody>
</table>
<%-- TODO : 테이블 반복문 끝 --%>
<%-- TODO : 페이지 번호 시작 --%>
<div class="d-flex justify-content-center">
<ul class="pagination">
<%-- TODO : 첫 페이지 번호 --%>
<%-- TODO : startPage : 1부터 시작 --%>
<%-- TODO : currentPage : 0부터 시작 --%>
<li class="page-item ${(startPage==1)? 'disabled': ''}">
<a class="page-link" href="/exam01/dept?page=${startPage-2}&size=${3}">Previous</a>
</li>
<%-- TODO : 실제 페이지 번호들(반복) --%>
<%-- 사용법 : <c:forEach var="data" begin="시작값" end="끝값">반복문</c:forEach>--%>
<c:forEach var="data" begin="${startPage}" end="${endPage}">
<li class="page-item ${(currentPage+1==data)? 'active': ''}">
<a class="page-link" href="/exam01/dept?page=${data-1}&size=${3}">
${data}
</a>
</li>
</c:forEach>
<%-- TODO : 끝 페이지 번호--%>
<li class="page-item ${(endPage==totalPages)? 'disabled': ''}">
<a class="page-link" href="/exam01/dept?page=${endPage}&size=${3}">Next</a>
</li>
</ul>
<%-- TODO : 페이지 번호 끝 --%>
</div>
<script>
let obj = "${dept}";
let obj2 = "${currentPage}";
let obj3 = "${totalItems}";
let obj4 = "${totalPages}";
let obj5 = "${startPage}";
let obj6 = "${endPage}";
console.log("obj", obj);
console.log("obj2", obj2);
console.log("obj3", obj3);
console.log("obj4", obj4);
console.log("obj5", obj5);
console.log("obj6", obj6);
</script>
<%-- footer --%>
<jsp:include page="../../common/footer.jsp"/>
</div>
</body>
</html>
'Spring Boot' 카테고리의 다른 글
[SpringBoot] 데이터베이스(SQL&Docker) 활용한 저장 함수 (0) | 2023.10.13 |
---|---|
[SpringBoot] 데이터베이스(SQL&Docker) 활용한 상세 조회 (0) | 2023.10.13 |
[SpringBoot] CRUD (1) | 2023.10.10 |
[SpringBoot] 로그백, 로깅 라이브러리 logback , log4jdbc 설정 (0) | 2023.10.06 |
[SpringBoot] 데이터를 입력받아(insert) 화면에 출력하기 (0) | 2023.10.06 |