INTP의 멋대로 개발 세상

[📚상품 구매 사이트 3단계] 판매자 서버 만들기 - MySQL 포트 연결하기 본문

KDT 풀스택 국비 과정/파이널 프로젝트(미니)

[📚상품 구매 사이트 3단계] 판매자 서버 만들기 - MySQL 포트 연결하기

인팁구름 2023. 4. 24. 16:04

⏬ 3단계 판매자 서버 전체 깃허브 ⏬

 

GitHub - JungminK1m/Springboot-Product-Study-V3-Seller

Contribute to JungminK1m/Springboot-Product-Study-V3-Seller development by creating an account on GitHub.

github.com

⏬ 판매자 서버 참고 코드 ⏬
연습(?)단계였던 1,2단계 코드를 가져와 사용했다.

 

GitHub - JungminK1m/Springboot-Product-Study-V1-V2

Contribute to JungminK1m/Springboot-Product-Study-V1-V2 development by creating an account on GitHub.

github.com

 

이번엔 판매자 페이지를 만들어 보자.

MySQL로 DB를 연동하는 방법을 사용했기 때문에,

한 프로젝트 안에 구매자/판매자가 나누어 지는 게 아니라

별 개의 프로젝트에 다른 포트번호를 사용한다.

 

구매자 서버와 다르게 로그인, 회원가입 기능은 존재하지 않는 대신,

상품등록, 수정, 삭제 기능이 있다.

1,2단계에서 구현했던 페이지를 MySQL로 연결해주는 작업만 하였다

포트번호가 달라서 두 개의 서버 둘 다 동시에 실행 가능하다!

 

구매자 서버와 헤더가 다르다.

 

구매자 서버와 달리 상품을 수정하고 삭제하는 기능이 있다.

 

상품 등록 페이지 / 상품 수정 페이지

 

 

 

 

application.yml

판매자 서버와 같이 MySQL 연결을 위한 의존성과 yml 파일을 세팅해 준다.

중요한 건 포트 번호!!!! 구매자 서버는 8000번 포트, 판매자 서버는 8080번 포트이다

server:
  port: 8080
  servlet:
    encoding:
      charset: utf-8
      force: true
 
spring:
  mvc:
    view:
      prefix: /WEB-INF/view/
      suffix: .jsp 
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/data?serverTimezone=UTC&characterEncoding=UTF-8
    username: root
    password: 1234
  output:
    ansi:
      enabled: always

