고래씌

[SpringBoot] 1-1. 전체 메뉴 목록 조회 본문

Server/SpringBoot

[SpringBoot] 1-1. 전체 메뉴 목록 조회

고래씌 2024. 2. 2. 11:51

1. index.jsp 페이지 보이도록 하기

 

=> com.kh.springboot 패키지아래에 HomeController class 파일 생성

▶ HomeController.java

package com.kh.springboot;

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

@Controller
public class HomeController {
	
	@GetMapping("/")
	public String home() {
		return "forward:index.jsp";
	}
}

 

=> index.jsp로 이동된 것을 확인

 

 

=> 그리고 버전이 17버전이라서 sqldevelper를 키면 이런창이 뜰 것이다. 안뜨면 바로 하면됨

 

 

① cmd창을 키고 sqlplus 입력

② SPRING, SPRING 를 각각 ID, PW에 입력

③ 아래코드를 모두 복사하여 cmd 창에 마우스 오른쪽 버튼 클릭 후 복사되면 엔터

create table menu (
    id number,
    restaurant varchar2(512) not null,
    name varchar2(256) not null,
    price number,
    type varchar2(10) not null, --  한식 kr, 중식 ch, 일식 jp
    taste varchar2(10) not null, -- 순한맛 mild, 매운맛 hot
    constraint pk_menu primary key(id),
    constraint uq_menu unique (restaurant, name, taste) -- 두리순대국 순대국 mild, 두리순대국 순대국 hot
);create sequence seq_menu_id;insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'두리순대국','순대국',7000,'kr','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'두리순대국','순대국',7000,'kr','hot');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'장터','뚝배기 김치찌게',7000,'kr','hot');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'만리향','간짜장',5000,'ch','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'만리향','짬뽕',6000,'ch','hot');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'짬뽕지존','짬뽕',9000,'ch','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'김남완초밥집','완초밥',13000,'jp','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'김남완초밥집','런치초밥',10000,'jp','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'김남완초밥집','참치도로초밥',33000,'jp','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'진가와','자루소면',8000,'jp','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'진가와','자루소바',9000,'jp','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'백운봉','막국수',9000,'kr','hot');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'대우부대찌게','부대지게',10000,'kr','hot');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'봉된장','열무비빔밥+우렁된장',7000,'kr','hot');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'대우부대찌게','부대찌게',10000,'kr','hot');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'산들애','딸기',500,'kr','hot');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'대우부대찌게','청국장',13000,'kr','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'스타동','사케동',8400,'jp','mild');
insert into spring.menu (id,restaurant,name,price,type,taste) values (seq_menu_id.nextval,'진씨화로','돌솥비빔밥',7000,'kr','mild');commit;select
    *
from
    menu;

 

 

 


2. 전송버튼 클릭시 Menu가 모두 보이도록 설정

 

=> /dev 폴더안에 있는 lombok클릭해서 /dev폴더 안에 있는 SpringToolSuite4.exe 클릭

 

 

 

=> Menu.java class 파일 생성

 

 

▶ Menu.java 

package com.kh.springboot.menu.model.vo;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Menu {
	
	private int id;
	private String restaurant;
	private String name;
	private int price;
	private MenuType type;  // 상속클래스로 만들 예정
	private String taste;
	
}

 

=> MenuType은 마우스 갖다대고 class 생성하면 된다.

 

 

 

▶ MenuType.java

- java.lang.Enum을 상속한 클래스

- 예전에는 static final String type="kr";

static final String type2 ="KR"; ....  => 이런식으로 상수값을 관리했었다.

 

- enum 클래스 경우 내부의 상수값을 설정해서 관리함. 이런 비슷한 값을 모아서 관리할 수 있는 것이 enum이다!

enum을 통해 간결하고 가독성 좋은 코드를 작성할 수 있고, 동일한 형태의 데이터그룹을 관리하는데 용이해진다.

 

package com.kh.springboot.menu.model.vo;

public enum MenuType {

	KR("kr"), CH("ch"), JP("jp");  // 클래스명.변수명
	
	private String value;
	
	MenuType(String value) {
		this.value = value;
	}
}

 

 

 

=> 자료형을 다뤄주는 클래스를 만들예정

 

 

 

▶ MenuTypeHandler.java 

