1. view 세팅
1-1. 🧔templates 폴더 세팅 (그림 그리기)

🧔layout/header.mustache
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>blog</title>
</head>
<body>
<nav>
<ul>
<li>
<a href="#">상품목록</a>
</li>
<li>
<a href="#">상품등록</a>
</li>
<li>
<a href="#">구매목록</a>
</li>
</ul>
</nav>
<hr>
🧔log/list.mustache
{{>layout/header}}
<section>
<table border="1">
<tr>
<th>주문번호</th>
<th>상품명(조인)</th>
<th>구매개수</th>
<th>총가격</th>
<th>구매자이름</th>
</tr>
<tr>
<td>1</td>
<td>바나나</td>
<td>5개</td>
<td>15000원</td>
<td>ssar</td>
</tr>
<tr>
<td>2</td>
<td>바나나</td>
<td>5개</td>
<td>15000원</td>
<td>ssar</td>
</tr>
<tr>
<td>3</td>
<td>딸기</td>
<td>5개</td>
<td>10000원</td>
<td>cos</td>
</tr>
</table>
</section>
</body>
</html>
🧔store/detail.mustache
{{> layout/header}}
<section>
<a href="#">수정화면가기</a>
<form action="#">
<button type="submit">삭제</button>
</form>
<div>
번호 : 1 <br>
상품명 : 바나나 <br>
상품가격 : 3000원 <br>
상품재고 : 100개 <br>
</div>
<form action="#">
<input type="hidden" value="1">
<input type="text" placeholder="당신은 누구인가요?">
<input type="text" placeholder="Enter 개수">
<button type="submit">구매</button>
</form>
</section>
</body>
</html>
🧔store/list.mustache
{{>layout/header}}
<section>
<table border="1">
<tr>
<th>번호</th>
<th>상품명</th>
<th></th>
</tr>
<tr>
<td>1</td>
<td>바나나</td>
<td><a href="#">상세보기</a></td>
</tr>
<tr>
<td>2</td>
<td>딸기</td>
<td><a href="#">상세보기</a></td>
</tr>
</table>
</section>
</body>
</html>
🧔store/save-form.mustache
{{> layout/header}}
<section>
<form action="#">
<input type="text" placeholder="상품명"><br>
<input type="text" placeholder="수량"><br>
<input type="text" placeholder="가격"><br>
<button type="submit">상품등록</button>
</form>
</section>
</body>
</html>
🧔store/update-form.mustache
{{> layout/header}}
<section>
<form action="#">
<input type="text" value="바나나"><br>
<input type="text" value="100"><br>
<input type="text" value="3000"><br>
<button type="submit">상품수정</button>
</form>
</section>
</body>
</html>
1-2. 🔗라우팅 테스트

☕HelloController.java
package com.metacoding.storev1;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
@GetMapping("/log/list")
public String t1() {
return "log/list";
}
@GetMapping("/store/list")
public String t2() {
return "store/list";
}
@GetMapping("/store/detail")
public String t3() {
return "store/detail";
}
@GetMapping("/store/save-form")
public String t4() {
return "store/save-form";
}
@GetMapping("/store/update-form")
public String t5() {
return "store/update-form";
}
}
1-3. 실행 결과 화면
🔗/log/list 페이지

🔗/store/list 페이지

🔗/store/detail 페이지

🔗/store/save-form 페이지

🔗/store/update-form 페이지

1-4. ☕java 파일 세팅

- Controller → 요청 받고 응답해주고
- Service → 서비스 로직 작성
- Repository → db에 데이터 넣고 받고
- Entity → Log.java, Store.java
1-5. 테이블 세팅