mybatis:
  mapper-locations:
  - classpath:mapper/**.xml
  configuration:
    map-underscore-to-camel-case: true

 

build.gradle

dependencies 부분만 복사해서 붙여넣으면 된다!

dependencies {
	testImplementation group: 'org.mybatis.spring.boot', name: 'mybatis-spring-boot-starter-test', version: '2.2.2'
	implementation 'javax.servlet:jstl'
	implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.0'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	implementation 'mysql:mysql-connector-java:8.0.28'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

 

product.java

package shop.mtcoding.productapp_seller.model;

import java.sql.Timestamp;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Product {

    private Integer productId;
    private String productName;
    private Integer productPrice;
    private Integer productQty;
    private Timestamp createdAt;

}

 

productRepository.java

package shop.mtcoding.productapp_seller.model;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface ProductRepository {

    public List<Product> findAll();

    public Product findById(Integer id);

    public int insert(Product product);

    // @Param으로 받는 방법
    // public int update(@Param("id") Integer id, @Param("name") String name,
    // @Param("price") Integer price,
    // @Param("qty") Integer qty);

    // Product 객체로 받는 방법
    public int update(Product product);

    // ajax 중복체크를 위한 메서드
    public Product findByName(String name);

    public int deleteById(Integer id);

}

 

 

product.xml

MySQL과 연동되어 있기 때문에, H2-Console을 사용할 때와 달리 테이블명 뒤에 _tb 같은 걸 붙여주지 않고

SQL에서 쓰는 테이블명 그대로 써도 오류가 나지 않는다.

<?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="shop.mtcoding.productapp_seller.model.ProductRepository">

	<select id = "findAll" resultType = "shop.mtcoding.productapp_seller.model.Product">
        select * from product
    </select>

    <select id = "findById" resultType = "shop.mtcoding.productapp_seller.model.Product">
        SELECT * FROM product WHERE product_id = #{productId}
    </select>

    <select id = "findByName" resultType = "shop.mtcoding.productapp_seller.model.Product">
        select product_name from product where product_name = #{productName}
    </select>

    <insert id = "insert">
        INSERT INTO product(product_name, product_price, product_qty, created_at)
		VALUES(#{productName}, #{productPrice}, #{productQty}, NOW())
    </insert>

    <update id = "update">
        UPDATE product SET 
		product_name = #{productName},
		product_price = #{productPrice},
		product_qty = #{productQty}
		WHERE product_id = #{productId}
    </update>

    <delete id = "deleteById">
        DELETE FROM product WHERE product_id = #{productId}
    </delete>

</mapper>

 

 

JSP 파일은 컨트롤러와 연결이 완성된 상태이므로 세팅 때 EL표현식이 그대로 적힌 코드를 사용하면 오류남!

 

header.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 lang="en">

        <head>
            <title>Product</title>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1" />
            <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
            <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
            <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" rel="stylesheet" />
            <link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-lite.min.css" rel="stylesheet" />
            <script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-lite.min.js"></script>
        </head>
        <style>
            .gitlink {
                text-decoration-line: none;
                color: rgb(255, 105, 138);
                font-weight: bolder;
                background-color: rgb(255, 228, 154);
            }
            .center {
                display: flex;
                justify-content: center;
            }
        </style>

        <body>
            <nav class="navbar navbar-expand-sm bg-dark navbar-dark">
                <div class="container-fluid">
                    <h3 style="color: white;">🤍쇼핑몰🛒판매자 페이지</h3>
                    <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapsibleNavbar">
                        <span class="navbar-toggler-icon"></span>
                    </button>
                    <div class="collapse navbar-collapse" id="collapsibleNavbar">
                        <ul class="navbar-nav">
                            <li class="nav-item">
                                <a class="nav-link" href="/productSave">상품등록페이지</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="/product">상품목록페이지</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </body>

        </html>

 

footer.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <br />
    <hr />
    <div class="jumbotron text-center" style="margin-bottom: 0">
        <p>👾 Created by <a class="gitlink"
                href="https://github.com/JungminK1m/Springboot-Product-Study-Seller">JungminK1m</a></p>
        <p>📞 010-1234-5678</p>
        <p>🏴 부산 부산진구 XX동</p>
    </div>
    </body>

    </html>

 

 

productList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <%@ include file="layout/header.jsp" %>

        <div class="container">
            <table class="table table-striped mt-4">
                <thead>
                    <tr>
                        <th>상품 번호</th>
                        <th>상품 이름</th>
                        <th>상품 가격</th>
                        <th>상품 재고</th>
                    </tr>
                </thead>
                <tbody>
                    <c:forEach items="${productList}" var="product" varStatus="status">
                        <tr>
                            <td>${status.count}</td>
                            <td><a href="/product/${product.productId}">${product.productName}</a></td>
                            <td>${product.productPrice}원</td>
                            <td>${product.productQty}개</td>
                        </tr>
                    </c:forEach>
                </tbody>
            </table>
        </div>

        <%@ include file="layout/footer.jsp" %>

 

productDetail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <%@ include file="layout/header.jsp" %>

        <div class="center">
            <div style="margin: 20px;">
                <table border="1" style="width: 500px; height: 200px; text-align: center;">
                    <tr style="border: 1px solid">
                        <th style="background-color: rgb(185, 185, 185)">상품명</th>
                        <th>${product.productName}</th>
                    </tr>
                    <tr style="border: 1px solid">
                        <th style="background-color: rgb(185, 185, 185)">상품명</th>
                        <td>${product.productPrice}원</td>
                    </tr>
                    <tr style="border: 1px solid">
                        <th style="background-color: rgb(185, 185, 185)">상품명</th>
                        <td>${product.productQty}개</td>
                    </tr>
                </table>
                <div class="center" style="margin-top: 20px; text-align: center;">
                    <form type="submit" action="/product/${product.productId}/updateForm" method="get">
                        <button
                            style="width: 240px; height: 50px; margin-right: 20px; background-color: rgb(255, 210, 199);">수정하기</button>
                    </form>
                    <form type="submit" action="/product/${product.productId}/delete" method="post">
                        <button
                            style="width: 240px; height: 50px; margin: auto; background-color: rgb(250, 255, 182);">삭제하기</button>
                    </form>
                </div>
            </div>
        </div>

        <%@ include file="layout/footer.jsp" %>

 

productSave.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <%@ include file="layout/header.jsp" %>
        <div class="container">
            <form action="/product/save" method="post">
                <div class="mb-3 mt-3">
                    상품명 : <input id="name" name="name" type="text" placeholder="상품명을 적어주세요">
                    <button id="CheckproductName" type="button">중복확인</button>

                </div>
                <div class="mb-3 mt-3">
                    상품가격 : <input id="price" name="price" type="text" placeholder="상품 가격을 적어주세요">
                </div>
                <div class="mb-3 mt-3">
                    상품수량 : <input id="qty" name="qty" type="text" placeholder="상품 수량을 적어주세요">
                </div>
                <button id="submit" type="submit" class="btn btn-primary">상품등록완료</button>

            </form>
        </div>

        <script>

            // 중복체크 여부 = false - 아직 체크 안했으니까
            let sameCheck = false;

            // 상품명 중복체크
            $('#CheckproductName').on('click', function () {

                // 이렇게 데이터를 변수로 만들면 보기가 편하다
                let data = { name: $('#name').val() }

                $.ajax({
                    url: '/productSave/checkName/',
                    type: 'post',
                    data: data,
                    contentType: "application/x-www-form-urlencoded; charset=utf-8"

                }).done((res) => {
                    alert("등록 가능한 상품입니다")
                    // 콘솔창 확인용
                    console.log(res);
                    // 등록 가능하니까 체크 여부를 true로 변경
                    sameCheck = true;

                }).fail((err) => {
                    alert("이미 등록한 상품입니다")
                    // 콘솔창 확인용
                    console.log(err);
                    // 등록 불가이기 때문에 중복체크를 안한 것으로 설정 (아래에 이벤트 처리를 위해)
                    sameCheck = false;
                });
            });

            // 상품명을 입력하는 input 태그에 값이 변경될 때마다 sameCheck 를 false로 설정하는 이벤트
            // => false가 됐으니 상품명을 다른 걸로 바뀌면 꼭 중복체크를 다시 해야되게 만든다.
            $('#name').on('input', function (e) {
                sameCheck = false;
                console.log(sameCheck);
            });
        
            // 동일 상품명 등록하지 못하게 처리하는 이벤트 (최종 상품 등록 버튼)
            // form이 submit 될 때 실행되는 이벤트
            $('form').on('submit', function(e) {
                // == 주의
                if (sameCheck == false) {
                    alert("상품명 중복확인을 해 주세요.");
                    // e.preventDefault(); = 브라우저가 이벤트를 처리하는 동작을 중단시키는 메서드
                    // submit 이벤트를 중단시키기 위해 사용됨
                     e.preventDefault();
                     console.log(sameCheck);
                }else if (sameCheck == true) {
                    alert("상품이 등록되었습니다.");
                    console.log(sameCheck);
                }
            });
        </script>
        <%@ include file="layout/footer.jsp" %>

 

productUpdate.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <%@ include file="layout/header.jsp" %>
        <div class="container">
            <form action="/product/${id}/update" method="post">
                <div class="mb-3 mt-3">
                    상품명 :
                    <input id="name" name="name" type="text" value="${product.productName}" placeholder="상품명을 적어주세요">
                </div>
                <div class="mb-3 mt-3">
                    상품가격 :
                    <input id="price" name="price" type="text" value="${product.productPrice}" placeholder="상품 가격을 적어주세요">
                </div>
                <div class="mb-3 mt-3">
                    상품수량 :
                    <input id="qty" name="qty" type="text" value="${product.productQty}" placeholder="상품 수량을 적어주세요">
                </div>
                <button type="submit" class="btn btn-primary">상품수정완료</button>

            </form>
        </div>
        <%@ include file="layout/footer.jsp" %>
Comments