基于SSH框架的仓库信息管理系统 - 源码深度解析

JavaJavaScriptSSH框架HTMLCSSMySQLJSP+Servlet
2026-02-283 浏览

文章摘要

本系统是一款基于SSH(Struts2 + Spring + Hibernate)整合框架开发的仓库信息管理软件,旨在解决中小型企业在仓储管理环节中普遍存在的信息记录混乱、库存数据更新不及时、人工操作效率低下等核心痛点。系统通过数字化的入库、出库、盘点流程,将实物库存与信息流高度统一,为企业提供准确...

仓储管理作为企业供应链的核心环节,其效率直接影响到企业的运营成本与客户满意度。针对中小型企业在仓储管理中普遍存在的信息记录混乱、库存数据更新滞后、人工操作效率低下等痛点,本文介绍了一套基于SSH(Struts2 + Spring + Hibernate)整合框架开发的智能仓储管理平台。该系统通过数字化的业务流程,实现了实物库存与信息流的高度统一,为企业提供准确的库存视图和完整的操作追溯能力。

系统架构与技术栈

该平台采用经典的三层架构设计,严格分离表现层、业务逻辑层和数据持久层。表现层基于Struts2框架构建,通过配置struts.xml文件定义前端请求与后端Action方法的映射关系。Struts2的拦截器机制实现了统一的权限验证和操作日志记录,确保系统的安全性和可审计性。

业务逻辑层由Spring框架的IoC容器负责管理,通过依赖注入(DI)将各个Service组件及DAO层对象进行组装。事务管理采用Spring的声明式事务配置,在Service层实现,保证了业务操作的原子性。这种设计使得业务逻辑组件之间的耦合度降到最低,提高了代码的可测试性和可维护性。

数据持久层基于Hibernate ORM框架实现,通过实体类的映射文件将Java对象与数据库表关联。Hibernate的HQL语言以及Criteria查询API简化了复杂的数据检索操作,避免了手写繁琐的SQL语句。同时,Hibernate的一级缓存和二级缓存机制有效提升了数据访问性能。

数据库设计亮点分析

系统数据库包含7个核心表,设计合理,关系清晰。以下重点分析几个关键表的设计:

商品信息表(product)的设计体现了完整的库存管理需求:

