在传统婚纱租赁行业中,商家长期依赖手工登记簿管理婚纱库存和客户预约,客户则需要亲自到店才能了解有限的婚纱款式。这种模式不仅效率低下,也限制了业务的拓展空间。囍·遇婚纱馆在线预订系统应运而生,旨在通过数字化手段重构婚纱租赁业务流程。
该系统采用B/S架构,构建了一个集产品展示、在线预订、订单管理于一体的企业级婚纱租赁管理平台。前端使用JSP动态页面技术结合HTML、CSS和JavaScript实现用户交互界面,后端基于Servlet控制器处理业务逻辑,数据持久层通过JDBC与MySQL数据库进行交互。整个系统严格遵循MVC设计模式,实现了展示层、业务逻辑层和数据访问层的清晰分离。
系统架构与技术栈深度解析
该平台的技术选型体现了经典Java Web开发的最佳实践。Servlet作为控制器核心,负责接收HTTP请求、调用业务逻辑处理,并选择合适的JSP视图进行响应。这种架构确保了代码的良好组织性和可维护性。
// 用户登录Servlet示例
@WebServlet("/user/login")
public class UserLoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
UserService userService = new UserServiceImpl();
User user = userService.login(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect("index.jsp");
} else {
request.setAttribute("msg", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
}
服务层封装了核心业务逻辑,如婚纱预订过程中的库存检查、价格计算和日期冲突验证等复杂操作:
// 订单服务实现
public class OrderServiceImpl implements OrderService {
private OrderDAO orderDAO = new OrderDAOImpl();
private GoodsDAO goodsDAO = new GoodsDAOImpl();
@Override
public boolean createOrder(Order order, List<OrderItem> items) {
Connection conn = null;
try {
conn = DBUtil.getConnection();
conn.setAutoCommit(false);
// 检查库存
for (OrderItem item : items) {
Goods goods = goodsDAO.findById(item.getGoodsId());
if (goods.getStock() < item.getAmount()) {
throw new RuntimeException("商品库存不足: " + goods.getName());
}
}
// 创建订单
orderDAO.save(conn, order);
// 创建订单项并更新库存
for (OrderItem item : items) {
item.setOrderId(order.getId());
orderDAO.saveItem(conn, item);
goodsDAO.updateStock(conn, item.getGoodsId(),
-item.getAmount());
}
conn.commit();
return true;
} catch (Exception e) {
if (conn != null) {
try { conn.rollback(); } catch (SQLException ex) {}
}
return false;
}
}
}
数据库设计亮点分析
商品表(goods)的规范化设计
商品表的设计体现了良好的数据库规范化原则。通过type_id外键关联到类型表,实现了商品分类的标准化管理。这种设计支持灵活的商品分类体系,便于扩展新的婚纱类别。
CREATE TABLE `goods` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品ID',
`name` varchar(45) DEFAULT NULL COMMENT '商品名称',
`cover` varchar(45) DEFAULT NULL COMMENT '商品封面图',
`image1` varchar(45) DEFAULT NULL COMMENT '商品图片1',
`image2` varchar(45) DEFAULT NULL COMMENT '商品图片2',
`price` float DEFAULT NULL COMMENT '商品价格',
`intro` varchar(300) DEFAULT NULL COMMENT '商品介绍',
`stock` int(11) DEFAULT NULL COMMENT '商品库存',
`type_id` int(11) DEFAULT NULL COMMENT '商品类型ID',
PRIMARY KEY (`id`),
KEY `fk_type_id_idx` (`type_id`),
CONSTRAINT `fk_type_id` FOREIGN KEY (`type_id`) REFERENCES `type` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=216 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='商品表'
字段设计考虑到了实际业务需求:cover字段存储封面图路径,image1和image2支持多图展示,intro字段的300字符长度充分满足商品描述需求。stock字段的整数类型确保了库存管理的精确性。
订单项表(orderitem)的事务完整性
订单项表采用与主订单表分离的设计,支持一个订单包含多件婚纱的复杂业务场景。这种设计遵循了数据库第三范式,避免了数据冗余。
CREATE TABLE `orderitem` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单项ID',
`price` float DEFAULT NULL COMMENT '商品单价',
`price` float DEFAULT NULL COMMENT '商品单价',
`amount` int(11) DEFAULT NULL COMMENT '商品数量',
`goods_id` int(11) DEFAULT NULL COMMENT '商品ID',
`order_id` int(11) DEFAULT NULL COMMENT '订单ID',
PRIMARY KEY (`id`),
KEY `fk_order_id_idx` (`order_id`),
KEY `fk_orderitem_goods_id_idx` (`goods_id`),
CONSTRAINT `fk_order_id` FOREIGN KEY (`order_id`) REFERENCES `order` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_orderitem_goods_id` FOREIGN KEY (`goods_id`) REFERENCES `goods` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='订单项表'
外键约束确保了数据的引用完整性,当尝试删除已被订单引用的商品时,数据库会阻止该操作。索引的合理设置优化了订单查询性能,特别是在处理大量历史订单数据时效果显著。
推荐表(recommend)的灵活架构
推荐表设计支持多种推荐类型,通过type字段区分首页推荐、热门推荐等不同场景。这种设计为后续推荐算法的升级预留了空间。
CREATE TABLE `recommend` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '推荐ID',
`type` tinyint(1) DEFAULT NULL COMMENT '推荐类型',
`goods_id` int(11) DEFAULT NULL COMMENT '商品ID',
PRIMARY KEY (`id`),
KEY `fk_goods_id_idx` (`goods_id`),
CONSTRAINT `fk_goods_id` FOREIGN KEY (`goods_id`) REFERENCES `goods` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='推荐表'
DELETE CASCADE约束实现了当商品被删除时自动清理相关推荐记录,避免了数据不一致问题。
核心功能实现详解
智能婚纱展示与筛选系统
系统首页采用分类展示机制,用户可以根据婚纱类型、价格区间等条件进行筛选。前端JSP页面通过EL表达式动态渲染商品信息:
<!-- 商品列表展示JSP片段 -->
<div class="product-list">
<c:forEach items="${goodsList}" var="goods">
<div class="product-item">
<img src="${pageContext.request.contextPath}/images/${goods.cover}"
alt="${goods.name}">
<h3>${goods.name}</h3>
<p class="price">¥${goods.price}</p>
<p class="intro">${goods.intro}</p>
<c:if test="${goods.stock > 0}">
<a href="goods_detail?id=${goods.id}" class="btn">查看详情</a>
</c:if>
<c:if test="${goods.stock <= 0}">
<span class="sold-out">已售罄</span>
</c:if>
</div>
</c:forEach>
</div>

后端商品查询服务实现了分页和条件过滤功能:
// 商品分页查询服务
public class GoodsQueryService {
public PageResult<Goods> queryGoods(GoodsQuery query) {
String sql = "SELECT * FROM goods WHERE 1=1";
List<Object> params = new ArrayList<>();
if (query.getTypeId() != null) {
sql += " AND type_id = ?";
params.add(query.getTypeId());
}
if (query.getMinPrice() != null) {
sql += " AND price >= ?";
params.add(query.getMinPrice());
}
if (query.getMaxPrice() != null) {
sql += " AND price <= ?";
params.add(query.getMaxPrice());
}
sql += " ORDER BY id DESC LIMIT ?, ?";
params.add((query.getPage() - 1) * query.getSize());
params.add(query.getSize());
List<Goods> goodsList = jdbcTemplate.query(sql,
new GoodsRowMapper(), params.toArray());
int total = countGoods(query);
return new PageResult<>(goodsList, total, query.getPage(), query.getSize());
}
}
购物车与订单管理模块
购物车功能采用Session存储临时数据,用户添加商品时系统会实时验证库存状态:
// 购物车服务实现
public class CartService {
public void addToCart(HttpSession session, int goodsId, int amount) {
Goods goods = goodsDAO.findById(goodsId);
if (goods == null || goods.getStock() < amount) {
throw new BusinessException("商品不存在或库存不足");
}
Map<Integer, CartItem> cart = getCart(session);
CartItem item = cart.get(goodsId);
if (item != null) {
item.setAmount(item.getAmount() + amount);
} else {
item = new CartItem(goods, amount);
cart.put(goodsId, item);
}
session.setAttribute("cart", cart);
}
public BigDecimal getTotalPrice(HttpSession session) {
Map<Integer, CartItem> cart = getCart(session);
return cart.values().stream()
.map(item -> item.getGoods().getPrice().multiply(
BigDecimal.valueOf(item.getAmount())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}

订单确认页面展示了完整的订单信息,包括商品明细、价格计算和用户信息确认:

管理员后台管理系统
管理员后台提供了完整的商品管理功能,支持婚纱信息的增删改查操作:
// 商品管理Servlet
@WebServlet("/admin/goods")
public class GoodsManageServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
GoodsService goodsService = new GoodsServiceImpl();
switch (action) {
case "add":
Goods goods = parseGoodsFromRequest(request);
if (goodsService.addGoods(goods)) {
response.getWriter().write("success");
}
break;
case "update":
Goods updateGoods = parseGoodsFromRequest(request);
if (goodsService.updateGoods(updateGoods)) {
response.getWriter().write("success");
}
break;
case "delete":
int id = Integer.parseInt(request.getParameter("id"));
if (goodsService.deleteGoods(id)) {
response.getWriter().write("success");
}
break;
}
}
private Goods parseGoodsFromRequest(HttpServletRequest request) {
Goods goods = new Goods();
goods.setName(request.getParameter("name"));
goods.setPrice(Double.parseDouble(request.getParameter("price")));
goods.setStock(Integer.parseInt(request.getParameter("stock")));
goods.setTypeId(Integer.parseInt(request.getParameter("type_id")));
goods.setIntro(request.getParameter("intro"));
return goods;
}
}

订单管理模块支持多状态筛选和批量操作:

实体模型设计精要
系统采用面向对象的设计思想,通过实体类完整映射数据库表结构:
// 商品实体类
public class Goods {
private Integer id;
private String name;
private String cover;
private String image1;
private String image2;
private Double price;
private String intro;
private Integer stock;
private Integer typeId;
private Type type; // 关联类型对象
// 构造方法、getter和setter
public Goods() {}
public Goods(Integer id, String name, Double price, Integer stock) {
this.id = id;
this.name = name;
this.price = price;
this.stock = stock;
}
// 完整的getter和setter方法
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// ... 其他getter和setter
}
订单实体采用组合模式,包含订单项集合:
// 订单实体类
public class Order {
private Integer id;
private BigDecimal total;
private Integer amount;
private Integer status;
private Integer payType;
private String name;
private String phone;
private String address;
private Date createTime;
private Integer userId;
private List<OrderItem> items; // 订单项列表
public BigDecimal getTotal() {
if (items != null) {
return items.stream()
.map(item -> item.getPrice().multiply(
BigDecimal.valueOf(item.getAmount())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
return total;
}
}
功能展望与系统优化方向
性能优化与缓存策略
当前系统在数据查询方面存在优化空间。引入Redis作为缓存层可以显著提升系统性能:
// Redis缓存集成示例
@Service
public class GoodsServiceWithCache {
@Autowired
private RedisTemplate<String, Goods> redisTemplate;
@Autowired
private GoodsDAO goodsDAO;
private static final String GOODS_KEY_PREFIX = "goods:";
private static final long EXPIRATION = 3600; // 1小时
public Goods findByIdWithCache(Integer id) {
String key = GOODS_KEY_PREFIX + id;
Goods goods = redisTemplate.opsForValue().get(key);
if (goods == null) {
goods = goodsDAO.findById(id);
if (goods != null) {
redisTemplate.opsForValue().set(key, goods, EXPIRATION, TimeUnit.SECONDS);
}
}
return goods;
}
public void evictGoodsCache(Integer id) {
String key = GOODS_KEY_PREFIX + id;
redisTemplate.delete(key);
}
}
微服务架构改造
随着业务规模扩大,可将单体应用拆分为微服务架构:
# 微服务配置示例
spring:
application:
name: wedding-reservation-system
cloud:
nacos:
discovery:
server-addr: localhost:8848
services:
user-service:
port: 8081
path: /user/**
goods-service:
port: 8082
path: /goods/**
order-service:
port: 8083
path: /order/**
智能推荐系统升级
基于用户行为数据构建个性化推荐引擎:
// 协同过滤推荐算法示例
@Service
public class RecommendationService {
public List<Goods> getPersonalizedRecommendations(Integer userId) {
// 基于用户历史订单和浏览行为
List<Goods> similarUsersPreferences = findSimilarUsersPreferences(userId);
List<Goods> contentBasedRecommendations = getContentBasedRecommendations(userId);
// 融合多种推荐结果
return mergeRecommendations(similarUsersPreferences, contentBasedRecommendations);
}
private List<Goods> findSimilarUsersPreferences(Integer userId) {
// 实现基于用户的协同过滤
return goodsDAO.findByUserSimilarity(userId);
}
}
移动端适配与PWA支持
通过响应式设计和PWA技术提升移动端用户体验:
<!-- 响应式布局示例 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
@media (max-width: 768px) {
.product-grid {
grid-template-columns: 1fr;
}
.filters {
flex-direction: column;
}
}
</style>
大数据分析与业务洞察
集成数据分析平台,为商家提供经营决策支持:
-- 销售分析查询示例
SELECT
DATE(create_time) as order_date,
COUNT(*) as order_count,
SUM(total) as total_revenue,
AVG(total) as avg_order_value
FROM `order`
WHERE create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DATE(create_time)
ORDER BY order_date DESC;
该婚纱租赁管理平台通过严谨的架构设计和完整的功能实现,为传统婚纱行业提供了成熟的数字化解决方案。系统在保持技术稳定性的同时,具备良好的扩展性和可维护性,为后续的技术升级和功能扩展奠定了坚实基础。