☕Store.java
package com.metacoding.storev1.store;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter // mustache에서 필드값에 접근하기 위해
@NoArgsConstructor // JPA가 ObjectMapping을 위해 new할 때 사용
// 리플렉션할 때 초반에 클래스를 생성해야하는데 기본생성자가 없으면 생성 불가하기 때문.
@Table(name = "store_tb") // 테이블명 설정
@Entity // 이 클래스가 DB 테이블과 매핑된 엔티티임을 나타냄
public class Store {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name; // 상품 이름
private Integer stock; // 상품 개수
private Integer price; // 상품 가격
}
☕Log.java
package com.metacoding.storev1.log;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter // mustache에서 필드값에 접근하기 위해
@NoArgsConstructor // JPA가 ObjectMapping을 위해 new할 때 사용
// 리플렉션할 때 초반에 클래스를 생성해야하는데 기본생성자가 없으면 생성 불가하기 때문.
@Table(name = "log_tb") // 테이블명 설정
@Entity // 이 클래스가 DB 테이블과 매핑된 엔티티임을 나타냄 -> JPA에게 알려줌
public class Log {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Integer storeId; // 상품 ID (FK)
private String qty; // 구매 개수
private Integer totalPrice; // qty * store(price)
private String buyer; // 구매자 이름
}
application.properties
# vscode console highlight
spring.output.ansi.enabled=always
# 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 | classpath->resources 폴더
# 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
# sql formatter
spring.jpa.properties.hibernate.format_sql=true
테이블 생성 쿼리문
# Table Setting
## store_tb
```sql
create table store_tb (
id integer generated by default as identity,
price integer,
stock integer,
name varchar(255),
primary key (id)
);
```
## log_tb
```sql
create table log_tb (
id integer generated by default as identity,
store_id integer,
total_price integer,
buyer varchar(255),
qty varchar(255),
primary key (id)
)
```
- 빨간줄 → 파일을 읽고 쿼리를 실행함
- 아직 파일도 없고 쿼리도 작성하지 않았으니 주석 처리
table
create table store_tb (
id integer generated by default as identity,
price integer,
stock integer,
name varchar(255),
primary key (id)
);
create table log_tb (
id integer generated by default as identity,
qty integer(255),
store_id integer,
buyer varchar(255),
total_price integer,
primary key (id)
);
resources/db/data.sql (더미 데이터 생성)
- 더미는 일관성 있게
- 테이블의 수량은 총 계산으로 맞추자
- 총 50개면
- 저장소에 40개
- 구매자에 10개
insert into store_tb (name, price, stock) values ('바나나', 3000, 40);
insert into store_tb (name, price, stock) values ('딸기', 2000, 45);
insert into log_tb (store_id, total_price, buyer, qty) values (1, 15000, 'ssar', 5);
insert into log_tb (store_id, total_price, buyer, qty) values (1, 15000, 'ssar', 5);
insert into log_tb (store_id, total_price, buyer, qty) values (2, 10000, 'cos', 5);
- 쿼리문을 작성했으니 위의 프로퍼티 코드에서 빨간줄을 주석해제 하자