package com.kh.springboot.menu.model.typeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import com.kh.springboot.menu.model.vo.MenuType;

/*
 * varchar2 → MenuType로 변환하고 싶다 → getString함수 오버라이딩
 * MenuType → varchar2로 변환시      → setString함수 오버라이딩
 */

@MappedTypes(MenuType.class)  // 자바에서 쓸 자료형
@MappedJdbcTypes(JdbcType.VARCHAR)  // DB에서 쓸 자료형
public class MenuTypeHandler extends BaseTypeHandler<MenuType>{

	/*
	 * query문을 만들때 필요한 함수
	 */
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, MenuType parameter, JdbcType jdbcType)
			throws SQLException {
		ps.setString(i, parameter.getValue());
	}
	
	
	/*
	 * resultSet을 만들 때 필요한 함수
	 * 
	 * 반환결과가 null일 수 있는 결과값일때 실행
	 */
	@Override
	public MenuType getNullableResult(ResultSet rs, String columnName) throws SQLException {
		// rs.getString(columnName);   // 문자열 결과값을 menuType으로 바꾸면 됨. ex)kr → KR 클래스로 바꾸고...
		
		MenuType mt = MenuType.menuTypeValueOf(rs.getString(columnName));
		
		return mt;
	}

	@Override
	public MenuType getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		
		MenuType mt = MenuType.menuTypeValueOf(rs.getString(columnIndex));
		return mt;
	}

	@Override
	public MenuType getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		
		MenuType mt = MenuType.menuTypeValueOf(cs.getString(columnIndex));
		return mt;
	}

}

 

 

 

▶ MenuType.java

=> getter함수 추가

 

=> menuTypeValueOf 추가

 

 

 

▶ application.properties

mybatis.type-handlers-package=com.kh.springboot.menu.model.typeHandler

=> 추가

 

 

 

 

 

=> class 모두 추가

 

 

 

=> index.jsp 추가

 

 

=> style.css추가

