基于SSM框架的服装租赁与库存管理系统 - 源码深度解析

JavaJavaScriptMavenHTMLCSSSSM框架MySQL
2026-03-114 浏览

文章摘要

本项目是一款基于SSM(Spring + Spring MVC + MyBatis)框架构建的服装租赁与库存管理系统,旨在为服装租赁商家提供一体化的业务运营与商品管理解决方案。其核心业务价值在于解决传统服装租赁行业中因手工记录、信息孤岛和流程繁琐导致的效率低下、库存数据不准确以及订单处理混乱等核心痛...

在服装租赁行业快速发展的背景下,传统手工管理模式已无法满足现代化运营需求。手工记录导致数据不一致、库存盘点困难、订单跟踪效率低下等问题日益突出。针对这些行业痛点,设计并实现了一套基于SSM框架的智能服装租赁与库存管理系统,该系统通过数字化手段实现了业务流程的全面优化。

系统采用经典的三层架构设计,Spring框架作为核心控制容器,负责依赖注入和事务管理;Spring MVC处理Web层请求响应,实现前后端分离;MyBatis作为数据持久层框架,通过XML配置实现灵活的SQL映射。前端采用HTML+CSS+JavaScript技术栈,结合Ajax实现异步数据交互,整体架构清晰、耦合度低。

管理员登录界面

数据库设计采用MySQL关系型数据库,共设计10张核心数据表。其中服装信息表(clothing)的设计体现了系统的专业性:

CREATE TABLE clothing (
    id INT PRIMARY KEY AUTO_INCREMENT,
    clothing_number VARCHAR(50) UNIQUE NOT NULL,
    name VARCHAR(100) NOT NULL,
    type_id INT NOT NULL,
    size VARCHAR(20),
    color VARCHAR(30),
    price DECIMAL(10,2) NOT NULL,
    stock_quantity INT DEFAULT 0,
    status ENUM('AVAILABLE','RENTED','MAINTENANCE') DEFAULT 'AVAILABLE',
    description TEXT,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (type_id) REFERENCES clothing_type(id)
);

该表通过状态字段实现服装生命周期管理,唯一编号确保每件服装的可追溯性,价格和库存数量字段为租赁计费提供数据支撑。时间戳字段自动记录数据变更,便于审计和数据分析。

租赁订单表(rental_order)的设计同样具有亮点:

CREATE TABLE rental_order (
    id INT PRIMARY KEY AUTO_INCREMENT,
    order_number VARCHAR(60) UNIQUE NOT NULL,
    customer_id INT NOT NULL,
    clothing_id INT NOT NULL,
    rental_date DATE NOT NULL,
    expected_return_date DATE NOT NULL,
    actual_return_date DATE,
    rental_days INT NOT NULL,
    total_amount DECIMAL(10,2) NOT NULL,
    deposit DECIMAL(10,2) DEFAULT 0,
    status ENUM('PENDING','ACTIVE','COMPLETED','OVERDUE') DEFAULT 'PENDING',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (customer_id) REFERENCES customer(id),
    FOREIGN KEY (clothing_id) REFERENCES clothing(id)
);

订单表通过状态机设计实现租赁流程控制,预计归还日期和实际归还日期的分离为逾期计算提供基础,押金字段支持灵活的收费策略。

在核心功能实现方面,服装信息管理模块通过分层架构实现了完整的数据操作。实体类设计遵循JavaBean规范:

@Entity
@Table(name = "clothing")
public class Clothing {
    private Integer id;
    private String clothingNumber;
    private String name;
    private ClothingType type;
    private String size;
    private String color;
    private BigDecimal price;
    private Integer stockQuantity;
    private String status;
    private String description;
    
    // Getter和Setter方法
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    
    @Column(name = "clothing_number", unique = true, nullable = false)
    public String getClothingNumber() { return clothingNumber; }
    public void setClothingNumber(String clothingNumber) { 
        this.clothingNumber = clothingNumber; 
    }
}

数据访问层采用MyBatis的注解方式实现CRUD操作:

