메뉴 주문 API에 필요한 Model
, Mapper
, Service
, Controller
클래스를 생성하고 코드를 추가하여 기능을 구현합니다.
STS에서 src/main/java 하위에 있는 io.infograb.order.model
패키지(package)를 선택합니다.
File > New > Class를 선택한 다음, Name 필드에 User
을 입력하고 Finish 버튼을 클릭합니다.
User.java
파일 내용을 아래와 같이 수정합니다.
package io.infograb.order.model;
import org.apache.ibatis.type.Alias;
@Alias("User")
public class User {
private String id;
private String name;
private String phone;
private String email;
private boolean useNickname;
private String nickname;
private int balance;
private int rewards;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isUseNickname() {
return useNickname;
}
public void setUseNickname(boolean useNickname) {
this.useNickname = useNickname;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
public int getRewards() {
return rewards;
}
public void setRewards(int rewards) {
this.rewards = rewards;
}
}
STS에서 io.infograb.order.mapper
패키지(package)를 선택합니다.
File > New > Interface를 선택한 다음, Name 필드에 UserMapper
을 입력하고 Finish 버튼을 클릭합니다.
UserMapper.java
파일 내용을 아래와 같이 수정합니다.
package io.infograb.order.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
import io.infograb.order.model.User;
@Repository
@Mapper
public interface UserMapper {
@Select("SELECT id, name, phone, email, use_nickname, nickname, balance, rewards FROM user WHERE id = #{id}")
User selectUserById(String id);
@Update("UPDATE user SET balance = #{balance} WHERE id = #{id}")
void updateBalance(@Param("id") String id, @Param("balance") int balance);
}
MenuMapper.java
파일을 열고 selectMenuById
메서드를 추가하여 아래와 같이 수정합니다.
package io.infograb.order.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import io.infograb.order.model.Menu;
@Repository
@Mapper
public interface MenuMapper {
@Select("SELECT id, name, english_name, price FROM menu")
List<Menu> selectMenus();
@Select("SELECT id, name, english_name, price FROM menu WHERE id = #{id}")
Menu selectMenuById(int id);
}
비슷한 방식으로 io.infograb.order.service
패키지에 OrderService.java
파일을 생성하고 아래와 같이 수정합니다.
package io.infograb.order.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import io.infograb.order.mapper.MenuMapper;
import io.infograb.order.mapper.UserMapper;
import io.infograb.order.model.Menu;
import io.infograb.order.model.User;
@Service
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class OrderService {
private final UserMapper userMapper;
private final MenuMapper menuMapper;
@Autowired
public OrderService(UserMapper userMapper, MenuMapper menuMapper) {
this.userMapper = userMapper;
this.menuMapper = menuMapper;
}
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
public boolean orderDrink(String userId, int menuId) {
User user = userMapper.selectUserById(userId);
Menu menu = menuMapper.selectMenuById(menuId);
int balance = user.getBalance();
int price = menu.getPrice();
if (balance - price >= 0) {
userMapper.updateBalance(userId, balance - price);
return true;
}
return false;
}
}
마찬가지로 io.infograb.order.controller
패키지에 OrderController.java
파일을 생성하고 코드를 수정합니다.
package io.infograb.order.controller;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.infograb.order.service.OrderService;
@CrossOrigin(origins = "*")
@RestController
public class OrderController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final OrderService orderService;
@Autowired
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
@PostMapping(value = "/orders", produces = MediaType.APPLICATION_JSON_VALUE)
public Map<String, String> requestOrder(
@RequestParam(value = "userId", required = false, defaultValue = "user01") String userId,
@RequestParam(value = "menuId", required = false, defaultValue = "0") int menuId) throws Exception {
logger.debug("userId ===== {}", userId);
logger.debug("menuId ===== {}", menuId);
boolean success = orderService.orderDrink(userId, menuId);
Map<String, String> result = new HashMap<>();
if (success) {
result.put("message", "주문이 완료되었습니다.");
} else {
result.put("message", "잔액이 부족합니다.");
}
return result;
}
}