水产品供应链管理一直是传统农业电商信息化的重点与难点领域。该系统采用经典的JSP+Servlet技术栈,构建了一个集前端销售、库存管理、订单处理于一体的全链路业务平台。在技术架构上严格遵循MVC设计模式,通过Servlet控制器统一处理业务逻辑,JSP页面负责数据展示,JDBC实现数据持久化,形成了清晰的三层架构体系。
数据库架构设计亮点
系统采用MySQL数据库,六张核心表的设计体现了业务场景的完整性。其中商品表(products)的设计尤为关键:
CREATE TABLE products (
product_id INT AUTO_INCREMENT PRIMARY KEY,
category_id INT NOT NULL,
product_name VARCHAR(100) NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL,
stock_quantity INT DEFAULT 0,
image_url VARCHAR(200),
is_hot BOOLEAN DEFAULT FALSE,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(category_id)
);
该表通过category_id与分类表建立外键关联,支持商品的多级分类管理。price字段采用DECIMAL(10,2)类型确保金额计算的精确性,stock_quantity字段实时反映库存数量,is_hot标志位支持热门商品标识,为前端页面差异化展示提供数据支撑。
库存流水表(inventory_logs)的设计体现了系统的核心业务逻辑:
CREATE TABLE inventory_logs (
log_id INT AUTO_INCREMENT PRIMARY KEY,
product_id INT NOT NULL,
change_type ENUM('IN','OUT','ADJUST') NOT NULL,
change_quantity INT NOT NULL,
previous_quantity INT NOT NULL,
current_quantity INT NOT NULL,
reference_id INT, -- 关联订单ID或调整单ID
operator_id INT NOT NULL,
operate_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remarks VARCHAR(200),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
该表通过change_type枚举字段清晰记录库存变动类型(入库、出库、调整),保留变动前后的数量值,形成完整的审计轨迹。reference_id字段灵活关联业务单据,满足不同场景下的溯源需求。
核心业务功能实现
用户身份认证与会话管理
系统采用基于Session的认证机制,LoginServlet处理用户登录请求:
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
String userType = request.getParameter("userType");
UserDAO userDAO = new UserDAO();
User user = userDAO.authenticate(username, password, userType);
if (user != null) {
HttpSession session = request.getSession();
session.setAttribute("currentUser", user);
session.setAttribute("userType", userType);
if ("admin".equals(userType)) {
response.sendRedirect("admin/dashboard.jsp");
} else {
response.sendRedirect("user/home.jsp");
}
} else {
request.setAttribute("errorMsg", "用户名或密码错误");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
}

认证过程通过UserDAO执行数据库验证,成功后建立会话并根据用户类型跳转到相应工作台。会话数据包含用户对象和类型标识,为后续权限控制提供基础。
商品库存联动更新机制
订单提交时,系统通过Transaction实现库存的原子性更新:
public class OrderService {
public boolean createOrder(Order order, List<OrderItem> items) {
Connection conn = null;
try {
conn = DataSourceUtil.getConnection();
conn.setAutoCommit(false);
// 插入订单主记录
OrderDAO orderDAO = new OrderDAO(conn);
int orderId = orderDAO.insertOrder(order);
// 处理订单明细和库存扣减
InventoryDAO inventoryDAO = new InventoryDAO(conn);
for (OrderItem item : items) {
item.setOrderId(orderId);
orderDAO.insertOrderItem(item);
// 检查并扣减库存
boolean stockSufficient = inventoryDAO.reduceStock(
item.getProductId(), item.getQuantity());
if (!stockSufficient) {
conn.rollback();
return false;
}
}
conn.commit();
return true;
} catch (SQLException e) {
if (conn != null) {
try { conn.rollback(); } catch (SQLException ex) {}
}
return false;
} finally {
DataSourceUtil.closeConnection(conn);
}
}
}

该机制确保订单创建与库存扣减的原子性,避免超卖情况。通过事务管理和连接传递,保证多个数据库操作的一致性。
动态商品展示与分类检索
商品列表页面采用JSTL标签库实现动态渲染:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div class="product-grid">
<c:forEach var="product" items="${productList}">
<div class="product-card">
<img src="${product.imageUrl}" alt="${product.productName}">
<h3>${product.productName}</h3>
<p class="price">¥${product.price}</p>
<p class="stock">库存: ${product.stockQuantity}</p>
<c:if test="${product.stockQuantity > 0}">
<button onclick="addToCart(${product.productId})">加入购物车</button>
</c:if>
<c:if test="${product.stockQuantity <= 0}">
<button disabled>缺货</button>
</c:if>
</div>
</c:forEach>
</div>

前端页面通过EL表达式动态绑定商品数据,JSTL条件判断实现库存状态的可视化提示,提升用户体验。
购物车管理与会话存储
购物车功能采用HttpSession存储临时数据:
@WebServlet("/cart")
public class CartServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
HttpSession session = request.getSession();
Map<Integer, CartItem> cart = getOrCreateCart(session);
if ("add".equals(action)) {
int productId = Integer.parseInt(request.getParameter("productId"));
int quantity = Integer.parseInt(request.getParameter("quantity"));
ProductDAO productDAO = new ProductDAO();
Product product = productDAO.getProductById(productId);
if (cart.containsKey(productId)) {
CartItem item = cart.get(productId);
item.setQuantity(item.getQuantity() + quantity);
} else {
cart.put(productId, new CartItem(product, quantity));
}
} else if ("remove".equals(action)) {
int productId = Integer.parseInt(request.getParameter("productId"));
cart.remove(productId);
}
session.setAttribute("shoppingCart", cart);
response.sendRedirect("cart.jsp");
}
private Map<Integer, CartItem> getOrCreateCart(HttpSession session) {
Map<Integer, CartItem> cart = (Map<Integer, CartItem>) session.getAttribute("shoppingCart");
return cart != null ? cart : new HashMap<>();
}
}