@Mapper
public interface ClothingMapper {
    @Insert("INSERT INTO clothing(clothing_number, name, type_id, size, " +
            "color, price, stock_quantity, status, description) " +
            "VALUES(#{clothingNumber}, #{name}, #{type.id}, #{size}, " +
            "#{color}, #{price}, #{stockQuantity}, #{status}, #{description})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(Clothing clothing);
    
    @Update("UPDATE clothing SET name=#{name}, type_id=#{type.id}, " +
            "size=#{size}, color=#{color}, price=#{price}, " +
            "stock_quantity=#{stockQuantity}, status=#{status}, " +
            "description=#{description} WHERE id=#{id}")
    int update(Clothing clothing);
    
    @Select("SELECT c.*, ct.name as type_name FROM clothing c " +
            "LEFT JOIN clothing_type ct ON c.type_id = ct.id " +
            "WHERE c.id = #{id}")
    @Results({
        @Result(property = "type.id", column = "type_id"),
        @Result(property = "type.name", column = "type_name")
    })
    Clothing selectById(Integer id);
}

业务逻辑层封装了复杂的业务规则,确保数据一致性:

@Service
@Transactional
public class ClothingService {
    @Autowired
    private ClothingMapper clothingMapper;
    @Autowired
    private InventoryService inventoryService;
    
    public void addClothing(Clothing clothing) {
        // 验证服装编号唯一性
        if (clothingMapper.selectByNumber(clothing.getClothingNumber()) != null) {
            throw new BusinessException("服装编号已存在");
        }
        
        // 设置默认状态
        if (clothing.getStatus() == null) {
            clothing.setStatus("AVAILABLE");
        }
        
        // 插入服装记录
        clothingMapper.insert(clothing);
        
        // 初始化库存记录
        InventoryRecord record = new InventoryRecord();
        record.setClothingId(clothing.getId());
        record.setChangeType("INIT");
        record.setChangeQuantity(clothing.getStockQuantity());
        record.setRemarks("初始入库");
        inventoryService.addInventoryRecord(record);
    }
    
    public void updateStock(Integer clothingId, Integer quantity) {
        Clothing clothing = clothingMapper.selectById(clothingId);
        if (clothing == null) {
            throw new BusinessException("服装不存在");
        }
        
        int newStock = clothing.getStockQuantity() + quantity;
        if (newStock < 0) {
            throw new BusinessException("库存不足");
        }
        
        clothingMapper.updateStock(clothingId, newStock);
    }
}

控制层处理HTTP请求,提供RESTful API接口:

@Controller
@RequestMapping("/clothing")
public class ClothingController {
    @Autowired
    private ClothingService clothingService;
    
    @PostMapping("/add")
    @ResponseBody
    public Result addClothing(@Valid @RequestBody Clothing clothing, 
                             BindingResult result) {
        if (result.hasErrors()) {
            return Result.error(result.getFieldError().getDefaultMessage());
        }
        
        try {
            clothingService.addClothing(clothing);
            return Result.success("添加成功");
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        }
    }
    
    @GetMapping("/list")
    @ResponseBody
    public PageResult<Clothing> getClothingList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer limit,
            String keyword, Integer typeId) {
        
        PageHelper.startPage(page, limit);
        List<Clothing> list = clothingService.getClothingList(keyword, typeId);
        PageInfo<Clothing> pageInfo = new PageInfo<>(list);
        
        return new PageResult<>(pageInfo.getTotal(), list);
    }
}

服装信息管理

租赁管理模块实现了完整的业务流程控制。租赁订单创建服务包含复杂的业务逻辑验证:

@Service
public class RentalService {
    public RentalOrder createRentalOrder(RentalOrder order) {
        // 验证服装可用性
        Clothing clothing = clothingService.getById(order.getClothingId());
        if (!"AVAILABLE".equals(clothing.getStatus())) {
            throw new BusinessException("服装当前不可租赁");
        }
        
        if (clothing.getStockQuantity() <= 0) {
            throw new BusinessException("服装库存不足");
        }
        
        // 计算租赁费用
        BigDecimal totalAmount = calculateRentalAmount(
            clothing.getPrice(), order.getRentalDays());
        order.setTotalAmount(totalAmount);
        
        // 生成唯一订单号
        order.setOrderNumber(generateOrderNumber());
        
        // 保存订单记录
        rentalOrderMapper.insert(order);
        
        // 更新服装状态和库存
        clothingService.updateStock(order.getClothingId(), -1);
        clothingService.updateStatus(order.getClothingId(), "RENTED");
        
        return order;
    }
    
    private String generateOrderNumber() {
        return "RO" + System.currentTimeMillis() + 
               String.format("%04d", new Random().nextInt(10000));
    }
}

库存管理模块通过触发器式的设计实现库存变化的自动跟踪:

