基于Java的SpringBoot在线商城管理系统 - 源码深度解析

JavaMySQL
2026-03-183 浏览

文章摘要

在当今数字化商业环境中,电子商务平台已成为企业运营的核心基础设施。基于SpringBoot框架构建的在线商城管理系统,采用Java语言开发,MySQL数据库存储,实现了完整的商品管理、订单处理、用户权限控制等核心功能。该系统采用分层架构设计,前后端分离模式,具有良好的可扩展性和维护性。

系统架构与技术栈

系统采用标准的MVC架构模式,后端基于SpringBoot 2.x框架,整合了Spring MVC、Spring Data JPA、Spring Security等核心模块。前端使用Thymeleaf模板引擎结合Bootstrap框架,实现响应式页面设计。数据库连接池采用HikariCP,缓存层使用Redis,文件存储支持本地和云存储两种方式。

数据访问层采用JPA规范,通过实体类映射实现对象关系映射。服务层通过@Service注解标识业务逻辑组件,控制层使用@RestController和@Controller分别处理RESTful API和页面请求。安全控制通过自定义UserDetailsService实现用户认证和权限管理。

数据库设计深度解析

用户表设计

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `password` varchar(100) NOT NULL,
  `email` varchar(100) DEFAULT NULL,
  `phone` varchar(20) DEFAULT NULL,
  `role` enum('ADMIN','USER') DEFAULT 'USER',
  `created_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username_unique` (`username`),
  UNIQUE KEY `email_unique` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

用户表设计体现了多个技术亮点:使用ENUM类型严格限制角色权限,确保数据完整性;username和email字段设置唯一约束,防止重复注册;created_time和updated_time自动维护时间戳,audit trail功能完善。密码字段预留100字符长度,为BCrypt加密算法留足空间。

商品表设计

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(200) NOT NULL,
  `description` text,
  `price` decimal(10,2) NOT NULL,
  `stock` int(11) DEFAULT '0',
  `category_id` int(11) NOT NULL,
  `image_url` varchar(500) DEFAULT NULL,
  `status` enum('AVAILABLE','UNAVAILABLE') DEFAULT 'AVAILABLE',
  `created_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `fk_product_category` (`category_id`),
  CONSTRAINT `fk_product_category` FOREIGN KEY (`category_id`) 
  REFERENCES `category` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

商品表采用十进制精度数据类型存储价格,避免浮点数精度问题。通过外键约束与分类表建立关联,ON DELETE CASCADE确保数据一致性。状态字段使用ENUM类型,限制商品可用状态。image_url字段支持长路径存储,为CDN集成预留接口。

订单表设计

CREATE TABLE `order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_number` varchar(50) NOT NULL,
  `user_id` int(11) NOT NULL,
  `total_amount` decimal(10,2) NOT NULL,
  `status` enum('PENDING','PAID','SHIPPED','COMPLETED','CANCELLED') DEFAULT 'PENDING',
  `payment_method` varchar(50) DEFAULT NULL,
  `shipping_address` text NOT NULL,
  `created_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `order_number_unique` (`order_number`),
  KEY `fk_order_user` (`user_id`),
  CONSTRAINT `fk_order_user` FOREIGN KEY (`user_id`) 
  REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

订单表设计采用业务主键与技术主键分离策略,order_number作为业务标识符支持定制化规则。状态枚举覆盖完整订单生命周期,支付方式字段为多支付渠道集成预留扩展性。地址信息使用TEXT类型存储结构化JSON数据,支持详细收货信息记录。

核心功能实现解析

用户权限管理模块

系统采用基于角色的访问控制模型,通过Spring Security实现细粒度权限管理。用户认证流程包含密码加密、会话管理和权限验证三个核心环节。

@Service
public class CustomUserDetailsService implements UserDetailsService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public UserDetails loadUserByUsername(String username) 
        throws UsernameNotFoundException {
        
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
        
        return org.springframework.security.core.userdetails.User
            .withUsername(user.getUsername())
            .password(user.getPassword())
            .authorities(user.getRole().name())
            .build();
    }
}

权限控制配置类定义URL访问规则,管理员角色可访问所有管理功能,普通用户限制在前台操作范围:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/dashboard")
            .permitAll()
            .and()
            .logout()
            .logoutSuccessUrl("/login?logout")
            .permitAll();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

用户登录界面

商品管理功能

商品管理模块支持完整的CRUD操作,包含图片上传、库存管理、分类管理等子功能。控制器层采用RESTful设计风格,提供统一的API接口。

@RestController
@RequestMapping("/api/products")
public class ProductController {
    
    @Autowired
    private ProductService productService;
    
    @GetMapping
    public ResponseEntity<Page<Product>> getProducts(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> products = productService.findAll(pageable);
        return ResponseEntity.ok(products);
    }
    
