Spring BootとMyBatisを用いたショッピングカート機能の実装

ショッピングカートの追加処理

ユーザーが商品をカートに追加する操作を実装するため、まずデータ転送オブジェクト(DTO)を定義します。このオブジェクトは、料理ID、セットメニューID、および料理の風味情報を受け取るために使用されます。

@Data
public class CartItemAddRequest implements Serializable {
    private Long dishId;
    private Long mealSetId;
    private String flavor;
}

次に、ユーザー向けAPIとしてCartControllerを作成し、カート関連のエンドポイントを提供します。

@RestController
@RequestMapping("/user/cart")
@Slf4j
public class CartController {

    @Autowired
    private CartService cartService;

    @PostMapping("/add")
    public Result addItemToCart(@RequestBody CartItemAddRequest request) {
        log.info("カートにアイテム追加: {}", request);
        cartService.addItem(request);
        return Result.success();
    }
}

ビジネスロジックはCartServiceインターフェースで定義され、その実装クラスCartServiceImplによって処理されます。

@Service
@Slf4j
public class CartServiceImpl implements CartService {

    @Autowired
    private ShoppingCartMapper cartMapper;

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private MealSetMapper mealSetMapper;

    @Override
    public void addItem(CartItemAddRequest request) {
        // 現在のユーザーIDを取得
        Long userId = BaseContext.getCurrentId();

        // 既存のカートアイテムを検索する条件を構築
        ShoppingCart criteria = new ShoppingCart();
        criteria.setUserId(userId);
        criteria.setDishId(request.getDishId());
        criteria.setMealSetId(request.getMealSetId());
        criteria.setFlavor(request.getFlavor());

        List<ShoppingCart> existingItems = cartMapper.findByCriteria(criteria);

        if (!existingItems.isEmpty()) {
            // 既に存在する場合は数量を1増やす
            ShoppingCart item = existingItems.get(0);
            item.setQuantity(item.getQuantity() + 1);
            cartMapper.updateItemQuantity(item);
            return;
        }

        // 新規アイテムとして登録
        ShoppingCart newItem = new ShoppingCart();
        BeanUtils.copyProperties(request, newItem);
        newItem.setUserId(userId);
        newItem.setQuantity(1);
        newItem.setCreateTime(LocalDateTime.now());

        // 商品名や価格などの追加情報を取得
        if (request.getDishId() != null) {
            Dish dish = dishMapper.selectById(request.getDishId());
            newItem.setName(dish.getName());
            newItem.setPrice(dish.getPrice());
            newItem.setImageUrl(dish.getImage());
        } else if (request.getMealSetId() != null) {
            MealSet mealSet = mealSetMapper.selectById(request.getMealSetId());
            newItem.setName(mealSet.getName());
            newItem.setPrice(mealSet.getPrice());
            newItem.setImageUrl(mealSet.getImage());
        }

        cartMapper.insert(newItem);
    }
}

マッパーインターフェースでは、MyBatisのアノテーションを使用してSQLを定義します。

@Mapper
public interface ShoppingCartMapper {

    @Select("<script>" +
            "SELECT * FROM shopping_cart WHERE user_id = #{userId} " +
            "<if test='dishId != null'> AND dish_id = #{dishId}</if> " +
            "<if test='mealSetId != null'> AND meal_set_id = #{mealSetId}</if> " +
            "<if test='flavor != null'> AND dish_flavor = #{flavor}</if> " +
            "</script>")
    List<ShoppingCart> findByCriteria(ShoppingCart criteria);

    @Insert("INSERT INTO shopping_cart " +
            "(name, user_id, dish_id, meal_set_id, dish_flavor, quantity, price, image_url, create_time) " +
            "VALUES " +
            "(#{name}, #{userId}, #{dishId}, #{mealSetId}, #{flavor}, #{quantity}, #{price}, #{imageUrl}, #{createTime})")
    void insert(ShoppingCart cartItem);

    @Update("UPDATE shopping_cart SET quantity = #{quantity} WHERE id = #{id}")
    void updateItemQuantity(ShoppingCart cartItem);
}

カート内容の取得

ユーザーが現在のカートの中身を確認できるように、全アイテムを取得する機能を実装します。

@GetMapping("/list")
public Result<List<ShoppingCart>> getCartItems() {
    log.info("カート内容を取得");
    List<ShoppingCart> items = cartService.listAll();
    return Result.success(items);
}

サービス層での実装は以下の通りです。

@Override
public List<ShoppingCart> listAll() {
    ShoppingCart query = new ShoppingCart();
    query.setUserId(BaseContext.getCurrentId());
    return cartMapper.findByUserId(query.getUserId());
}

対応するマッパーメソッド:

@Select("SELECT * FROM shopping_cart WHERE user_id = #{userId} ORDER BY create_time DESC")
List<ShoppingCart> findByUserId(Long userId);

カートの全削除

ユーザーがカート内すべてのアイテムを一度に削除できるようにする機能です。

@DeleteMapping("/clear")
public Result clearCart() {
    log.info("カートを空にする");
    cartService.clear();
    return Result.success();
}

サービス実装:

@Override
public void clear() {
    cartMapper.deleteByUserId(BaseContext.getCurrentId());
}

マッパーメソッド:

@Delete("DELETE FROM shopping_cart WHERE user_id = #{userId}")
void deleteByUserId(Long userId);

タグ: Spring Boot MyBatis REST API ショッピングカート Java

6月3日 19:49 投稿