@Service
public class InventoryService {
    @Transactional
    public void processInventoryChange(InventoryChange change) {
        // 记录库存变更历史
        InventoryHistory history = new InventoryHistory();
        history.setClothingId(change.getClothingId());
        history.setChangeType(change.getChangeType());
        history.setChangeQuantity(change.getQuantity());
        history.setRemarks(change.getRemarks());
        inventoryHistoryMapper.insert(history);
        
        // 更新当前库存
        Clothing clothing = clothingMapper.selectById(change.getClothingId());
        int newStock = clothing.getStockQuantity() + change.getQuantity();
        clothingMapper.updateStock(change.getClothingId(), newStock);
        
        // 自动更新服装状态
        if (newStock > 0 && !"AVAILABLE".equals(clothing.getStatus())) {
            clothingMapper.updateStatus(change.getClothingId(), "AVAILABLE");
        } else if (newStock == 0) {
            clothingMapper.updateStatus(change.getClothingId(), "SOLD_OUT");
        }
    }
}

租赁记录查询

系统通过统一的异常处理机制保障稳定性:

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public Result handleBusinessException(BusinessException e) {
        return Result.error(e.getMessage());
    }
    
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result handleException(Exception e) {
        logger.error("系统异常:", e);
        return Result.error("系统繁忙,请稍后重试");
    }
}

public class Result {
    private boolean success;
    private String message;
    private Object data;
    
    public static Result success(Object data) {
        return new Result(true, "操作成功", data);
    }
    
    public static Result error(String message) {
        return new Result(false, message, null);
    }
}

用户管理和权限控制模块确保系统安全性:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    
    public User login(String username, String password) {
        User user = userMapper.selectByUsername(username);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        if (!password.equals(user.getPassword())) {
            throw new BusinessException("密码错误");
        }
        
        if (!"ACTIVE".equals(user.getStatus())) {
            throw new BusinessException("账户已被禁用");
        }
        
        return user;
    }
    
    @Transactional
    public void changePassword(Integer userId, String oldPassword, String newPassword) {
        User user = userMapper.selectById(userId);
        if (!oldPassword.equals(user.getPassword())) {
            throw new BusinessException("原密码错误");
        }
        
        userMapper.updatePassword(userId, newPassword);
    }
}

用户管理界面

系统在数据查询优化方面采用了多种策略。复杂查询通过MyBatis的动态SQL实现:

<select id="selectRentalOrders" parameterType="map" resultMap="RentalOrderResult">
    SELECT o.*, c.name as customer_name, cl.name as clothing_name
    FROM rental_order o
    LEFT JOIN customer c ON o.customer_id = c.id
    LEFT JOIN clothing cl ON o.clothing_id = cl.id
    <where>
        <if test="customerName != null and customerName != ''">
            AND c.name LIKE CONCAT('%', #{customerName}, '%')
        </if>
        <if test="clothingName != null and clothingName != ''">
            AND cl.name LIKE CONCAT('%', #{clothingName}, '%')
        </if>
        <if test="status != null and status != ''">
            AND o.status = #{status}
        </if>
        <if test="startDate != null">
            AND o.rental_date >= #{startDate}
        </if>
        <if test="endDate != null">
            AND o.rental_date <= #{endDate}
        </if>
    </where>
    ORDER BY o.create_time DESC
</select>

在系统性能优化方面,通过数据库索引设计和查询优化提升响应速度:

-- 为频繁查询的字段创建索引
CREATE INDEX idx_clothing_type ON clothing(type_id);
CREATE INDEX idx_clothing_status ON clothing(status);
CREATE INDEX idx_rental_order_date ON rental_order(rental_date);
CREATE INDEX idx_rental_order_status ON rental_order(status);
CREATE INDEX idx_customer_name ON customer(name);

针对未来系统扩展,可以考虑以下几个优化方向:首先,引入Redis缓存层,将热点数据如服装分类、用户信息等缓存至内存,减少数据库访问压力。实现方案可以通过Spring Cache注解统一管理缓存策略。

其次,开发移动端应用,通过RESTful API为手机客户端提供数据接口,使用JWT令牌实现跨平台身份认证。移动端可以重点实现扫码租赁、移动支付等便捷功能。

第三,集成智能预警系统,基于历史租赁数据建立预测模型,实现库存预警、租赁高峰期预测等功能。可以通过Spring Batch处理批量数据,使用Quartz调度定时分析任务。

第四,引入微服务架构重构系统,将用户服务、库存服务、订单服务等拆分为独立微服务,通过Spring Cloud实现服务治理,提升系统可扩展性和容错能力。

最后,增强数据分析功能,利用ELK栈实现操作日志分析,通过数据可视化技术展示经营指标,为管理决策提供数据支持。可以集成ECharts等前端图表库实现丰富的可视化效果。

系统通过严谨的架构设计和细致的功能实现,为服装租赁行业提供了完整的数字化解决方案。模块化的设计使得系统具有良好的可维护性和扩展性,为后续功能迭代奠定了坚实的技术基础。

本文关键词
SSM框架服装租赁库存管理系统源码解析数据库设计

上下篇

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