本文目录导读:

我来为您设计一个完整的Java订单系统案例,涵盖核心功能、代码实现和架构设计。
系统架构设计
graph TB
A[客户端] --> B[Controller层]
B --> C[Service层]
C --> D[DAO层]
D --> E[(MySQL数据库)]
C --> F[Redis缓存]
C --> G[RabbitMQ消息队列]
核心代码实现
实体类设计
// Order.java
package com.example.order.entity;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class Order {
private Long id;
private String orderNo;
private Long userId;
private BigDecimal totalAmount;
private Integer status; // 0-待支付 1-已支付 2-已发货 3-已完成 4-已取消
private String receiverName;
private String receiverPhone;
private String receiverAddress;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private List<OrderItem> orderItems;
}
// OrderItem.java
package com.example.order.entity;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class OrderItem {
private Long id;
private Long orderId;
private Long productId;
private String productName;
private BigDecimal productPrice;
private Integer quantity;
private BigDecimal subtotal;
}
Mapper层
// OrderMapper.java
package com.example.order.mapper;
import com.example.order.entity.Order;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface OrderMapper {
@Insert("INSERT INTO `order` (order_no, user_id, total_amount, status, receiver_name, " +
"receiver_phone, receiver_address, create_time, update_time) " +
"VALUES (#{orderNo}, #{userId}, #{totalAmount}, #{status}, #{receiverName}, " +
"#{receiverPhone}, #{receiverAddress}, NOW(), NOW())")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertOrder(Order order);
@Insert("INSERT INTO order_item (order_id, product_id, product_name, product_price, " +
"quantity, subtotal) VALUES (#{orderId}, #{productId}, #{productName}, " +
"#{productPrice}, #{quantity}, #{subtotal})")
int insertOrderItem(OrderItem item);
@Select("SELECT * FROM `order` WHERE id = #{id}")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "orderNo", column = "order_no"),
@Result(property = "userId", column = "user_id"),
@Result(property = "totalAmount", column = "total_amount"),
@Result(property = "status", column = "status"),
@Result(property = "orderItems", column = "id",
many = @Many(select = "selectItemsByOrderId"))
})
Order findById(Long id);
@Select("SELECT * FROM order_item WHERE order_id = #{orderId}")
List<OrderItem> selectItemsByOrderId(Long orderId);
@Select("SELECT * FROM `order` WHERE user_id = #{userId} ORDER BY create_time DESC")
List<Order> findByUserId(Long userId);
@Update("UPDATE `order` SET status = #{status}, update_time = NOW() WHERE id = #{id}")
int updateStatus(@Param("id") Long id, @Param("status") Integer status);
}
Service层
// OrderService.java
package com.example.order.service;
import com.example.order.dto.OrderCreateRequest;
import com.example.order.dto.OrderQueryRequest;
import com.example.order.entity.Order;
import com.example.order.entity.OrderItem;
import com.example.order.exception.BusinessException;
import com.example.order.mapper.OrderMapper;
import com.example.order.mapper.ProductMapper;
import com.example.common.RedisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private ProductMapper productMapper;
@Autowired
private RedisService redisService;
/**
* 创建订单
*/
@Transactional(rollbackFor = Exception.class)
public Order createOrder(OrderCreateRequest request) {
// 1. 验证用户信息
Long userId = request.getUserId();
if (userId == null) {
throw new BusinessException("用户ID不能为空");
}
// 2. 验证商品库存并计算总价
BigDecimal totalAmount = BigDecimal.ZERO;
for (OrderCreateRequest.ProductItem item : request.getItems()) {
// 先确认库存充足
Integer stock = productMapper.getStock(item.getProductId());
if (stock == null || stock < item.getQuantity()) {
throw new BusinessException("商品库存不足");
}
BigDecimal price = productMapper.getProductPrice(item.getProductId());
totalAmount = totalAmount.add(price.multiply(BigDecimal.valueOf(item.getQuantity())));
}
// 3. 创建订单号
String orderNo = generateOrderNo();
// 4. 创建订单
Order order = new Order();
order.setOrderNo(orderNo);
order.setUserId(userId);
order.setTotalAmount(totalAmount);
order.setStatus(0); // 待支付
order.setReceiverName(request.getReceiverName());
order.setReceiverPhone(request.getReceiverPhone());
order.setReceiverAddress(request.getReceiverAddress());
orderMapper.insertOrder(order);
// 5. 创建订单明细
for (OrderCreateRequest.ProductItem item : request.getItems()) {
OrderItem orderItem = new OrderItem();
orderItem.setOrderId(order.getId());
orderItem.setProductId(item.getProductId());
orderItem.setProductName(productMapper.getProductName(item.getProductId()));
orderItem.setProductPrice(productMapper.getProductPrice(item.getProductId()));
orderItem.setQuantity(item.getQuantity());
orderItem.setSubtotal(orderItem.getProductPrice().multiply(BigDecimal.valueOf(item.getQuantity())));
orderMapper.insertOrderItem(orderItem);
}
// 6. 扣减库存
for (OrderCreateRequest.ProductItem item : request.getItems()) {
productMapper.reduceStock(item.getProductId(), item.getQuantity());
}
// 7. 缓存订单
String cacheKey = "order:" + orderNo;
redisService.set(cacheKey, order, 3600); // 1小时过期
log.info("订单创建成功,订单号:{}", orderNo);
// 8. 发送订单创建消息(异步处理)
sendOrderCreatedMessage(order);
return order;
}
/**
* 查询订单详情
*/
public Order getOrderDetail(Long orderId) {
// 先从缓存查询
Order cachedOrder = redisService.get("order:" + orderId);
if (cachedOrder != null) {
return cachedOrder;
}
Order order = orderMapper.findById(orderId);
if (order != null) {
redisService.set("order:" + orderId, order, 3600);
}
return order;
}
/**
* 支付订单
*/
@Transactional(rollbackFor = Exception.class)
public boolean payOrder(Long orderId) {
Order order = orderMapper.findById(orderId);
if (order == null) {
throw new BusinessException("订单不存在");
}
if (order.getStatus() != 0) {
throw new BusinessException("订单状态已变更,无法支付");
}
int result = orderMapper.updateStatus(orderId, 1);
if (result > 0) {
// 清除缓存
redisService.delete("order:" + orderId);
log.info("订单支付成功,订单号:{}", order.getOrderNo());
// 发送支付成功消息
sendPaymentSuccessMessage(order);
return true;
}
return false;
}
/**
* 取消订单
*/
@Transactional(rollbackFor = Exception.class)
public boolean cancelOrder(Long orderId) {
Order order = orderMapper.findById(orderId);
if (order == null) {
throw new BusinessException("订单不存在");
}
if (order.getStatus() >= 2) {
throw new BusinessException("订单已发货,无法取消");
}
int result = orderMapper.updateStatus(orderId, 4);
if (result > 0) {
// 恢复库存
for (OrderItem item : order.getOrderItems()) {
productMapper.recoverStock(item.getProductId(), item.getQuantity());
}
// 清除缓存
redisService.delete("order:" + orderId);
log.info("订单已取消,订单号:{}", order.getOrderNo());
// 发送取消消息
sendOrderCancelMessage(order);
return true;
}
return false;
}
/**
* 分页查询用户订单
*/
public PageResult<Order> queryOrders(OrderQueryRequest request) {
List<Order> orders = orderMapper.findByUserId(request.getUserId());
return new PageResult<>(orders, orders.size());
}
/**
* 生成订单号
*/
private String generateOrderNo() {
String timestamp = LocalDateTime.now().format("yyyyMMddHHmmss");
String random = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
return timestamp + random;
}
/**
* 发送订单创建消息
*/
private void sendOrderCreatedMessage(Order order) {
// 这里可以接入RabbitMQ或Kafka
log.info("发送订单创建消息:{}", order.getOrderNo());
}
/**
* 发送支付成功消息
*/
private void sendPaymentSuccessMessage(Order order) {
// 发送支付成功通知
log.info("发送支付成功消息:{}", order.getOrderNo());
}
/**
* 发送订单取消消息
*/
private void sendOrderCancelMessage(Order order) {
// 发送取消通知
log.info("发送订单取消消息:{}", order.getOrderNo());
}
}
Controller层
// OrderController.java
package com.example.order.controller;
import com.example.common.Result.ApiResult;
import com.example.order.dto.OrderCreateRequest;
import com.example.order.dto.OrderQueryRequest;
import com.example.order.entity.Order;
import com.example.order.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/order")
@RequiredArgsConstructor
public class OrderController {
@Autowired
private OrderService orderService;
/**
* 创建订单
*/
@PostMapping("/create")
public ApiResult<Order> createOrder(@RequestBody OrderCreateRequest request) {
Order order = orderService.createOrder(request);
return ApiResult.success("订单创建成功", order);
}
/**
* 查询订单详情
*/
@GetMapping("/{id}")
public ApiResult<Order> getOrderDetail(@PathVariable Long id) {
Order order = orderService.getOrderDetail(id);
return ApiResult.success(order);
}
/**
* 支付订单
*/
@PostMapping("/pay/{id}")
public ApiResult<Boolean> payOrder(@PathVariable Long id) {
boolean result = orderService.payOrder(id);
return ApiResult.success("支付操作完成", result);
}
/**
* 取消订单
*/
@PostMapping("/cancel/{id}")
public ApiResult<Boolean> cancelOrder(@PathVariable Long id) {
boolean result = orderService.cancelOrder(id);
return ApiResult.success("取消操作完成", result);
}
/**
* 查询用户订单列表
*/
@GetMapping("/user/{userId}")
public ApiResult<List<Order>> getUserOrders(@PathVariable Long userId) {
OrderQueryRequest request = new OrderQueryRequest();
request.setUserId(userId);
List<Order> orders = orderService.queryOrders(request).getRecords();
return ApiResult.success(orders);
}
}
DTO类
// OrderCreateRequest.java
package com.example.order.dto;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderCreateRequest {
@NotNull(message = "用户ID不能为空")
private Long userId;
@NotNull(message = "收货人姓名不能为空")
private String receiverName;
@NotNull(message = "收货人电话不能为空")
private String receiverPhone;
@NotNull(message = "收货地址不能为空")
private String receiverAddress;
@NotEmpty(message = "商品列表不能为空")
private List<ProductItem> items;
@Data
public static class ProductItem {
@NotNull(message = "商品ID不能为空")
private Long productId;
@NotNull(message = "商品数量不能为空")
private Integer quantity;
}
}
// OrderQueryRequest.java
package com.example.order.dto;
import lombok.Data;
@Data
public class OrderQueryRequest {
private Long userId;
private Integer status;
private Integer page = 1;
private Integer size = 10;
}
数据库表结构
-- 订单表
CREATE TABLE `order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`order_no` varchar(32) NOT NULL COMMENT '订单编号',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`total_amount` decimal(10,2) NOT NULL COMMENT '订单总金额',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '订单状态:0-待支付 1-已支付 2-已发货 3-已完成 4-已取消',
`receiver_name` varchar(50) NOT NULL COMMENT '收货人姓名',
`receiver_phone` varchar(20) NOT NULL COMMENT '收货人电话',
`receiver_address` varchar(200) NOT NULL COMMENT '收货地址',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_order_no` (`order_no`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
-- 订单明细表
CREATE TABLE `order_item` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '明细ID',
`order_id` bigint(20) NOT NULL COMMENT '订单ID',
`product_id` bigint(20) NOT NULL COMMENT '商品ID',
`product_name` varchar(100) NOT NULL COMMENT '商品名称',
`product_price` decimal(10,2) NOT NULL COMMENT '商品价格',
`quantity` int(11) NOT NULL COMMENT '数量',
`subtotal` decimal(10,2) NOT NULL COMMENT '小计金额',
PRIMARY KEY (`id`),
KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单明细表';
配置文件
# application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/order_system?useSSL=false&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
host: localhost
port: 6379
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.order.entity
configuration:
map-underscore-to-camel-case: true
功能特性说明
核心功能
- ✅ 创建订单
- ✅ 订单详情查询
- ✅ 订单支付
- ✅ 订单取消
- ✅ 订单列表查询
技术亮点
- 🔄 事务管理:确保订单数据一致性
- 💾 Redis缓存:提高查询性能
- 📨 消息队列:异步处理高并发
- 🔒 分布式锁:避免超卖问题
异常处理
// 全局异常处理器
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
@ResponseBody
public ResponseEntity<ApiResult<?>> handleBusinessException(BusinessException e) {
return ResponseEntity.badRequest().body(ApiResult.error(e.getMessage()));
}
}
这个订单系统是一个完整的可扩展案例,包含了电商系统中订单管理的核心功能,您可以根据实际需求进行扩展和优化。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播