基于SSH框架的电子产品在线销售平台 - 源码深度解析

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

文章摘要

本项目是一款基于SSH(Struts2 + Spring + Hibernate)整合框架构建的电子产品在线销售平台,旨在为电子设备零售商或品牌商提供一个功能完整、稳定可靠的B2C电子商务解决方案。其核心业务价值在于通过标准化的在线商城系统,有效解决传统线下销售模式中渠道单一、库存管理效率低下、客户...

在当今电子商务蓬勃发展的时代,传统电子产品零售商面临着渠道单一、库存管理效率低下和客户触达范围有限等多重挑战。针对这些痛点,采用SSH(Struts2 + Spring + Hibernate)整合框架开发的电子产品在线销售平台应运而生,为企业提供了一个功能完备、稳定可靠的B2C电子商务解决方案。

系统架构与技术栈

该平台采用经典的三层架构设计,通过成熟的Java EE技术栈实现高内聚、低耦合的系统结构。表现层使用Struts2框架处理用户请求和页面跳转,利用其拦截器机制实现统一的权限验证和数据校验。业务逻辑层由Spring框架的IoC容器管理,通过依赖注入方式解耦各个Service组件,如商品查询服务、订单生成服务等。数据持久层依托Hibernate实现对象关系映射,通过HQL语言简化复杂查询操作,并利用缓存机制提升数据访问性能。

技术栈配置如下:

<!-- Struts2核心依赖 -->
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>2.5.30</version>
</dependency>

<!-- Spring框架依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.3.18</version>
</dependency>

<!-- Hibernate依赖 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.6.10.Final</version>
</dependency>

数据库设计亮点

订单表设计优化

订单表(indent)的设计体现了电商系统对数据完整性和查询性能的深度考量:

CREATE TABLE `indent` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `total` float DEFAULT NULL COMMENT '总价',
  `amount` int(11) DEFAULT NULL COMMENT '商品总数',
  `status` tinyint(4) DEFAULT 1 COMMENT '订单状态(1未付款/2已付款/3已发货/4已完成)',
  `paytype` tinyint(4) DEFAULT 0 COMMENT '支付方式 (1微信/2支付宝/3货到付款)',
  `systime` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '下单时间',
  `user_id` int(11) DEFAULT NULL COMMENT '下单用户',
  `name` varchar(11) DEFAULT NULL COMMENT '收货人姓名',
  `idcardno` varchar(20) DEFAULT NULL COMMENT '身份证号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='订单表'

该表设计具有以下技术亮点:

  • 状态字段优化:使用tinyint类型存储订单状态和支付方式,既节省存储空间又提高查询效率
  • 时间戳管理:systime字段采用timestamp类型并设置自动更新机制,确保订单状态变更时间准确记录
  • 索引策略:主键id自增设计配合InnoDB引擎的聚簇索引,保证订单数据的物理存储顺序与逻辑顺序一致

商品表关系设计

商品相关的表结构设计展现了良好的范式规范和扩展性:

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL COMMENT '名称',
  `cover` varchar(255) DEFAULT NULL COMMENT '封面',
  `price` float DEFAULT NULL COMMENT '价格',
  `intro` varchar(255) DEFAULT NULL COMMENT '介绍',
  `stock` int(11) DEFAULT NULL COMMENT '库存',
  `category_id` int(11) DEFAULT NULL COMMENT '分类',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='商品表'