@charset "UTF-8";
body {font-family:"휴먼모음T";}
div, section, header, aside, footer {padding:10px;}
/********** header **********/
header div#header-container {height:100px;}
header div#header-container h2  {margin:30px 10px 0px 10px;}
/********** content **********/
section#content     {min-height:600px;}
/********** footer **********/
footer  {background-color:#f8f9fa; background-clip:content-box; clear:both; height:95px; text-align:center;}
footer p    {margin-top:30px;}

 

 

=> resources 폴더아래에 images 폴더 생성후 사진파일 2개 추가

 

 

 

▶ pom.xml 에 전체 복사후 붙여놓기

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.2.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.kh</groupId>
	<artifactId>springboot</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>3.0.3</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
		    <groupId>com.oracle.database.jdbc</groupId>
		    <artifactId>ojdbc6</artifactId>
		    <version>11.2.0.4</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter-test</artifactId>
			<version>3.0.3</version>
			<scope>test</scope>
		</dependency>
		
		<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-tomcat</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->
		
		<dependency>
			<groupId>jakarta.servlet</groupId>
			<artifactId>jakarta.servlet-api</artifactId>
		</dependency>
		<dependency>
			<groupId>jakarta.servlet.jsp</groupId>
			<artifactId>jakarta.servlet.jsp-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>jakarta.el</groupId>
			<artifactId>jakarta.el-api</artifactId>
			<version>5.0.0</version>
		</dependency>
		<dependency>
			<groupId>jakarta.servlet.jsp.jstl</groupId>
			<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
		</dependency>
		<dependency>
			<groupId>org.glassfish.web</groupId>
			<artifactId>jakarta.servlet.jsp.jstl</artifactId>
		</dependency>
		<dependency>
		    <groupId>org.apache.tomcat.embed</groupId>
		    <artifactId>tomcat-embed-jasper</artifactId>
		</dependency>
		
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

 

 

 

▶ application.properties  아래 코드 추가

#jsp preview
server.servlet.jsp.init-parameters.development = true

 

 

 

▶ index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="jakarta.tags.core"%>

<!-- contextPath 보관 -->
<c:set var="contextPath" value="${pageContext.request.contextPath }" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<!-- bootstrap js: jquery load 이후에 작성할것.-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<!-- bootstrap css -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<link rel="stylesheet" href="${contextPath }/resources/css/style.css" />
</head>
<body>
	<div id="container">
		<header>
			<div id="header-container">
				<h2>Menu</h2>
			</div>
			
			<nav class="navbar navbar-expand-lg navbar-light bg-light">
	            <a class="navbar-brand" href="#">
	                    <img src="${pageContext.request.contextPath }/resources/images/logo-spring.png" alt="스프링로고" width="50px" />
	            </a>
	            <!-- 반응형으로 width 줄어들경우, collapse버튼관련 -->
	            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
	                <span class="navbar-toggler-icon"></span>
	            </button>
	            <div class="collapse navbar-collapse" id="navbarNav">
	            </div>
       		</nav>
		</header>
		
		<section id='content'>
			<div id='menu-container' class='text-center'>
				<div class='menu-test'>
					<h4>전체메뉴조회기능(GET)</h4>
					<input type='button' class='btn btn-block btn-outline-success btn-send'
						id='btn-menus' value="전송">
				</div>
				<div id="menus-result" class='result'></div>
				<script>
					function displayResultTable(id, data){
						
						const container = $("#" +id);
						
						let html = "<table class='table'>";
							html += "<tr><th>번호</th><th>음식점</th><th>메뉴</th>" + 
									"<th>가격</th><th>타입</th><th>맛</th></tr>";
						 
						if(data.length > 0) {  // 데이터가 있다면
							$(data).each((index, menu) => {   // menu라는 변수 사용. js객체로 받은 menu객체일것
								const {id, restaurant, name, price, type, taste} = menu;
								html += `<tr>
											<td>\${id}</td>  
											<td>\${restaurant}</td>
											<td>\${name}</td>
											<td>\${price}</td>
											<td>\${type}</td>
											<td>\${taste}</td>
										</tr>`;
							})
						}else{
							html += "<tr><td colspan='6'>검색결과가 없습니다.</td></tr>";
						}
						
						html += "</table>";  // 열어놨던 table 태그 닫음
						container.html(html);
					}
					
					$("#btn-menus").click(() => {
						$.ajax({
							url : '${contextPath}/menus',
							method : "get",
							success : (data) => {
								displayResultTable("menus-result", data);
							},
							error : (error, req, res) => {
								console.log(error, req, res)
							}
						})
					})
				</script>
			</div>
		</section>
	</div>
</body>
</html>

 


▶ MenuController.java

package com.kh.springboot.menu.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.RestController;

import com.kh.springboot.menu.model.service.MenuService;
import com.kh.springboot.menu.model.vo.Menu;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class MenuController {
	
	@Autowired
	private MenuService menuService;

	
//	메뉴 목록 조회
	@GetMapping("/menus")
	public List<Menu> menus(){
		
		System.out.println(menuService.selectMenus());
		return menuService.selectMenus();
	}
	
}

 

 

▶ MenuService.java

package com.kh.springboot.menu.model.service;

import java.util.List;

import com.kh.springboot.menu.model.vo.Menu;

public interface MenuService {

//	메뉴목록 조회
	List<Menu> selectMenus();

}

 

 

▶ MenuServiceImpl.java

package com.kh.springboot.menu.model.service;

import java.util.List;

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

import com.kh.springboot.menu.model.dao.MenuDao;
import com.kh.springboot.menu.model.vo.Menu;

@Service
public class MenuServiceImpl implements MenuService{
	
	@Autowired
	private MenuDao menuDao;

//	메뉴 목록 조회
	@Override
	public List<Menu> selectMenus() {
		return menuDao.selectMenus();
	}

}

 

 

 

▶ MenuDao.java

package com.kh.springboot.menu.model.dao;

import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.kh.springboot.menu.model.vo.Menu;

@Repository
public class MenuDao {
	
	@Autowired
	private SqlSessionTemplate session;

	public List<Menu> selectMenus() {
		return session.selectList("menuMapper.selectMenus");
	}

}

 

 

▶ menu-mapper.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="menuMapper">

	<resultMap type="menu" id="menuMap">
		<result column="TYPE" typeHandler="menuTypeHandler" property="type" />
	</resultMap>

	<select id="selectMenus" resultMap="menuMap">
		SELECT *
		FROM MENU
		ORDER BY ID DESC
	</select>

</mapper>

 

 

▶ 결과