1-6. 화면 연결
- mustache 파일과 Controller를 연결하자
🧔templates/layout/header.mustache
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>blog</title>
</head>
<body>
<nav>
<ul>
<li>
<a href="/">상품목록</a>
</li>
<li>
<a href="/store/save-form">상품등록</a>
</li>
<li>
<a href="/log">구매목록</a>
</li>
</ul>
</nav>
<hr>
☕StoreController
@GetMapping("/")
public String list() {
return "store/list";
}
@GetMapping("/store/save-form")
public String saveForm() {
return "store/save-form";
}
☕LogController
@GetMapping("/log")
public String list() {
return "log/list";
}
🧔templates/store/detail.mustache
{{> layout/header}}
<section>
<a href="/store/1/update-form">수정화면가기</a>
<form action="/store/1/delete" method="post">
<button type="submit">삭제</button>
</form>
<div>
번호 : 1 <br>
상품명 : 바나나 <br>
상품가격 : 3000원 <br>
상품재고 : 100개 <br>
</div>
<form action="#" method="post">
<input type="hidden" value="1">
<input type="text" placeholder="당신은 누구인가요?">
<input type="text" placeholder="Enter 개수">
<button type="submit">구매</button>
</form>
</section>
</body>
</html>
☕StoreController
@GetMapping("/store/{id}/update-form")
public String updateForm(@PathVariable("id") int id) {
return "store/update-form";
}
@PostMapping("/store/{id}/delete")
public String delete(@PathVariable("id") int id) {
return "redirect:/";
}
🧔templates/store/list.mustache
{{>layout/header}}
<section>
<table border="1">
<tr>
<th>번호</th>
<th>상품명</th>
<th></th>
</tr>
<tr>
<td>1</td>
<td>바나나</td>
<td><a href="/store/1">상세보기</a></td>
</tr>
<tr>
<td>2</td>
<td>딸기</td>
<td><a href="/store/2">상세보기</a></td>
</tr>
</table>
</section>
</body>
</html>
☕StoreController
@GetMapping("/store/{id}")
public String detail(@PathVariable("id") int id) {
return "store/detail";
}
🧔templates/store/save-form.mustache
{{> layout/header}}
<section>
<form action="/store/save" method="post">
<input type="text" placeholder="상품명"><br>
<input type="text" placeholder="수량"><br>
<input type="text" placeholder="가격"><br>
<button type="submit">상품등록</button>
</form>
</section>
</body>
</html>
☕StoreController
@PostMapping("/store/save")
public String save() {
return "redirect:/store/1";
}
🧔templates/store/update-form.mustache
{{> layout/header}}
<section>
<form action="/store/1/update" method="post">
<input type="text" value="바나나"><br>
<input type="text" value="100"><br>
<input type="text" value="3000"><br>
<button type="submit">상품수정</button>
</form>
</section>
</body>
</html>
☕StoreController
@PostMapping("/store/{id}/update")
public String update(@PathVariable("id") int id) {
return "redirect:/store/1";
}
git add .
git commit -m "view complete"
git push origin master
2. store 로직 추가
2-1. 상품 등록

🧔templates/store/save-form.mustache
{{> layout/header}}
{{! value 값 나중에 삭제 }}
<section>
<form action="/store/save" method="post">
<input type="text" placeholder="상품명" name="name" value="오렌지"><br>
<input type="text" placeholder="수량" name="stock" value="30"><br>
<input type="text" placeholder="가격" name="price" value="1500"><br>
<button type="submit">상품등록</button>
</form>
</section>
</body>
</html>
☕StoreController
package com.metacoding.storev1.store;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller // IoC (제어의 역전)컨테이너에 등록 => HashSet
public class StoreController {
private StoreService storeService;
public StoreController(StoreService storeService) {
this.storeService = storeService;
}
@GetMapping("/store/save-form")
public String saveForm() {
return "store/save-form";
}
@PostMapping("/store/save")
public String save(@RequestParam("name") String name, @RequestParam("stock") int stock,
@RequestParam("price") int price) {
System.out.println("name : " + name);
System.out.println("stock : " + stock);
System.out.println("price : " + price);
storeService.상품등록(name, stock, price);
return "redirect:/";
}
}
☕StoreService
package com.metacoding.storev1.store;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class StoreService {
private StoreRepository storeRepository;
public StoreService(StoreRepository storeRepository) {
this.storeRepository = storeRepository;
}
@Transactional
public void 상품등록(String name, int stock, int price) {
storeRepository.save(name, stock, price);
}
}
☕StoreRepository
package com.metacoding.storev1.store;
import org.springframework.stereotype.Repository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
// @RequiredArgsConstructor // final 이 붙은 필드로만 생성자 만들어
@Repository
public class StoreRepository {
private final EntityManager em;
public StoreRepository(EntityManager em) {
this.em = em;
}
public void save(String name, int stock, int price) {
Query query = em.createNativeQuery("insert into store_tb (name, price, stock) values (?, ?, ?)");
query.setParameter(1, name);
query.setParameter(2, stock);
query.setParameter(3, price);
query.executeUpdate();
}
}