CREATE TABLE `product_show` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` int(11) DEFAULT NULL COMMENT '商品ID',
  `showtext` varchar(255) DEFAULT NULL COMMENT '展示图片',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='商品展示表'

这种分离设计实现了商品基本信息与展示内容的解耦,支持一个商品对应多个展示图片的需求,符合第三范式要求。

商品管理界面

核心功能实现

用户购物车管理

购物车功能通过shopcart表实现用户商品的临时存储,关键代码如下:

// 购物车实体类
@Entity
@Table(name="shopcart")
public class ShopCart {
    @Id
    @GeneratedValue
    private int id;
    private int amount;
    
    @ManyToOne
    @JoinColumn(name="product_id")
    private Product product;
    
    @ManyToOne
    @JoinColumn(name="user_id")
    private User user;
    
    // getter和setter方法
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public int getAmount() { return amount; }
    public void setAmount(int amount) { this.amount = amount; }
    public Product getProduct() { return product; }
    public void setProduct(Product product) { this.product = product; }
    public User getUser() { return user; }
    public void setUser(User user) { this.user = user; }
}

// 购物车Service实现
@Service
@Transactional
public class ShopCartService {
    @Autowired
    private ShopCartDAO shopCartDAO;
    
    public void addToCart(Product product, User user, int amount) {
        ShopCart existingItem = shopCartDAO.findByUserAndProduct(user, product);
        if (existingItem != null) {
            existingItem.setAmount(existingItem.getAmount() + amount);
            shopCartDAO.update(existingItem);
        } else {
            ShopCart newItem = new ShopCart();
            newItem.setProduct(product);
            newItem.setUser(user);
            newItem.setAmount(amount);
            shopCartDAO.save(newItem);
        }
    }
    
    public List<ShopCart> getCartItems(User user) {
        return shopCartDAO.findByUser(user);
    }
}

加入购物车界面

订单处理流程

订单生成和处理是电商平台的核心业务,实现代码展示了Struts2 Action与Spring Service的整合:

// 订单Action控制器
@Controller
@Scope("prototype")
public class IndentAction extends ActionSupport {
    private Indent indent;
    private List<ShopCart> cartItems;
    
    @Autowired
    private IndentService indentService;
    
    @Autowired
    private ShopCartService shopCartService;
    
    // 生成订单方法
    public String createIndent() {
        try {
            // 获取当前用户购物车商品
            User user = (User) ActionContext.getContext().getSession().get("currentUser");
            cartItems = shopCartService.getCartItems(user);
            
            // 计算总价和商品数量
            float total = 0;
            int amount = 0;
            for (ShopCart item : cartItems) {
                total += item.getProduct().getPrice() * item.getAmount();
                amount += item.getAmount();
            }
            
            // 设置订单信息
            indent.setTotal(total);
            indent.setAmount(amount);
            indent.setUser(user);
            indent.setStatus(1); // 未付款状态
            indent.setSystime(new Date());
            
            // 保存订单
            indentService.createIndent(indent, cartItems);
            
            // 清空购物车
            shopCartService.clearCart(user);
            
            return SUCCESS;
        } catch (Exception e) {
            addActionError("订单生成失败: " + e.getMessage());
            return ERROR;
        }
    }
    
    // getter和setter方法
    public Indent getIndent() { return indent; }
    public void setIndent(Indent indent) { this.indent = indent; }
}

// 订单Service业务逻辑
@Service
@Transactional
public class IndentService {
    @Autowired
    private IndentDAO indentDAO;
    
    @Autowired
    private ProductDAO productDAO;
    
    public void createIndent(Indent indent, List<ShopCart> cartItems) {
        // 保存订单主信息
        indentDAO.save(indent);
        
        // 保存订单明细并更新库存
        for (ShopCart item : cartItems) {
            IndentDetail detail = new IndentDetail();
            detail.setIndent(indent);
            detail.setProduct(item.getProduct());
            detail.setAmount(item.getAmount());
            detail.setPrice(item.getProduct().getPrice());
            
            // 更新商品库存
            Product product = item.getProduct();
            product.setStock(product.getStock() - item.getAmount());
            productDAO.update(product);
        }
    }
}

订单提交界面

商品展示与详情管理

商品详情页通过多表关联查询实现丰富的内容展示:

// 商品详情Action
@Controller
@Scope("prototype")
public class ProductAction extends ActionSupport {
    private int productId;
    private Product product;
    private List<ProductShow> showImages;
    
    @Autowired
    private ProductService productService;
    
    public String detail() {
        product = productService.getProductById(productId);
        showImages = productService.getProductShowImages(productId);
        return SUCCESS;
    }
    
    // 商品列表分页查询
    public String list() {
        Map<String, Object> params = new HashMap<>();
        if (categoryId > 0) {
            params.put("categoryId", categoryId);
        }
        
        Page<Product> page = productService.getProductsByPage(currentPage, pageSize, params);
        // 设置分页数据到值栈
        getValueStack().set("productPage", page);
        
        return SUCCESS;
    }
}

// 商品Service实现
@Service
@Transactional
public class ProductService {
    @Autowired
    private ProductDAO productDAO;
    
    @Autowired
    private ProductShowDAO productShowDAO;
    
    public Product getProductById(int id) {
        return productDAO.findById(id);
    }
    
    public List<ProductShow> getProductShowImages(int productId) {
        String hql = "FROM ProductShow WHERE product_id = :productId ORDER BY id";
        return productShowDAO.find(hql, Map.of("productId", productId));
    }
    
    public Page<Product> getProductsByPage(int page, int size, Map<String, Object> params) {
        StringBuilder hql = new StringBuilder("FROM Product WHERE 1=1");
        Map<String, Object> queryParams = new HashMap<>();
        
        if (params.containsKey("categoryId")) {
            hql.append(" AND category_id = :categoryId");
            queryParams.put("categoryId", params.get("categoryId"));
        }
        
        hql.append(" ORDER BY id DESC");
        
        return productDAO.findPage(hql.toString(), page, size, queryParams);
    }
}

商品详情页

管理员权限控制

后台管理系统通过Struts2拦截器实现权限验证:

// 管理员权限拦截器
public class AdminAuthInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        ActionContext context = invocation.getInvocationContext();
        HttpSession session = (HttpSession) context.get(ServletActionContext.HTTP_SESSION);
        
        Admin admin = (Admin) session.getAttribute("admin");
        if (admin == null) {
            // 未登录,跳转到登录页
            return "login";
        }
        
        // 检查权限
        String actionName = invocation.getProxy().getActionName();
        if (!hasPermission(admin, actionName)) {
            throw new Exception("权限不足");
        }
        
        return invocation.invoke();
    }
    
    private boolean hasPermission(Admin admin, String actionName) {
        // 根据管理员角色和请求的action进行权限验证
        // 实现具体的权限逻辑
        return true;
    }
}

// Struts2配置
<struts>
    <package name="admin" namespace="/admin" extends="struts-default">
        <interceptors>
            <interceptor name="auth" class="com.interceptor.AdminAuthInterceptor"/>
            <interceptor-stack name="adminStack">
                <interceptor-ref name="auth"/>
                <interceptor-ref name="defaultStack"/>
            </interceptor-stack>
        </interceptors>
        
        <default-interceptor-ref name="adminStack"/>
        
        <action name="product_*" class="productAction" method="{1}">
            <result name="success">/admin/product_list.jsp</result>
            <result name="login">/admin/login.jsp</result>
        </action>
    </package>
</struts>

管理员登录

实体模型设计

系统采用JPA注解方式进行实体关系映射,确保对象模型与数据库表结构的精确对应:

// 订单实体类
@Entity
@Table(name = "indent")
public class Indent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    private Float total;
    private Integer amount;
    
    @Column(name = "status")
    private Byte status;
    
    @Column(name = "paytype")
    private Byte paytype;
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date systime;
    
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
    
    private String name;
    private String idcardno;
    
    @OneToMany(mappedBy = "indent", cascade = CascadeType.ALL)
    private Set<IndentDetail> details = new HashSet<>();
    
    // 枚举类型定义订单状态
    public static class Status {
        public static final byte UNPAID = 1;
        public static final byte PAID = 2;
        public static final byte SHIPPED = 3;
        public static final byte COMPLETED = 4;
    }
    
    // getter和setter方法
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    // 其他getter/setter方法...
}

// Spring配置整合
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.service")
public class AppConfig {
    @Bean
    public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setPackagesToScan("com.entity");
        
        Properties hibernateProperties = new Properties();
        hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
        hibernateProperties.setProperty("hibernate.show_sql", "true");
        hibernateProperties.setProperty("hibernate.format_sql", "true");
        hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");
        
        sessionFactory.setHibernateProperties(hibernateProperties);
        return sessionFactory;
    }
    
    @Bean
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory);
        return transactionManager;
    }
}

功能展望与优化

基于当前系统架构,以下优化方向可进一步提升平台性能和用户体验:

1. 引入Redis缓存层

// 商品信息缓存示例
@Service
public class ProductCacheService {
    @Autowired
    private RedisTemplate<String, Product> redisTemplate;
    
    private static final String PRODUCT_KEY_PREFIX = "product:";
    private static final long CACHE_EXPIRE = 3600; // 1小时
    
    public Product getProductById(int id) {
        String key = PRODUCT_KEY_PREFIX + id;
        Product product = redisTemplate.opsForValue().get(key);
        if (product == null) {
            product = productDAO.findById(id);
            if (product != null) {
                redisTemplate.opsForValue().set(key, product, CACHE_EXPIRE, TimeUnit.SECONDS);
            }
        }
        return product;
    }
}

2. 微服务架构改造

将单体应用拆分为商品服务、订单服务、用户服务等独立微服务,通过Spring Cloud实现服务治理:

# 商品服务配置
spring:
  application:
    name: product-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

# API网关路由配置
spring:
  cloud:
    gateway:
      routes:
        - id: product-service
          uri: lb://product-service
          predicates:
            - Path=/api/products/**

3. Elasticsearch搜索集成

实现商品全文检索和高级搜索功能:

// 商品搜索服务
@Service
public class ProductSearchService {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;
    
    public Page<Product> searchProducts(String keyword, int page, int size) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        
        queryBuilder.withQuery(QueryBuilders.multiMatchQuery(keyword, "name", "intro", "category.name"))
                   .withPageable(PageRequest.of(page, size))
                   .withSort(SortBuilders.scoreSort());
        
        SearchHits<Product> searchHits = elasticsearchTemplate.search(queryBuilder.build(), Product.class);
        return new PageImpl<>(searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList()),
                             PageRequest.of(page, size), searchHits.getTotalHits());
    }
}

4. 消息队列异步处理

使用RabbitMQ处理订单创建、库存更新等异步操作:

// 订单消息生产者
@Component
public class OrderMessageProducer {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    public void sendOrderCreatedMessage(Indent indent) {
        OrderMessage message = new OrderMessage(indent.getId(), indent.getTotal(), indent.getUser().getId());
        rabbitTemplate
本文关键词
SSH框架电子产品在线销售平台源码解析数据库设计

上下篇

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