购物车数据存储在用户会话中,支持商品的添加、移除和数量修改,无需频繁访问数据库,提升系统响应性能。
实体模型与业务逻辑封装
系统通过JavaBean封装业务实体,如订单实体包含完整的业务属性:
public class Order {
private int orderId;
private int userId;
private String orderNumber;
private BigDecimal totalAmount;
private String status; // PENDING, PAID, SHIPPED, COMPLETED, CANCELLED
private String shippingAddress;
private String recipientName;
private String recipientPhone;
private Date createTime;
private Date updateTime;
private List<OrderItem> items;
// 计算订单总金额
public BigDecimal calculateTotal() {
return items.stream()
.map(item -> item.getUnitPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
// 验证订单状态流转
public boolean canChangeStatus(String targetStatus) {
Map<String, List<String>> allowedTransitions = Map.of(
"PENDING", Arrays.asList("PAID", "CANCELLED"),
"PAID", Arrays.asList("SHIPPED", "CANCELLED"),
"SHIPPED", Arrays.asList("COMPLETED")
);
return allowedTransitions.getOrDefault(this.status, Collections.emptyList())
.contains(targetStatus);
}
}
实体类内封装业务规则验证方法,确保状态流转的合法性和金额计算的准确性。
管理端功能深度解析
分类管理与商品关联
分类管理Servlet支持分类的增删改查操作:
@WebServlet("/admin/category")
public class CategoryServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
CategoryDAO categoryDAO = new CategoryDAO();
if ("create".equals(action)) {
String categoryName = request.getParameter("categoryName");
String description = request.getParameter("description");
Category category = new Category(0, categoryName, description);
categoryDAO.insertCategory(category);
} else if ("update".equals(action)) {
int categoryId = Integer.parseInt(request.getParameter("categoryId"));
String categoryName = request.getParameter("categoryName");
Category category = new Category(categoryId, categoryName, "");
categoryDAO.updateCategory(category);
}
response.sendRedirect("category-management.jsp");
}
}