    @PostMapping
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Product> createProduct(
            @RequestBody @Valid Product product) {
        
        Product savedProduct = productService.save(product);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedProduct);
    }
    
    @PutMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Product> updateProduct(
            @PathVariable Long id, 
            @RequestBody @Valid Product product) {
        
        product.setId(id);
        Product updatedProduct = productService.update(product);
        return ResponseEntity.ok(updatedProduct);
    }
}

服务层实现业务逻辑,包含价格验证、库存检查等核心业务规则:

@Service
@Transactional
public class ProductService {
    
    @Autowired
    private ProductRepository productRepository;
    
    public Product save(Product product) {
        validateProductPrice(product.getPrice());
        validateStockQuantity(product.getStock());
        
        return productRepository.save(product);
    }
    
    public Product update(Product product) {
        Product existingProduct = productRepository.findById(product.getId())
            .orElseThrow(() -> new EntityNotFoundException("商品不存在"));
        
        if (!existingProduct.getPrice().equals(product.getPrice())) {
            validateProductPrice(product.getPrice());
        }
        
        existingProduct.setName(product.getName());
        existingProduct.setDescription(product.getDescription());
        existingProduct.setPrice(product.getPrice());
        existingProduct.setStock(product.getStock());
        
        return productRepository.save(existingProduct);
    }
    
    private void validateProductPrice(BigDecimal price) {
        if (price.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("商品价格不能为负数");
        }
    }
    
    private void validateStockQuantity(Integer stock) {
        if (stock < 0) {
            throw new IllegalArgumentException("库存数量不能为负数");
        }
    }
}

商品管理界面

购物车与订单处理

购物车功能采用会话存储方案,支持商品添加、数量修改、批量删除等操作。订单生成流程包含库存校验、价格计算、支付状态跟踪等关键步骤。

@Service
public class ShoppingCartService {
    
    public void addItem(CartItem cartItem, HttpSession session) {
        Map<Long, CartItem> cart = getCart(session);
        Long productId = cartItem.getProduct().getId();
        
        if (cart.containsKey(productId)) {
            CartItem existingItem = cart.get(productId);
            existingItem.setQuantity(existingItem.getQuantity() + cartItem.getQuantity());
        } else {
            cart.put(productId, cartItem);
        }
        
        session.setAttribute("cart", cart);
    }
    
    public Order createOrderFromCart(HttpSession session, User user) {
        Map<Long, CartItem> cart = getCart(session);
        validateCart(cart);
        
        Order order = new Order();
        order.setUser(user);
        order.setOrderNumber(generateOrderNumber());
        order.setStatus(OrderStatus.PENDING);
        
        List<OrderItem> orderItems = new ArrayList<>();
        BigDecimal totalAmount = BigDecimal.ZERO;
        
        for (CartItem cartItem : cart.values()) {
            OrderItem orderItem = new OrderItem();
            orderItem.setProduct(cartItem.getProduct());
            orderItem.setQuantity(cartItem.getQuantity());
            orderItem.setUnitPrice(cartItem.getProduct().getPrice());
            
            BigDecimal itemTotal = cartItem.getProduct().getPrice()
                .multiply(BigDecimal.valueOf(cartItem.getQuantity()));
            orderItem.setTotalPrice(itemTotal);
            
            orderItems.add(orderItem);
            totalAmount = totalAmount.add(itemTotal);
        }
        
        order.setOrderItems(orderItems);
        order.setTotalAmount(totalAmount);
        
        // 清空购物车
        session.removeAttribute("cart");
        
        return orderService.save(order);
    }
    
    private void validateCart(Map<Long, CartItem> cart) {
        if (cart.isEmpty()) {
            throw new EmptyCartException("购物车为空");
        }
        
        for (CartItem item : cart.values()) {
            if (item.getQuantity() <= 0) {
                throw new InvalidQuantityException("商品数量无效");
            }
            
            Product product = productService.findById(item.getProduct().getId());
            if (product.getStock() < item.getQuantity()) {
                throw new InsufficientStockException("库存不足");
            }
        }
    }
}

订单支付状态机实现业务状态流转控制:

@Component
public class OrderStateMachine {
    
    private final StateMachineFactory<OrderStatus, OrderEvent> factory;
    
    public OrderStateMachine(StateMachineFactory<OrderStatus, OrderEvent> factory) {
        this.factory = factory;
    }
    
    public boolean sendEvent(Order order, OrderEvent event) {
        StateMachine<OrderStatus, OrderEvent> stateMachine = build(order);
        return stateMachine.sendEvent(event);
    }
    
    @Transactional
    public Order processPayment(Long orderId) {
        Order order = orderRepository.findById(orderId)
            .orElseThrow(() -> new EntityNotFoundException("订单不存在"));
        
        if (sendEvent(order, OrderEvent.PAY)) {
            order.setStatus(OrderStatus.PAID);
            order.setPaymentTime(LocalDateTime.now());
            return orderRepository.save(order);
        }
        
        throw new IllegalStateException("订单状态转换失败");
    }
    
