README
# Table Setting
## user_tb
```sql
create table user_tb (
id integer generated by default as identity,
created_at timestamp(6),
password varchar(12) not null,
username varchar(12) not null unique,
fullname varchar(255) not null,
primary key (id)
);
```
## store_tb
```sql
create table store_tb (
id integer generated by default as identity,
price integer,
stock integer,
name varchar(255),
primary key (id)
);
```
## order_tb
```sql
create table order_tb (
id integer generated by default as identity,
qty integer,
store_id integer,
total_price integer,
user_id integer,
primary key (id)
);
```

DummyData
insert into store_tb(name, stock, price) values('바나나', 40, 3000);
insert into store_tb(name, stock, price) values('딸기', 45, 2000);
insert into user_tb(username, password, fullname, created_at) values ('ssar', '1234', '쌀', now());
insert into user_tb(username, password, fullname, created_at) values ('cos', '1234', '코스', now());
insert into order_tb(store_id, qty, total_price, user_id) values(1, 5, 15000, 1);
insert into order_tb(store_id, qty, total_price, user_id) values(1, 5, 15000, 1);
insert into order_tb(store_id, qty, total_price, user_id) values(2, 5, 10000, 2);
application.properties
# utf-8
server.servlet.encoding.charset=utf-8
server.servlet.encoding.force=true
# DB
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
# JPA table create or none
spring.jpa.hibernate.ddl-auto=create
# query log
spring.jpa.show-sql=true
# dummy data
spring.sql.init.data-locations=classpath:db/data.sql
# create dummy data after ddl-auto create
spring.jpa.defer-datasource-initialization=true
# mustache request expose
spring.mustache.servlet.expose-request-attributes=true
# mustache session expose
spring.mustache.servlet.expose-session-attributes=true
# sql formatter
spring.jpa.properties.hibernate.format_sql=true
header
<!DOCTYPE html>
<html lang="en">
<head>
<title>Store</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="/">Home</a>
<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="#">회원가입</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">로그인</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">상품목록</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">상품등록</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">구매목록</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">로그아웃</a>
</li>
</ul>
</div>
</div>
</nav>
<!--네브바종료-->
home
{{> layout/header}}
<div class="container mt-2">
<div class="mt-4 p-5 bg-light text-dark rounded-4">
<h1>가게에 오신것을 환영합니다.</h1>
<h3 class="mt-3">
쌀님
</h3>
</div>
</div>
</body>
</html>
login-form
{{> layout/header}}
<div class="container mt-2">
<div class="mt-4 p-5 bg-light text-dark rounded-4">
<h1>로그인 페이지</h1>
<form action="/login" method="post">
<div class="mb-3 mt-3">
<input type="text" class="form-control" placeholder="Enter username" name="username">
</div>
<div class="mb-3">
<input type="password" class="form-control" placeholder="Enter password" name="password">
</div>
<button type="submit" class="btn btn-primary">로그인</button>
</form>
</div>
</div>
</body>
</html>
join-form
{{> layout/header}}
<div class="container mt-2">
<div class="mt-4 p-5 bg-light text-dark rounded-4">
<h1>회원가입 페이지</h1>
<form action="/join" method="post">
<div class="mb-3 mt-3">
<input type="text" class="form-control" placeholder="Enter username" name="username">
</div>
<div class="mb-3">
<input type="password" class="form-control" placeholder="Enter password" name="password">
</div>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter fullname" name="fullname">
</div>
<button type="submit" class="btn btn-primary">회원가입</button>
</form>
</div>
</div>
</body>
</html>
detail
{{> layout/header}}
<div class="container mt-2">
<div class="mt-4 p-5 bg-light text-dark rounded-4">
<p>번호 : 1</p>
<p>상품명 : 바나나</p>
<p>상품가격 : 3000</p>
<p>상품재고 : 40</p>
</div>
<div class="mt-3 mb-3">
<a href="#" class="btn btn-outline-primary">수정</a>
<form action="#" method="POST" class="d-inline">
<button type="submit" class="btn btn-outline-primary">삭제</button>
</form>
</div>
<div class="mt-4 p-5 bg-light text-dark rounded-4">
<form action="#">
<input type="hidden" value="1">
<input type="text" placeholder="개수를 입력하세요">
<button type="submit" class="btn btn-outline-primary">구매</button>
</form>
</div>
</div>
</body>
</html>
store/list
{{> layout/header}}
<div class="container mt-2">
<table class="table table-hover">
<thead>
<tr>
<th>번호</th>
<th>상품명</th>
<th>상세보기</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>바나나</td>
<td><a href="#">상세보기</a></td>
</tr>
<tr>
<td>2</td>
<td>딸기</td>
<td><a href="#">상세보기</a></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
save-form
{{> layout/header}}
<div class="container mt-2">
<div class="mt-4 p-5 bg-light text-dark rounded-4">
<h1>상품등록 페이지</h1>
<form action="#" method="post">
<div class="mb-3 mt-3">
<input type="text" class="form-control" placeholder="상품명을 입력하세요" name="name">
</div>
<div class="mb-3">
<input type="text" class="form-control" placeholder="재고를 입력하세요" name="stock">
</div>
<div class="mb-3 mt-3">
<input type="text" class="form-control" placeholder="가격을 입력하세요" name="price">
</div>
<button type="submit" class="btn btn-primary">상품등록</button>
</form>
</div>
</div>
</body>
</html>
update-form
{{> layout/header}}
<div class="container mt-2">
<div class="mt-4 p-5 bg-light text-dark rounded-4">
<h1>상품수정 페이지</h1>
<form action="#" method="post">
<div class="mb-3 mt-3">
<input type="text" class="form-control" name="name" value="딸기">
</div>
<div class="mb-3">
<input type="text" class="form-control" name="stock" value=45>
</div>
<div class="mb-3 mt-3">
<input type="text" class="form-control" name="price" value=2000>
</div>
<button type="submit" class="btn btn-primary">상품수정</button>
</form>
</div>
</div>
</body>
</html>
order/list
{{> layout/header}}
<div class="container mt-2">
<div class="mt-4 p-5 bg-light text-dark rounded-4">
<h1>구매목록 페이지</h1>
<hr>
<table class="mt-4 table table-hover">
<thead>
<tr>
<th>주문번호</th>
<th>상품명</th>
<th>구매개수</th>
<th>총 가격</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>바나나</td>
<td>5개</td>
<td>15000원</td>
</tr>
<tr>
<td>2</td>
<td>바나나</td>
<td>5개</td>
<td>15000원</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
ViewCheckController
package com.metacoding.storev2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ViewCheckController {
@GetMapping("/t1")
public String t1() {
return "home";
}
@GetMapping("/t2")
public String t2() {
return "user/join-form";
}
@GetMapping("/t3")
public String t3() {
return "user/login-form";
}
@GetMapping("/t4")
public String t4() {
return "store/list";
}
@GetMapping("/t5")
public String t5() {
return "store/detail";
}
@GetMapping("/t6")
public String t6() {
return "store/save-form";
}
@GetMapping("/t7")
public String t7() {
return "store/update-form";
}
@GetMapping("/t8")
public String t8() {
return "order/list";
}
}
Share article