CREATE TABLE `product` (
  `product_id` int(11) NOT NULL AUTO_INCREMENT,
  `product_name` varchar(100) NOT NULL,
  `product_model` varchar(50) DEFAULT NULL,
  `unit` varchar(10) DEFAULT NULL,
  `price` decimal(10,2) DEFAULT NULL,
  `stock_quantity` int(11) DEFAULT '0',
  `remark` varchar(500) DEFAULT NULL,
  `category_id` int(11) DEFAULT NULL,
  `manufacturer_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`product_id`),
  KEY `fk_product_category` (`category_id`),
  KEY `fk_product_manufacturer` (`manufacturer_id`),
  CONSTRAINT `fk_product_category` FOREIGN KEY (`category_id`) 
    REFERENCES `product_category` (`category_id`),
  CONSTRAINT `fk_product_manufacturer` FOREIGN KEY (`manufacturer_id`) 
    REFERENCES `manufacturer` (`manufacturer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

该表设计包含商品基本属性、库存数量、价格信息,并通过外键关联商品分类和制造商表。stock_quantity字段实时反映当前库存数量,为库存预警和补货决策提供数据支持。价格字段采用decimal(10,2)类型,确保金额计算的精确性。

入库记录表(stock_in)的设计支持完整的入库流程追踪:

CREATE TABLE `stock_in` (
  `in_id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` int(11) NOT NULL,
  `in_quantity` int(11) NOT NULL,
  `in_date` datetime NOT NULL,
  `handler` varchar(50) NOT NULL,
  `remark` varchar(500) DEFAULT NULL,
  `purchase_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`in_id`),
  KEY `fk_stockin_product` (`product_id`),
  KEY `fk_stockin_purchase` (`purchase_id`),
  CONSTRAINT `fk_stockin_product` FOREIGN KEY (`product_id`) 
    REFERENCES `product` (`product_id`),
  CONSTRAINT `fk_stockin_purchase` FOREIGN KEY (`purchase_id`) 
    REFERENCES `purchase` (`purchase_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

该表记录了每次入库的详细信息,包括入库商品、数量、时间、经手人等,并与采购记录关联,实现了从采购到入库的完整链路追踪。时间戳字段为库存周转率分析提供了数据基础。

核心功能实现深度解析

商品信息管理模块

商品管理作为系统的基础模块,实现了商品的增删改查、分类管理和库存监控功能。通过Struts2的Action类处理前端请求,Spring Service层实现业务逻辑,Hibernate完成数据持久化。

商品查询功能的Service层实现:

@Service("productService")
@Transactional
public class ProductServiceImpl implements ProductService {
    
    @Autowired
    private ProductDAO productDAO;
    
    @Override
    public List<Product> findProductsByCriteria(String productName, 
                                              Integer categoryId, 
                                              Integer manufacturerId) {
        DetachedCriteria criteria = DetachedCriteria.forClass(Product.class);
        
        if (StringUtils.isNotBlank(productName)) {
            criteria.add(Restrictions.like("productName", "%" + productName + "%"));
        }
        if (categoryId != null && categoryId > 0) {
            criteria.add(Restrictions.eq("category.categoryId", categoryId));
        }
        if (manufacturerId != null && manufacturerId > 0) {
            criteria.add(Restrictions.eq("manufacturer.manufacturerId", manufacturerId));
        }
        
        criteria.addOrder(Order.asc("productName"));
        return productDAO.findByCriteria(criteria);
    }
    
    @Override
    public Product getProductWithDetails(Integer productId) {
        Product product = productDAO.findById(productId);
        // 初始化懒加载关联对象
        Hibernate.initialize(product.getCategory());
        Hibernate.initialize(product.getManufacturer());
        return product;
    }
}

该服务方法利用Hibernate的Criteria API构建动态查询条件,支持按商品名称、分类、制造商等多条件组合查询。@Transactional注解确保方法在事务环境中执行,保证数据一致性。

商品管理界面

采购入库流程实现

采购入库模块实现了从采购计划到实物入库的完整业务流程。系统通过工作流方式确保每个环节的数据准确性和操作规范性。

入库操作的Action控制类:

public class StockInAction extends ActionSupport {
    private StockIn stockIn;
    private List<Product> productList;
    private StockInService stockInService;
    private ProductService productService;
    
    // 准备入库页面数据
    public String prepareStockIn() {
        productList = productService.findAllActiveProducts();
        return SUCCESS;
    }
    
    // 执行入库操作
    public String executeStockIn() {
        try {
            // 验证入库数量
            if (stockIn.getInQuantity() <= 0) {
                addActionError("入库数量必须大于0");
                return INPUT;
            }
            
            // 设置入库时间
            stockIn.setInDate(new Date());
            
            // 调用服务层完成入库
            stockInService.processStockIn(stockIn);
            
            addActionMessage("入库操作成功完成");
            return SUCCESS;
            
        } catch (Exception e) {
            addActionError("入库操作失败: " + e.getMessage());
            return ERROR;
        }
    }
    
    // Getter和Setter方法
    public StockIn getStockIn() { return stockIn; }
    public void setStockIn(StockIn stockIn) { this.stockIn = stockIn; }
    
    @Autowired
    public void setStockInService(StockInService stockInService) {
        this.stockInService = stockInService;
    }
    
    @Autowired
    public void setProductService(ProductService productService) {
        this.productService = productService;
    }
}

该Action类通过Spring的依赖注入获取服务层实例,实现了入库操作的完整控制流程。输入验证、业务处理、异常处理等环节都得到了妥善处理。

入库服务的核心业务逻辑:

@Service("stockInService")
@Transactional
public class StockInServiceImpl implements StockInService {
    
    @Autowired
    private StockInDAO stockInDAO;
    
    @Autowired
    private ProductDAO productDAO;
    
    @Override
    public void processStockIn(StockIn stockIn) {
        // 1. 保存入库记录
        stockInDAO.save(stockIn);
        
        // 2. 更新商品库存数量
        Product product = productDAO.findById(stockIn.getProduct().getProductId());
        int newQuantity = product.getStockQuantity() + stockIn.getInQuantity();
        product.setStockQuantity(newQuantity);
        productDAO.update(product);
        
        // 3. 记录操作日志
        logStockInOperation(stockIn, product);
    }
    
    private void logStockInOperation(StockIn stockIn, Product product) {
        // 记录详细的入库日志,用于审计和追溯
        SystemLogger.info("入库操作: 商品[" + product.getProductName() + 
                         "], 数量[" + stockIn.getInQuantity() + 
                         "], 操作人[" + stockIn.getHandler() + "]");
    }
}

该服务方法在@Transactional注解的保护下,确保入库记录保存和库存数量更新这两个操作要么全部成功,要么全部回滚,保证了数据的原子性。

采购入库管理

出库发货管理

出库管理模块处理销售出库、调拨出库等多种出库类型,确保库存数据的实时准确更新。

出库验证与库存扣减逻辑:

@Service("shipmentService")
@Transactional
public class ShipmentServiceImpl implements ShipmentService {
    
    @Override
    public ShipmentResult processShipment(Shipment shipment) {
        ShipmentResult result = new ShipmentResult();
        
        try {
            // 验证库存充足性
            Product product = productDAO.findById(shipment.getProduct().getProductId());
            if (product.getStockQuantity() < shipment.getShipQuantity()) {
                result.setSuccess(false);
                result.setMessage("库存不足,当前库存: " + product.getStockQuantity());
                return result;
            }
            
            // 执行出库操作
            executeShipment(shipment, product);
            
            result.setSuccess(true);
            result.setMessage("出库操作成功完成");
            
        } catch (Exception e) {
            result.setSuccess(false);
            result.setMessage("出库操作失败: " + e.getMessage());
            // 事务将自动回滚
        }
        
        return result;
    }
    
    private void executeShipment(Shipment shipment, Product product) {
        // 保存出库记录
        shipment.setShipDate(new Date());
        shipmentDAO.save(shipment);
        
        // 扣减库存
        int newQuantity = product.getStockQuantity() - shipment.getShipQuantity();
        product.setStockQuantity(newQuantity);
        productDAO.update(product);
        
        // 库存预警检查
        checkStockWarning(product);
    }
}

出库操作首先进行库存验证,防止超卖情况发生。库存扣减后自动触发库存预警检查,为库存补货提供及时提醒。

出库发货管理

用户权限管理

系统采用基于角色的访问控制(RBAC)模型,不同的用户角色拥有不同的操作权限。

用户权限验证拦截器:

public class AuthorizationInterceptor extends AbstractInterceptor {
    
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        // 获取当前Action的注解信息
        Class<?> actionClass = invocation.getAction().getClass();
        PermissionRequired permission = actionClass.getAnnotation(PermissionRequired.class);
        
        if (permission != null) {
            // 从Session中获取当前用户信息
            User currentUser = (User) invocation.getInvocationContext()
                    .getSession().get("currentUser");
                    
            if (currentUser == null) {
                return "login"; // 跳转到登录页面
            }
            
            // 检查用户权限
            if (!hasPermission(currentUser, permission.value())) {
                return "unauthorized"; // 权限不足页面
            }
        }
        
        return invocation.invoke();
    }
    
    private boolean hasPermission(User user, String requiredPermission) {
        // 检查用户角色是否包含所需权限
        return user.getRole().getPermissions()
                .stream()
                .anyMatch(p -> p.getPermissionCode().equals(requiredPermission));
    }
}

该拦截器在每次Action执行前进行权限验证,确保只有授权用户才能访问相应功能。通过注解方式声明权限要求,使权限控制更加灵活和精确。

用户管理界面

实体模型与数据持久化

系统采用面向对象的领域模型设计,通过Hibernate实现对象关系映射。每个实体类对应数据库中的一张表,实体之间的关系通过关联映射实现。

商品实体类的Hibernate映射配置:

<hibernate-mapping>
    <class name="com.warehouse.entity.Product" table="product">
        <id name="productId" column="product_id" type="integer">
            <generator class="identity"/>
        </id>
        
        <property name="productName" column="product_name" 
                 type="string" length="100" not-null="true"/>
        <property name="productModel" column="product_model" 
                 type="string" length="50"/>
        <property name="unit" column="unit" type="string" length="10"/>
        <property name="price" column="price" type="big_decimal"/>
        <property name="stockQuantity" column="stock_quantity" 
                 type="integer" not-null="true"/>
        <property name="remark" column="remark" type="string" length="500"/>
        
        <!-- 多对一关联:商品分类 -->
        <many-to-one name="category" column="category_id" 
                    class="com.warehouse.entity.ProductCategory"
                    not-null="false" lazy="false"/>
        
        <!-- 多对一关联:制造商 -->
        <many-to-one name="manufacturer" column="manufacturer_id" 
                    class="com.warehouse.entity.Manufacturer"
                    not-null="false" lazy="false"/>
        
        <!-- 一对多关联:入库记录 -->
        <set name="stockInRecords" inverse="true" lazy="true">
            <key column="product_id"/>
            <one-to-many class="com.warehouse.entity.StockIn"/>
        </set>
        
        <!-- 一对多关联:出库记录 -->
        <set name="shipmentRecords" inverse="true" lazy="true">
            <key column="product_id"/>
            <one-to-many class="com.warehouse.entity.Shipment"/>
        </set>
    </class>
</hibernate-mapping>

该映射配置定义了商品实体的完整属性映射和关联关系。通过lazy属性控制关联对象的加载策略,在保证性能的同时满足不同的数据访问需求。

基于Hibernate的通用DAO实现:

@Repository
public class BaseDAOImpl<T> implements BaseDAO<T> {
    
    @Autowired
    private SessionFactory sessionFactory;
    
    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }
    
    @Override
    public T findById(Serializable id, Class<T> entityClass) {
        return (T) getCurrentSession().get(entityClass, id);
    }
    
    @Override
    public List<T> findAll(Class<T> entityClass) {
        Criteria criteria = getCurrentSession().createCriteria(entityClass);
        criteria.addOrder(Order.asc("id"));
        return criteria.list();
    }
    
    @Override
    public void save(T entity) {
        getCurrentSession().saveOrUpdate(entity);
    }
    
    @Override
    public void delete(T entity) {
        getCurrentSession().delete(entity);
    }
    
    @Override
    public List<T> findByCriteria(DetachedCriteria criteria) {
        Criteria executableCriteria = criteria.getExecutableCriteria(getCurrentSession());
        return executableCriteria.list();
    }
}

该通用DAO基类封装了常用的数据访问操作,提供了类型安全的数据访问接口。通过泛型技术实现了代码的重用,减少了重复的DAO实现代码。

系统配置与集成

系统的整体配置通过Spring的ApplicationContext统一管理,各层组件通过依赖注入方式组装。

Spring应用上下文的核心配置:

<beans xmlns="http://www.springframework.org/schema/beans">
    
    <!-- 数据源配置 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/warehouse_db"/>
        <property name="username" value="warehouse_user"/>
        <property name="password" value="warehouse_pass"/>
        <property name="initialSize" value="5"/>
        <property name="maxActive" value="20"/>
    </bean>
    
    <!-- SessionFactory配置 -->
    <bean id="sessionFactory" 
          class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>com/warehouse/entity/Product.hbm.xml</value>
                <value>com/warehouse/entity/StockIn.hbm.xml</value>
                <!-- 其他实体映射文件 -->
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>
    
    <!-- 事务管理器配置 -->
    <bean id="transactionManager"
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <!-- 声明式事务配置 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*"
本文关键词
SSH框架仓库信息管理系统仓储管理源码解析数据库设计

上下篇

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