分类数据通过外键与商品表关联,确保数据完整性。管理界面提供直观的操作入口,支持分类信息的维护。
订单处理与状态跟踪
订单管理模块实现多状态流转控制:
public class OrderDAO {
public boolean updateOrderStatus(int orderId, String newStatus, String oldStatus) {
String sql = "UPDATE orders SET status = ?, update_time = NOW() " +
"WHERE order_id = ? AND status = ?";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, newStatus);
stmt.setInt(2, orderId);
stmt.setString(3, oldStatus);
return stmt.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public List<Order> getOrdersByStatus(String status) {
String sql = "SELECT * FROM orders WHERE status = ? ORDER BY create_time DESC";
// 执行查询并映射结果集
}
}

通过乐观锁机制防止并发状态更新冲突,确保订单状态变更的准确性。
性能优化与安全考量
系统在数据访问层实现连接池管理:
public class DataSourceUtil {
private static BasicDataSource dataSource;
static {
dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/aquatic_sales?useSSL=false");
dataSource.setUsername("username");
dataSource.setPassword("password");
dataSource.setInitialSize(5);
dataSource.setMaxTotal(20);
dataSource.setMaxIdle(10);
dataSource.setMinIdle(5);
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
连接池配置优化数据库连接资源管理,提升系统并发处理能力。参数设置平衡了资源利用率和系统性能。
输入验证与SQL注入防护:
public class InputValidator {
public static boolean validateProductInput(String productName, String price) {
if (productName == null || productName.trim().isEmpty()) {
return false;
}
if (!productName.matches("[\\u4e00-\\u9fa5a-zA-Z0-9\\s]{1,100}")) {
return false;
}
try {
BigDecimal decimalPrice = new BigDecimal(price);
return decimalPrice.compareTo(BigDecimal.ZERO) >= 0;
} catch (NumberFormatException e) {
return false;
}
}
public static String sanitizeSql(String input) {
return input.replace("'", "''")
.replace(";", "")
.replace("--", "")
.replace("/*", "")
.replace("*/", "");
}
}
通过正则表达式和参数化查询结合的方式,有效防止SQL注入攻击,确保系统安全性。
技术架构优化方向
缓存层引入与性能提升
当前系统每次商品查询均直接访问数据库,可引入Redis缓存层:
public class ProductServiceWithCache {
private JedisPool jedisPool;
private ProductDAO productDAO;
public Product getProductById(int productId) {
String cacheKey = "product:" + productId;
try (Jedis jedis = jedisPool.getResource()) {
String cached = jedis.get(cacheKey);
if (cached != null) {
return JSON.parseObject(cached, Product.class);
}
}
Product product = productDAO.getProductById(productId);
if (product != null) {
try (Jedis jedis = jedisPool.getResource()) {
jedis.setex(cacheKey, 3600, JSON.toJSONString(product));
}
}
return product;
}
}
缓存热点商品数据,显著降低数据库访问压力,提升系统响应速度。
异步处理与消息队列集成
订单创建后的库存扣减、通知发送等操作可异步化:
@WebServlet("/async-order")
public class AsyncOrderServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
asyncContext.start(() -> {
try {
// 创建订单主记录
Order order = createOrder(request);
// 异步处理库存扣减
inventoryService.asyncReduceStock(order);
// 异步发送通知
notificationService.asyncSendOrderConfirm(order);
asyncContext.complete();
} catch (Exception e) {
asyncContext.complete();
}
});
}
}
通过Servlet异步支持实现非阻塞处理,提升系统吞吐量。
微服务架构改造
将单体应用拆分为商品服务、订单服务、库存服务等微服务:
// 商品服务接口
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/{id}")
public Product getProduct(@PathVariable int id) {
return productService.getProductById(id);
}
}
// 库存服务接口
@RestController
@RequestMapping("/inventory")
public class InventoryController {
@PutMapping("/reduce")
public boolean reduceStock(@RequestBody StockReduceRequest request) {
return inventoryService.reduceStock(request);
}
}
通过Spring Cloud等技术实现服务治理,提升系统可扩展性和维护性。
该系统通过严谨的架构设计和扎实的技术实现,为水产品行业提供了可靠的数字化管理解决方案。其在库存联动、订单处理等核心业务场景的技术实现具有行业参考价值,为传统农产品电商信息化建设提供了实践范例。