일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 객체지향
- 생활코딩
- Java
- FastAPI
- servlet
- python
- Error
- ddit
- 자바
- 자바문제
- ibatis
- Mac
- JDBC
- nodejs
- 컬렉션프레임워크
- 배열
- 이클립스
- 반복문
- API
- spring
- html
- Oracle
- 대덕인재개발원
- 맥
- crud
- Android
- pyqt
- 단축키
- jsp
- Homebrew
- Today
- Total
romworld
Spring 28 - adminlte3을 사용한 CRUD [setInterval(), datatables 사용법, ID 자동완성] 본문
Spring 28 - adminlte3을 사용한 CRUD [setInterval(), datatables 사용법, ID 자동완성]
inderrom 2023. 2. 16. 17:40현재시각 출력
- 비동기방식(json)
- ajax(Acynchronous Javascript And XML)
- setInterval() 함수 사용
setInterval()
- 웹페이지의 특정 부분을 주기적으로 업데이트해줘야 하거나 어떤 API로부터 변경된 데이터를 주기적으로 받아와야 하는 경우 사용
- 어떤 코드를 일정한 시간 간격을 두고 반복해서 실행하고 싶을 때 사용
- setTimeout()함수와 대동소이.
- 첫번째 인자로 실행할 코드를 담고 있는 함수를 받음
- 두번째 인자로 반복 주기를 밀리초(ms) 단위로 받음
<WelcomeController.java>
package kr.or.ddit.controller;
import java.util.Date;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class WelcomeController {
// 요청URI : /home
@GetMapping("/home")
public String home(Model model) {
String CT = getCurrentTime();
model.addAttribute("greeting", "Welcome to BookMarket");
model.addAttribute("strapline", "Welcome to Web Shopping Mall!");
model.addAttribute("CT", CT);
//forwarding
// Views/welcome.jsp
return "welcome";
}
/*
*/
//현재시각을 json 데이터로 리턴
@ResponseBody
@GetMapping("/getCurrentTime")
public String getCurrentTime() {
Date day = new Date();
String am_pm;
int hour = day.getHours();
int minute = day.getMinutes();
int second = day.getSeconds();
if(hour / 12 == 0) {
am_pm = "AM";
}else {
am_pm = "PM";
hour = hour - 12;
}
String CT = hour + " : " + minute + " : " +second + " " + am_pm;
return CT;
}
}
<welcome.jsp>
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
/* setInterval()
- 웹페이지의 특정 부분을 주기적으로 업데이트해줘야 하거나
어떤 API로부터 변경된 데이터를 주기적으로 받아와야 하는 경우 사용
- 어떤 코드를 일정한 시간 간격을 두고 반복해서 실행하고 싶을 때 사용
- setTimeout()함수와 대동소이.
- 첫번째 인자로 실행할 코드를 담고 있는 함수를 받음
- 두번째 인자로 반복 주기를 밀리초(ms) 단위로 받음
*/
// setInterval(()=>console.log(new Date()),1000);
//0과 9 사이의 수를 무작위로 생성하여 3초마다 출력(floor : 소수부는 버림)
// let intervalId =
// setInterval(()=>console.log(Math.floor(Math.random()*10)),3000);
//메모리 누수 방지
// clearInterval(intervalId);
$(function(){
// 1초에 한 번씩 pCt요소의 text를 현재시각으로 변경해보자
// ajax(Acynchronous Javascript And XML)
// processType:false, : let f = new FormData();
// contentType : 보내는 타입
// data : 보내는 데이터
// dataType : "json" 응답데이터타입 (Controller에서 String에서 리턴 시 생략)
setInterval(function(){
$.ajax({
url:"/getCurrentTime",
type:"get",
success:function(res){
console.log(" 보낸당")
//.html() : 새로고침
$("#pCt").html(res);
}
});
}, 1000)
});
</script>
<title>도서관리시스템</title>
</head>
<body>
<h1>${greeting}</h1>
<p>${strapline}</p>
<p id="pCt">${CT}</p>
</body>
</html>
PRODUCT 테이블 생성
*SQL DEVELOPER
CREATE TABLE PRODUCT(
PRODUCT_ID VARCHAR2(10),
PNAME VARCHAR2(150),
UNIT_PRICE NUMBER,
DESCRIPTION VARCHAR2(4000),
MANUFACTURER VARCHAR2(60),
CATEGORY VARCHAR2(60),
UNITS_IN_STOCK NUMBER,
CONDITION VARCHAR2(60),
FILENAME VARCHAR2(1000),
QUANTITY NUMBER,
CONSTRAINT PK_PRODUCT PRIMARY KEY(PRODUCT_ID)
);
<ProductVO.java>
package kr.or.ddit.vo;
import lombok.Data;
@Data
public class ProductVO {
private String productId;
private String pname;
private int unitPrice;
private String description;
private String manufacturer;
private String category;
private int unitsInStock;
private String condition;
private String filename;
private int quantity;
}
데이터 INSERT
<product._SQL.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">
<!-- namespace : xml 파일이 여러개일 수 있으므로
이를 구별하기 위한 식별 용도로 사용 -->
<mapper namespace="kr.or.ddit.mapper.ProductMapper">
<!--
제품 목록
파라미터타입 : x
리턴타입 : productVO
-->
<select id="list" resultType="productVO">
SELECT PRODUCT_ID, PNAME, UNIT_PRICE, DESCRIPTION, MANUFACTURER
, CATEGORY, UNITS_IN_STOCK, CONDITION, FILENAME, QUANTITY
FROM PRODUCT
ORDER BY PRODUCT_ID
</select>
</mapper>
<ProductMapper.java>
package kr.or.ddit.mapper;
import java.util.List;
import kr.or.ddit.vo.ProductVO;
public interface ProductMapper {
// 제품 목록
public List<ProductVO> list();
}
<mybatisAlias.xml>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--
[마이바티스] 스프링에서 "_"를 사용한 컬럼명을 사용 시(BOOK 테이블의 BOOK_ID)
카멜케이스로 읽어줌(bookId)
ex) 테이블 컬럼명이 member_id인 경우 jsp화면단에서 이 값을 사용 시 memberId로 사용
-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 자주 사용하는 타입의 별칭을 세팅 -->
<typeAliases>
<typeAlias type="kr.or.ddit.vo.ProductVO" alias="productVO" />
</typeAliases>
</configuration>
<ProductService.java>
package kr.or.ddit.service;
import java.util.List;
import kr.or.ddit.vo.ProductVO;
public interface ProductService {
// 제품목록
public List<ProductVO> list();
}
<ProductServiceImpl.java>
package kr.or.ddit.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import kr.or.ddit.mapper.ProductMapper;
import kr.or.ddit.service.ProductService;
import kr.or.ddit.vo.ProductVO;
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
ProductMapper productMapper;
// 제품목록
@Override
public List<ProductVO> list() {
return productMapper.list();
}
}
<ProductController.java>
package kr.or.ddit.controller;
import java.util.List;
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 kr.or.ddit.service.ProductService;
import kr.or.ddit.vo.ProductVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequestMapping("/product")
@Controller
public class ProductController {
@Autowired
ProductService productService;
@GetMapping("/list")
public String list(Model model){
List<ProductVO> productVOList = this.productService.list();
log.info("productVOList : " + productVOList);
model.addAttribute("pvo", productVOList);
//forwarding. product폴더의 list.jsp를 리턴
return "product/list";
}
}
list
부트스트랩을 가져오자!
PDF 파일저장 기능을 다 사용하려면
tiles도 수정해주자
datatables 사용하기
1. tiles의 index.jsp의 상단에 추가함(css)
<!-- DataTables -->
<link rel="stylesheet" href="/resources/AdminLTE/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css">
<link rel="stylesheet" href="/resources/AdminLTE/plugins/datatables-responsive/css/responsive.bootstrap4.min.css">
<link rel="stylesheet" href="/resources/AdminLTE/plugins/datatables-buttons/css/buttons.bootstrap4.min.css">
2. tiles의 index.jsp의 하단에 추가함(js)
<!-- DataTables & Plugins -->
<script src="/resources/AdminLTE/plugins/datatables/jquery.dataTables.min.js"></script>
<script src="/resources/AdminLTE/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js"></script>
<script src="/resources/AdminLTE/plugins/datatables-responsive/js/dataTables.responsive.min.js"></script>
<script src="/resources/AdminLTE/plugins/datatables-responsive/js/responsive.bootstrap4.min.js"></script>
<script src="/resources/AdminLTE/plugins/datatables-buttons/js/dataTables.buttons.min.js"></script>
<script src="/resources/AdminLTE/plugins/datatables-buttons/js/buttons.bootstrap4.min.js"></script>
<script src="/resources/AdminLTE/plugins/jszip/jszip.min.js"></script>
<script src="/resources/AdminLTE/plugins/pdfmake/pdfmake.min.js"></script>
<script src="/resources/AdminLTE/plugins/pdfmake/vfs_fonts.js"></script>
<script src="/resources/AdminLTE/plugins/datatables-buttons/js/buttons.html5.min.js"></script>
<script src="/resources/AdminLTE/plugins/datatables-buttons/js/buttons.print.min.js"></script>
<script src="/resources/AdminLTE/plugins/datatables-buttons/js/buttons.colVis.min.js"></script>
3. list.jsp에 추가함
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<!-- jQuery -->
<script src="/resources/js/jquery-3.6.0.js"></script>
<script src="/resources/js/jquery-3.6.3.min.js"></script>
<div class="card">
<div class="card-header">
<h3 class="card-title">목록</h3>
</div>
<div class="card-body">
<div id="example1_wrapper" class="dataTables_wrapper dt-bootstrap4">
<div class="row">
<div class="col-sm-12">
<table id="example1" class="table table-bordered table-striped dataTable dtr-inline" aria-describedby="example1_info">
<thead>
<tr>
<th onclick="event.cancelBubble=true">상품번호</th>
<th onclick="event.cancelBubble=true">카테고리</th>
<th onclick="event.cancelBubble=true">상품명</th>
<th onclick="event.cancelBubble=true">제조사</th>
<th onclick="event.cancelBubble=true">가격</th>
<th onclick="event.cancelBubble=true">상태</th>
<th onclick="event.cancelBubble=true">재고</th>
</tr>
</thead>
<tbody>
<c:forEach var="pvo" items="${pvo}" varStatus="stat">
<tr>
<td>${pvo.productId}</td>
<td>${pvo.category}</td>
<td>${pvo.pname}</td>
<td>${pvo.manufacturer}</td>
<td style="text-align: right;"><fmt:formatNumber type="number" maxFractionDigits="3" value="${pvo.unitPrice}" />원</td>
<td>${pvo.condition}</td>
<td>${pvo.unitsInStock}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
$(function () {
$("#example1").DataTable({
"responsive": true, "lengthChange": false, "autoWidth": false,
"buttons": ["copy", "csv", "excel", "pdf", "print", "colvis"]
}).buttons().container().appendTo('#example1_wrapper .col-md-6:eq(0)');
});
</script>
tiles 의 <index.jsp>
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<!DOCTYPE html>
<html class>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AdminLTE 3 | Dashboard</title>
<!-- Google Font: Source Sans Pro -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
<!-- Font Awesome -->
<link rel="stylesheet" href="/resources/adminlte3/plugins/fontawesome-free/css/all.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<!-- Tempusdominus Bootstrap 4 -->
<link rel="stylesheet" href="/resources/adminlte3/plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css">
<!-- iCheck -->
<link rel="stylesheet" href="/resources/adminlte3/plugins/icheck-bootstrap/icheck-bootstrap.min.css">
<!-- JQVMap -->
<link rel="stylesheet" href="/resources/adminlte3/plugins/jqvmap/jqvmap.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="/resources/adminlte3/dist/css/adminlte.min.css">
<!-- overlayScrollbars -->
<link rel="stylesheet" href="/resources/adminlte3/plugins/overlayScrollbars/css/OverlayScrollbars.min.css">
<!-- Daterange picker -->
<link rel="stylesheet" href="/resources/adminlte3/plugins/daterangepicker/daterangepicker.css">
<!-- summernote -->
<link rel="stylesheet" href="/resources/adminlte3/plugins/summernote/summernote-bs4.min.css">
<!-- DataTables -->
<link rel="stylesheet" href="/resources/adminlte3/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css">
<link rel="stylesheet" href="/resources/adminlte3/plugins/datatables-responsive/css/responsive.bootstrap4.min.css">
<link rel="stylesheet" href="/resources/adminlte3/plugins/datatables-buttons/css/buttons.bootstrap4.min.css">
<!-- jQuery -->
<script src="/resources/js/jquery-3.6.0.js"></script>
</head>
<body class="hold-transition sidebar-mini layout-fixed">
<div class="wrapper">
<!-- Preloader -->
<div class="preloader flex-column justify-content-center align-items-center">
<img class="animation__shake" src="/resources/adminlte3/dist/img/AdminLTELogo.png" alt="AdminLTELogo" height="60" width="60">
</div>
<!---------------- Navbar header.jsp 시작 -------------->
<tiles:insertAttribute name="header" />
<!---------------- /.navbar header.jsp 끝 -------------->
<!-- Main Sidebar Container aside.jsp 시작 -->
<tiles:insertAttribute name="aside" />
<!-- Main Sidebar Container aside.jsp 끝 -->
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0">Dashboard</h1>
</div><!-- /.col -->
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item active">Dashboard v1</li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<!-- Main content -->
<section class="content">
<div class="container-fluid">
<!-- body 시작 -->
<tiles:insertAttribute name="body" />
<!-- body 끝 -->
<!-- /.row (main row) -->
</div><!-- /.container-fluid -->
</section>
<!-- /.content -->
</div>
<!-- /.content-wrapper -->
<!------------- footer.jsp 시작 ------------->
<tiles:insertAttribute name="footer" />
<!------------- footer.jsp 끝 ------------->
<!-- Control Sidebar -->
<aside class="control-sidebar control-sidebar-dark">
<!-- Control sidebar content goes here -->
</aside>
<!-- /.control-sidebar -->
</div>
<!-- ./wrapper -->
<!-- jQuery -->
<script src="/resources/adminlte3/plugins/jquery/jquery.min.js"></script>
<!-- jQuery UI 1.11.4 -->
<script src="/resources/adminlte3/plugins/jquery-ui/jquery-ui.min.js"></script>
<!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
<script>
$.widget.bridge('uibutton', $.ui.button)
</script>
<!-- Bootstrap 4 -->
<script src="/resources/adminlte3/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- ChartJS -->
<script src="/resources/adminlte3/plugins/chart.js/Chart.min.js"></script>
<!-- Sparkline -->
<script src="/resources/adminlte3/plugins/sparklines/sparkline.js"></script>
<!-- JQVMap -->
<script src="/resources/adminlte3/plugins/jqvmap/jquery.vmap.min.js"></script>
<script src="/resources/adminlte3/plugins/jqvmap/maps/jquery.vmap.usa.js"></script>
<!-- jQuery Knob Chart -->
<script src="/resources/adminlte3/plugins/jquery-knob/jquery.knob.min.js"></script>
<!-- daterangepicker -->
<script src="/resources/adminlte3/plugins/moment/moment.min.js"></script>
<script src="/resources/adminlte3/plugins/daterangepicker/daterangepicker.js"></script>
<!-- Tempusdominus Bootstrap 4 -->
<script src="/resources/adminlte3/plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>
<!-- Summernote -->
<script src="/resources/adminlte3/plugins/summernote/summernote-bs4.min.js"></script>
<!-- overlayScrollbars -->
<script src="/resources/adminlte3/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script>
<!-- AdminLTE App -->
<script src="/resources/adminlte3/dist/js/adminlte.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="/resources/adminlte3/dist/js/demo.js"></script>
<!-- AdminLTE dashboard demo (This is only for demo purposes) -->
<script src="/resources/adminlte3/dist/js/pages/dashboard.js"></script>
<!-- DataTables & Plugins -->
<script src="/resources/adminlte3/plugins/datatables/jquery.dataTables.min.js"></script>
<script src="/resources/adminlte3/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js"></script>
<script src="/resources/adminlte3/plugins/datatables-responsive/js/dataTables.responsive.min.js"></script>
<script src="/resources/adminlte3/plugins/datatables-responsive/js/responsive.bootstrap4.min.js"></script>
<script src="/resources/adminlte3/plugins/datatables-buttons/js/dataTables.buttons.min.js"></script>
<script src="/resources/adminlte3/plugins/datatables-buttons/js/buttons.bootstrap4.min.js"></script>
<script src="/resources/adminlte3/plugins/jszip/jszip.min.js"></script>
<script src="/resources/adminlte3/plugins/pdfmake/pdfmake.min.js"></script>
<script src="/resources/adminlte3/plugins/pdfmake/vfs_fonts.js"></script>
<script src="/resources/adminlte3/plugins/datatables-buttons/js/buttons.html5.min.js"></script>
<script src="/resources/adminlte3/plugins/datatables-buttons/js/buttons.print.min.js"></script>
<script src="/resources/adminlte3/plugins/datatables-buttons/js/buttons.colVis.min.js"></script>
</body>
</html>
<list.jsp>
- product폴더를 만들고 list 생성
테이블 표 가져오기
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<!-- jQuery -->
<script src="/resources/js/jquery-3.6.0.js"></script>
<script src="/resources/js/jquery-3.6.3.min.js"></script>
<div class="card">
<div class="card-header">
<h3 class="card-title">목록</h3>
</div>
<div class="card-body">
<div id="example1_wrapper" class="dataTables_wrapper dt-bootstrap4">
<div class="row">
<div class="col-sm-12">
<table id="example1" class="table table-bordered table-striped dataTable dtr-inline" aria-describedby="example1_info">
<thead>
<tr>
<th onclick="event.cancelBubble=true">상품번호</th>
<th onclick="event.cancelBubble=true">카테고리</th>
<th onclick="event.cancelBubble=true">상품명</th>
<th onclick="event.cancelBubble=true">제조사</th>
<th onclick="event.cancelBubble=true">가격</th>
<th onclick="event.cancelBubble=true">상태</th>
<th onclick="event.cancelBubble=true">재고</th>
</tr>
</thead>
<tbody>
<c:forEach var="pvo" items="${pvo}" varStatus="stat">
<tr>
<td>${pvo.productId}</td>
<td>${pvo.category}</td>
<td>${pvo.pname}</td>
<td>${pvo.manufacturer}</td>
<td style="text-align: right;"><fmt:formatNumber type="number" maxFractionDigits="3" value="${pvo.unitPrice}" />원</td>
<td>${pvo.condition}</td>
<td>${pvo.unitsInStock}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
$(function () {
$("#example1").DataTable({
"responsive": true, "lengthChange": false, "autoWidth": false,
"buttons": ["copy", "csv", "excel", "pdf", "print", "colvis"]
}).buttons().container().appendTo('#example1_wrapper .col-md-6:eq(0)');
});
</script>
CREATE
<ProductCotroller.java>
package kr.or.ddit.controller;
import java.util.List;
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 kr.or.ddit.service.ProductService;
import kr.or.ddit.vo.ProductVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequestMapping("/product")
@Controller
public class ProductController {
@Autowired
ProductService productService;
@GetMapping("/list")
public String list(Model model){
List<ProductVO> productVOList = this.productService.list();
log.info("productVOList : " + productVOList);
model.addAttribute("pvo", productVOList);
//forwarding. product폴더의 list.jsp를 리턴
return "product/list";
}
// 요청 URI : /product/create
//요청방식 : get
@GetMapping("/create")
public String create() {
//forwarding
return "product/create";
}
}
<list.jsp>
- <a href="/product/create" class="btn btn-primary" style="float:right;">등록</a>
- 클래스가 버튼 타입이라 a링크 줘도 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<!-- jQuery -->
<script src="/resources/js/jquery-3.6.0.js"></script>
<script src="/resources/js/jquery-3.6.3.min.js"></script>
<div class="card">
<div class="card-header" style="width:100%;">
<div style="width:30%;float:left;">
<h3 class="card-title">목록</h3>
</div>
<div style="width:70%;float:right;">
<!-- 등록 버튼 클릭 시 /product/create를 get방식으로 요청
product폴더의 create.jsp를 forwarding처리해보자
create.jsp는 https://adminlte.io/themes/v3/pages/forms/advanced.html를 활용해보자
-->
<a href="/product/create" class="btn btn-primary" style="float:right;">등록</a>
</div>
</div>
<div class="card-body">
<div id="example1_wrapper" class="dataTables_wrapper dt-bootstrap4">
<div class="row">
<div class="col-sm-12">
<table id="example1" class="table table-bordered table-striped dataTable dtr-inline" aria-describedby="example1_info">
<thead>
<tr>
<th onclick="event.cancelBubble=true">상품번호</th>
<th onclick="event.cancelBubble=true">카테고리</th>
<th onclick="event.cancelBubble=true">상품명</th>
<th onclick="event.cancelBubble=true">제조사</th>
<th onclick="event.cancelBubble=true">가격</th>
<th onclick="event.cancelBubble=true">상태</th>
<th onclick="event.cancelBubble=true">재고</th>
</tr>
</thead>
<tbody>
<c:forEach var="pvo" items="${pvo}" varStatus="stat">
<tr>
<td>${pvo.productId}</td>
<td>${pvo.category}</td>
<td>${pvo.pname}</td>
<td>${pvo.manufacturer}</td>
<td style="text-align: right;"><fmt:formatNumber type="number" maxFractionDigits="3" value="${pvo.unitPrice}" />원</td>
<td>${pvo.condition}</td>
<td>${pvo.unitsInStock}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
$(function () {
// Datatables 설정
$("#example1").DataTable({
"responsive": true, "lengthChange": false, "autoWidth": false,
"buttons": ["copy", "csv", "excel", "pdf", "print", "colvis"]
}).buttons().container().appendTo('#example1_wrapper .col-md-6:eq(0)');
// 동록 버튼 눌렀을 때
});
</script>
<create.jsp>
- product폴더에 추가
- ckeditor 이용함
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<script type="text/javascript" src="/resources/ckeditor/ckeditor.js"></script>
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">상품 등록</h3>
</div>
<!--
요청URI : /product/create
요청방식 : post
메소드명 : createPost
PRODUCT 테이블에 입력해보자
-->
<form name="frm" action="/product/create" method="post">
<div class="card-body">
<div class="form-group">
<label for="productId">상품아이디</label> <input
type="text" name="productId" class="form-control" id="productId"
placeholder="상품아이디를 입력해주세요" required />
</div>
<div class="form-group">
<label for="pname">상품명</label> <input
type="text" name="pname" class="form-control" id="pname"
placeholder="상품명을 입력해주세요" required />
</div>
<div class="form-group">
<label for="unitPrice">판매 가격</label> <input
type="number" name="unitPrice" class="form-control" id="unitPrice"
placeholder="판매 가격을 입력해주세요" required />
</div>
<div class="form-group">
<label for="description">상품 설명</label>
<textarea cols="30" rows="5" name="description" class="form-control" id="description"
placeholder="판매 가격을 입력해주세요"></textarea>
</div>
<div class="form-group">
<label for="manufacturer">제조사</label> <input
type="text" name="manufacturer" class="form-control" id="manufacturer"
placeholder="제조사를 입력해주세요" required />
</div>
<div class="form-group">
<label for="category">카테고리</label> <input
type="text" name="category" class="form-control" id="category"
placeholder="카테고리를 입력해주세요" required />
</div>
<div class="form-group">
<label for="unitsInStock">재고수</label> <input
type="number" name="unitsInStock" class="form-control" id="unitsInStock"
placeholder="재고수를 입력해주세요" value="0" />
</div>
<div class="form-group">
<label for="category">상태</label>
<div class="col-sm-6">
<div class="form-group">
<select id="condition" name="condition" class="form-control">
<option value="New">New</option>
<option value="Old">Old</option>
<option value="Refurbished">Refurbished</option>
</select>
</div>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">등록</button>
</div>
<!-- Cross Site Request Forgery -->
<sec:csrfInput/>
</form>
</div>
<script type="text/javascript">
CKEDITOR.replace("description");
</script>
<ProductCotroller.java>
- createPost 매서드생성
package kr.or.ddit.controller;
import java.util.List;
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.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import kr.or.ddit.service.ProductService;
import kr.or.ddit.vo.ProductVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequestMapping("/product")
@Controller
public class ProductController {
@Autowired
ProductService productService;
@GetMapping("/list")
public String list(Model model){
List<ProductVO> productVOList = this.productService.list();
log.info("productVOList : " + productVOList);
model.addAttribute("pvo", productVOList);
//forwarding. product폴더의 list.jsp를 리턴
return "product/list";
}
//요청URI : /product/create
//요청방식 : get
@GetMapping("/create")
public String create() {
//fowarding
//product폴더의 create.jsp를 forwarding
return "product/create";
}
@PostMapping("/create")
public String createPost(@ModelAttribute ProductVO productVO) {
/*
productVO : ProductVO(productId=P1237, pname=Galaxy Note 20, unitPrice=1000
, description=<p>상품 설명</p>
, manufacturer=Samsung, category=Smart Phone, unitsInStock=1000, condition=New
, filename=null, quantity=0, productImage=null)
*/
log.info("productVO : " + productVO);
int result = this.productService.createPost(productVO);
log.info("result : " + result);
if(result > 0) { // 등록 성공
//redirect : URI 재요청
return "redirect:/product/list";
}else { //등록 실패
return "redirect:/product/create";
}
}
}
<product_SQL.xml>
<!-- 상품 등록
productVO
생략(int)
-->
<insert id="createPost" parameterType="productVO">
<selectKey resultType="String" order="BEFORE" keyProperty="productId">
SELECT SUBSTR(MAX(PRODUCT_ID),1,1)
|| (SUBSTR(MAX(PRODUCT_ID),2) + 1)
FROM PRODUCT
</selectKey>
INSERT INTO PRODUCT(PRODUCT_ID, PNAME, UNIT_PRICE, DESCRIPTION, MANUFACTURER
, CATEGORY, UNITS_IN_STOCK, CONDITION)
VALUES(#{productId},#{pname},#{unitPrice},#{description},#{manufacturer}
,#{category},#{unitsInStock},#{condition})
</insert>
<ProductMapper.xml>
// 제품 등록. insert, update, delete 당연히 int로 리턴
public int createPost(ProductVO productVO);
<ProductService.java>
//제품 등록
public int createPost(ProductVO productVO);
<ProductServiceImpl.java>
// 제품 등록
@Override
public int createPost(ProductVO productVO) {
return this.productMapper.createPost(productVO);
상품아이디 자동생성, readonly
<ProductController.java>
// 상품아이디 자동생성
//json으로 응답 시 ResponseBody
//1)String
//2)List<..VO>, ..VO, Map<String,String>,List<Map<String,String>> : dataType="json"
@ResponseBody
@PostMapping("/getproductId")
public String getproductId() {
String productId = this.productService.getproductId();
//dataType="json" 생략
//List<..VO> =>$.each(result,function(index,data)
//result : List<ProductVO>
//data : ProductVO
//index : 0부터1씩 증가
return productId;
}
<product_SQL.xml>
<!-- 상품아이디 자동 생성 -->
<select id="getproductId" resultType="String">
SELECT SUBSTR(MAX(PRODUCT_ID),1,1)
|| (SUBSTR(MAX(PRODUCT_ID),2) + 1)
FROM PRODUCT
</select>
<ProductService.java>
// 상품아이디 자동생성
public String getproductId();
<ProductServiceImpl.java>
// 상품 아이디 자동 생성
@Override
public String getproductId() {
return this.productMapper.getproductId();
}
<create.jsp>
- ajax를 써줄 때 안에 꼭 같이 써주자!
beforeSend : function(xhr) { // 데이터 전송 전 헤더에 csrf값 설정
xhr.setRequestHeader("${_csrf.headerName}", "${_csrf.token}");
},
- 아이디 자동생성
- readonly
- button 태그 사용
- 제이쿼리를 쓰는 경우에 꼭 스크립트 등록
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<script type="text/javascript" src="/resources/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript">
$(function(){
$("#btnAuto").on("click",function(){
$.ajax({
url:"/product/getproductId",
type:"post",
beforeSend : function(xhr) { // 데이터 전송 전 헤더에 csrf값 설정
xhr.setRequestHeader("${_csrf.headerName}", "${_csrf.token}");
},
success:function(res){
$("input[name='productId']").val(res);
}
});
});
})
</script>
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">상품 등록</h3>
</div>
<!--
요청URI : /product/create
요청방식 : post
메소드명 : createPost
PRODUCT 테이블에 입력해보자
-->
<form name="frm" action="/product/create" method="post">
<div class="card-body">
<div class="form-group">
<label for="productId">상품아이디</label> <input
type="text" name="productId" class="form-control" id="productId"
placeholder="상품아이디를 입력해주세요" required readonly />
<button type="button" id="btnAuto" class="btn bg-gradient-primary">자동생성</button>
</div>
<div class="form-group">
<label for="pname">상품명</label> <input
type="text" name="pname" class="form-control" id="pname"
placeholder="상품명을 입력해주세요" required />
</div>
<div class="form-group">
<label for="unitPrice">판매 가격</label> <input
type="number" name="unitPrice" class="form-control" id="unitPrice"
placeholder="판매 가격을 입력해주세요" required />
</div>
<div class="form-group">
<label for="description">상품 설명</label>
<textarea cols="30" rows="5" name="description" class="form-control" id="description"
placeholder="판매 가격을 입력해주세요"></textarea>
</div>
<div class="form-group">
<label for="manufacturer">제조사</label> <input
type="text" name="manufacturer" class="form-control" id="manufacturer"
placeholder="제조사를 입력해주세요" required />
</div>
<div class="form-group">
<label for="category">카테고리</label> <input
type="text" name="category" class="form-control" id="category"
placeholder="카테고리를 입력해주세요" required />
</div>
<div class="form-group">
<label for="unitsInStock">재고수</label> <input
type="number" name="unitsInStock" class="form-control" id="unitsInStock"
placeholder="재고수를 입력해주세요" value="0" />
</div>
<div class="form-group">
<label for="category">상태</label>
<div class="col-sm-6">
<div class="form-group">
<select id="condition" name="condition" class="form-control">
<option value="New">New</option>
<option value="Old">Old</option>
<option value="Refurbished">Refurbished</option>
</select>
</div>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">등록</button>
</div>
<!-- Cross Site Request Forgery -->
<sec:csrfInput/>
</form>
</div>
<script type="text/javascript">
CKEDITOR.replace("description");
</script>
'Spring' 카테고리의 다른 글
Spring 30 - adminlte3을 사용한 CRUD (파일업로드) (0) | 2023.02.17 |
---|---|
Spring 29 - adminlte3을 사용한 CRUD (상세보기, 수정, 삭제,MERGE INTO) (0) | 2023.02.17 |
Spring 27 - 전자정부프레임워크와 부트스트랩 사용해보자(adminlte3) (0) | 2023.02.15 |
Spring 26 - security (애너테이션, PL/SQL&패키지를 통한 비밀번호 암호화/복호화 , 상관관계 서브쿼리) (0) | 2023.02.15 |
Spring 24 - security (테이블을 생성해 실습해보자 DB사용), LEFT OUTER JOIN, 구글 카멜변환, 로그인, 로그아웃 (0) | 2023.02.14 |