git add .
git commit -m "store save"
git push origin master
2-2. 상품 목록

☕StoreRepository
// List<Store> -> 모델
public List<Store> findAll() {
// 조건 : 오브젝트 매핑은 @Entity가 붙어야지만 가능하다(디폴트생성자 호출) -> Store.class
Query query = em.createNativeQuery("select * from store_tb order by id desc", Store.class);
return query.getResultList();
}
☕StoreController
@GetMapping("/")
public String list(HttpServletRequest request) {
List<Store> storeList = storeService.상품목록();
request.setAttribute("models", storeList);
return "store/list";
}
☕StoreService
public List<Store> 상품목록() {
List<Store> storeList = storeRepository.findAll();
return storeList;
}
🧔templates/store/list.mustache
{{>layout/header}}
<section>
<table border="1">
<tr>
<th>번호</th>
<th>상품명</th>
<th></th>
</tr>
{{# models}}
<tr>
<td>{{id}}</td>
<td>{{name}}</td>
<td><a href="/store/{{id}}">상세보기</a></td>
</tr>
{{/models}}
</table>
</section>
</body>
</html>


git add .
git commit -m "store list"
git push origin master
2-3. 상품 상세보기

☕StoreRepository
public Store findById(int id) {
// 조건 : 오브젝트 매핑은 @Entity가 붙어야지만 가능하다(디폴트생성자 호출)
Query query = em.createNativeQuery("select * from store_tb where id = ?", Store.class);
query.setParameter(1, id);
return (Store) query.getSingleResult();
}
☕StoreController
@GetMapping("/store/{id}")
public String detail(@PathVariable("id") int id, HttpServletRequest request) {
Store store = storeService.상품상세보기(id);
request.setAttribute("model", store);
return "store/detail";
}
☕StoreService
public Store 상품상세보기(int id) {
try {
return storeRepository.findById(id);
} catch (Exception e) {
throw new RuntimeException("해당 상품이 없어 상세보기가 불가합니다");
}
}
🧔templates/store/list.mustache
{{> layout/header}}
<section>
<a href="/store/{{id}}/update-form">수정화면가기</a>
<form action="/store/{{id}}/delete" method="post">
<button type="submit">삭제</button>
</form>
<div>
번호 : {{model.id}} <br>
상품명 : {{model.name}} <br>
상품가격 : {{model.price}} <br>
상품재고 : {{model.stock}}개 <br>
</div>
<form action="#" method="post">
<input type="hidden" value="{{id}}">
<input type="text" placeholder="당신은 누구인가요?">
<input type="text" placeholder="Enter 개수">
<button type="submit">구매</button>
</form>
</section>
</body>
</html>

git add .
git commit -m "store detail"
git push origin master
2-4. 상품 삭제

☕StoreRepository
// TODO #1 삭제 쿼리문 작성
public void deleteById(int id) {
Query query = em.createNativeQuery("delete from store_tb where id = ?");
query.setParameter(1, id);
query.executeUpdate();
}
☕StoreController
// TODO #2 요청데이터에서 무엇을 사용해서 삭제를 할까
@PostMapping("/store/{id}/delete")
public String delete(@PathVariable("id") int id) {
storeService.상품삭제(id);
return "redirect:/";
}
☕StoreService
// TODO #3 싱픔삭제 로직 작성
@Transactional
public void 상품삭제(int id) {
try {
storeRepository.findById(id);
storeRepository.deleteById(id);
} catch (Exception e) {
throw new RuntimeException("해당 상품이 없어 삭제 불가합니다");
}
}


git add .
git commit -m "store delete"
git push origin master
2-5. 상품 업데이트

☕StoreRepository
// TODO #1 id를 기준으로 업데이트 쿼리 작성
public void updateById(int id, String name, int stock, int price) {
Query query = em.createNativeQuery("update store_tb set name = ?, stock = ?, price = ? where id = ?");
query.setParameter(1, name);
query.setParameter(2, stock);
query.setParameter(3, price);
query.setParameter(4, id);
query.executeUpdate();
}
☕StoreController
// TODO #2 id, name, stock, price를 받아 업데이트 요청
@PostMapping("/store/{id}/update")
public String update(@PathVariable("id") int id, @RequestParam("name") String name,
@RequestParam("stock") int stock, @RequestParam("price") int price) {
storeService.상품업데이트(id, name, stock, price);
return "redirect:/store/" + id;
}
☕StoreService
// TODO #3 상품데이터 업데이트 로직
@Transactional
public void 상품업데이트(int id, String name, int stock, int price) {
try {
storeRepository.findById(id);
storeRepository.updateById(id, name, stock, price);
} catch (Exception e) {
throw new RuntimeException("해당 상품이 없어 업데이트가 불가합니다");
}
}
🧔templates/store/update-form.mustache
{{> layout/header}}
<section>
<form action="/store/{{model.id}}/update" method="post">
<input type="text" name="name" value={{model.name}}><br>
<input type="text" name="stock" value={{model.stock}}><br>
<input type="text" name="price" value={{model.price}}><br>
<button type="submit">상품수정</button>
</form>
</section>
</body>
</html>
☕StoreController
// TODO #4 업데이트 화면을 요청, id에 해당하는 데이터 출력
@GetMapping("/store/{id}/update-form")
public String updateForm(@PathVariable("id") int id, HttpServletRequest request) {
Store store = storeService.상품상세보기(id);
request.setAttribute("model", store);
return "store/update-form";
}


git add .
git commit -m "store update"
git push origin master
3. log 로직 추가
9. 스프링부트 상점 v1 TEST ← log 쿼리를 테스트
3-0. 쿼리 테이블 확인
결과 테이블

두 테이블을 inner join

이 중에서 보여줄 테이블만 select

3-1. join한 테이블에 담을 DTO 생성
DTO → 화면에 필요한 데이터만 있는 오브젝트
package com.metacoding.storev1.log;
import lombok.Data;
// DTO : Data Transfer Object -> 화면에 필요한 데이터만 있는 오브젝트
public class LogResponse {
@Data // getter, setter, toString
public static class ListPage {
private int id;
private String name;
private int qty;
private int totalPrice;
private String buyer;
public ListPage(int id, String name, int qty, int totalPrice, String buyer) {
this.id = id;
this.name = name;
this.qty = qty;
this.totalPrice = totalPrice;
this.buyer = buyer;
}
}
}
@Data
→ getter, setter, toString을 만들어 주는 어노테이션
3-2. 구매 목록
☕LogRepository
package com.metacoding.storev1.log;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Repository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
@Repository
public class LogRepository {
private EntityManager em;
public LogRepository(EntityManager em) {
this.em = em;
}
public List<LogResponse.ListPage> findAllJoinStore() {
List<LogResponse.ListPage> logList = new ArrayList<>();
String q = "SELECT lt.id, st.name, lt.qty, lt.total_price, lt.buyer FROM log_tb lt INNER JOIN store_tb st ON lt.store_id = st.id ORDER BY lt.id DESC";
Query query = em.createNativeQuery(q);
List<Object[]> obsList = (List<Object[]>) query.getResultList(); // Object[] -> ROW
// ObjectMapping
for (Object[] obs : obsList) {
LogResponse.ListPage log = new LogResponse.ListPage(
(int) obs[0], (String) obs[1], (int) obs[2], (int) obs[3], (String) obs[4]);
logList.add(log);
}
return logList;
}
}
- 수작업으로 오브젝트 맵핑을 해보았다
☕LogController
package com.metacoding.storev1.log;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import jakarta.servlet.http.HttpServletRequest;
@Controller
public class LogController {
private LogService logService;
public LogController(LogService logService) {
this.logService = logService;
}
@GetMapping("/log")
public String list(HttpServletRequest request) {
List<LogResponse.ListPage> listPage = logService.구매목록();
request.setAttribute("models", listPage);
return "log/list";
}
}
☕LogService
package com.metacoding.storev1.log;
import java.util.List;
import org.springframework.stereotype.Service;
import com.metacoding.storev1.log.LogResponse.ListPage;
@Service
public class LogService {
private LogRepository logRepository;
public LogService(LogRepository logRepository) {
this.logRepository = logRepository;
}
public List<ListPage> 구매목록() {
return logRepository.findAllJoinStore();
}
}
🧔log/list.mustache
{{>layout/header}}
<section>
<table border="1">
<tr>
<th>주문번호</th>
<th>상품명(조인)</th>
<th>구매개수</th>
<th>총가격</th>
<th>구매자이름</th>
</tr>
{{#models}}
<tr>
<td>{{id}}</td>
<td>{{name}}</td>
<td>{{qty}}개</td>
<td>{{totalPrice}}원</td>
<td>{{buyer}}</td>
</tr>
{{/models}}
</table>
</section>
</body>
</html>

3-3. 구매 하기
🧔store/detail.mustache
{{> layout/header}}
<section>
<a href="/store/{{id}}/update-form">수정화면가기</a>
<form action="/store/{{id}}/delete" method="post">
<button type="submit">삭제</button>
</form>
<div>
번호 : {{model.id}} <br>
상품명 : {{model.name}} <br>
상품가격 : {{model.price}} <br>
상품재고 : {{model.stock}}개 <br>
</div>
<form action="/log/save" method="post">
<input type="hidden" value="{{model.id}}" name="storeId">
<input type="text" placeholder="당신은 누구인가요?" name="buyer">
<input type="text" placeholder="Enter 개수" name="qty">
<button type="submit">구매</button>
</form>
</section>
</body>
</html>
☕LogController
@PostMapping("/log/save")
public String save(
@RequestParam("storeId") int storeId,
@RequestParam("buyer") String buyer,
@RequestParam("qty") int qty) {
logService.구매하기(storeId, buyer, qty);
return "redirect:/log";
}
☕LogService
@Transactional
public void 구매하기(int storeId, String buyer, int qty) {
// 1. 상품 재고 업데이트 (조회, 업데이트)
// 1-1. 조회
Store store = storeRepository.findById(storeId);
// 1-2. 재고 상태 변경
store.재고감소(qty);
// 1-3. 재고 업데이트
storeRepository.updateById(store.getId(), store.getName(), store.getStock(), store.getPrice());
// 2. 구매 기록 하기
logRepository.save(storeId, qty, qty * store.getPrice(), buyer);
}
☕Store
package com.metacoding.storev1.store;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter // JPA가 필드 값에 접근하기 위해 필요함
@NoArgsConstructor // JPA가 ObjectMapping을 위해 new할 때 사용
// 리플렉션할 때 초반에 클래스를 생성해야하는데 기본생성자가 없으면 생성 불가하기 때문.
@Table(name = "store_tb") // 테이블명 설정
@Entity // 이 클래스가 DB 테이블과 매핑된 엔티티임을 나타냄 -> JPA에게 알려줌
public class Store {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name; // 상품 이름
private Integer stock; // 상품 개수
private Integer price; // 상품 가격
public void 재고감소(int qty) {
this.stock = this.stock - qty;
}
}
☕LogRepository
public void save(int storeId, int qty, int totalPrice, String buyer) {
Query query = em.createNativeQuery("insert into log_tb (store_id, qty ,total_price, buyer) values (?,?,?,?)");
query.setParameter(1, storeId);
query.setParameter(2, qty);
query.setParameter(3, totalPrice);
query.setParameter(4, buyer);
query.executeUpdate();
}
Share article