    @Configuration
    @EnableStateMachine
    public static class OrderStateMachineConfig 
        extends StateMachineConfigurerAdapter<OrderStatus, OrderEvent> {
        
        @Override
        public void configure(StateMachineStateConfigurer<OrderStatus, OrderEvent> states)
            throws Exception {
            
            states.withStates()
                .initial(OrderStatus.PENDING)
                .state(OrderStatus.PAID)
                .state(OrderStatus.SHIPPED)
                .end(OrderStatus.COMPLETED)
                .end(OrderStatus.CANCELLED);
        }
        
        @Override
        public void configure(StateMachineTransitionConfigurer<OrderStatus, OrderEvent> transitions)
            throws Exception {
            
            transitions.withExternal()
                .source(OrderStatus.PENDING).target(OrderStatus.PAID).event(OrderEvent.PAY)
                .and().withExternal()
                .source(OrderStatus.PAID).target(OrderStatus.SHIPPED).event(OrderEvent.SHIP)
                .and().withExternal()
                .source(OrderStatus.SHIPPED).target(OrderStatus.COMPLETED).event(OrderEvent.COMPLETE)
                .and().withExternal()
                .source(OrderStatus.PENDING).target(OrderStatus.CANCELLED).event(OrderEvent.CANCEL)
                .and().withExternal()
                .source(OrderStatus.PAID).target(OrderStatus.CANCELLED).event(OrderEvent.REFUND);
        }
    }
}

订单管理界面

数据实体模型设计

系统采用JPA实体映射,建立完整的对象关系模型。实体类设计遵循DDD领域驱动设计原则,封装业务逻辑和行为。

@Entity
@Table(name = "user")
@Data
@EqualsAndHashCode(callSuper = true)
public class User extends BaseEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false, unique = true, length = 50)
    private String username;
    
    @Column(nullable = false, length = 100)
    private String password;
    
    @Column(unique = true, length = 100)
    private String email;
    
    @Column(length = 20)
    private String phone;
    
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private UserRole role = UserRole.USER;
    
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Order> orders = new ArrayList<>();
    
    public boolean isAdmin() {
        return UserRole.ADMIN.equals(this.role);
    }
}

@Entity
@Table(name = "product")
@Data
@EqualsAndHashCode(callSuper = true)
public class Product extends BaseEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false, length = 200)
    private String name;
    
    @Lob
    private String description;
    
    @Column(nullable = false, precision = 10, scale = 2)
    private BigDecimal price;
    
    private Integer stock = 0;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "category_id")
    private Category category;
    
    @Column(length = 500)
    private String imageUrl;
    
    @Enumerated(EnumType.STRING)
    private ProductStatus status = ProductStatus.AVAILABLE;
    
    public boolean isAvailable() {
        return ProductStatus.AVAILABLE.equals(this.status) && this.stock > 0;
    }
    
    public void decreaseStock(Integer quantity) {
        if (this.stock < quantity) {
            throw new InsufficientStockException("库存不足");
        }
        this.stock -= quantity;
    }
}

@MappedSuperclass
@Data
public abstract class BaseEntity {
    
    @CreatedDate
    @Column(name = "created_time", updatable = false)
    private LocalDateTime createdTime;
    
    @LastModifiedDate
    @Column(name = "updated_time")
    private LocalDateTime updatedTime;
}

系统优化与功能扩展建议

性能优化方向

  1. 查询优化:对商品列表、订单查询等高频操作添加数据库索引,使用@QueryHints优化JPA查询性能
  2. 缓存策略:集成Redis实现商品详情、用户会话等数据的分布式缓存,减少数据库压力
  3. 异步处理:使用@Async注解实现邮件发送、订单通知等耗时操作的异步执行

功能扩展建议

  1. 推荐系统:基于用户行为数据实现协同过滤推荐算法,提升商品转化率
  2. 多商户支持:扩展角色体系支持供应商入驻,实现平台化运营模式
  3. 国际化支持:集成Spring MessageSource实现多语言界面,支持全球化业务拓展

技术架构升级

  1. 微服务化改造:将单体应用拆分为用户服务、商品服务、订单服务等独立微服务
  2. 容器化部署:采用Docker容器化部署,结合Kubernetes实现弹性伸缩
  3. 监控体系:集成Prometheus和Grafana构建完整的应用监控平台

系统通过严谨的架构设计和代码实现,提供了稳定可靠的电商平台基础功能。模块化设计为后续功能扩展奠定了良好基础,标准化的开发规范确保了代码的可维护性。随着业务规模的增长,可通过逐步实施上述优化方案提升系统性能和用户体验。

本文关键词
SpringBootJava在线商城管理系统源码解析MySQL

上下篇

上一篇
没有更多文章
下一篇
没有更多文章