基于JSP+Servlet的图书销售与库存管理系统 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-03-184 浏览

文章摘要

本项目是一款基于JSP和Servlet技术栈开发的图书销售与库存管理系统,旨在为中小型书店或图书馆提供一个集成化的业务管理解决方案。其核心业务价值在于将传统的线下图书销售与库存管理流程数字化,有效解决了人工记录效率低下、库存信息更新不及时、销售数据难以统计与分析等核心痛点。系统通过集中管理图书信息、...

在传统图书零售与库存管理领域,手工记录和信息滞后一直是制约运营效率的关键瓶颈。面对每日动态变化的图书销售、库存盘点以及分类管理需求,一套能够实现业务流程数字化、信息实时同步的管理系统显得尤为重要。本文介绍的“书海领航”系统,正是基于JSP和Servlet技术栈构建的综合性解决方案,旨在为中小型书店、图书馆及企业内部书吧提供从图书上架、销售到库存监控的全流程管理支持。

系统采用经典的MVC架构模式,通过Servlet实现请求控制、JavaBean封装业务逻辑、JSP负责视图展示,形成了层次分明的技术体系。MySQL数据库作为数据存储核心,通过七张数据表的有机结合,支撑起用户管理、图书分类、库存控制、订单处理等核心业务场景。

在数据库设计层面,系统通过规范化的表结构设计确保数据一致性和操作效率。图书信息表(book)作为核心数据载体,采用多字段组合的方式记录图书的完整属性:

CREATE TABLE `book` (
  `bid` char(32) NOT NULL,
  `bname` varchar(100) DEFAULT NULL,
  `author` varchar(100) DEFAULT NULL,
  `price` decimal(8,2) DEFAULT NULL,
  `currPrice` decimal(8,2) DEFAULT NULL,
  `discount` decimal(3,1) DEFAULT NULL,
  `press` varchar(100) DEFAULT NULL,
  `publishtime` char(10) DEFAULT NULL,
  `edition` int(11) DEFAULT NULL,
  `pageNum` int(11) DEFAULT NULL,
  `wordNum` int(11) DEFAULT NULL,
  `printtime` char(10) DEFAULT NULL,
  `booksize` int(11) DEFAULT NULL,
  `paper` varchar(50) DEFAULT NULL,
  `cid` char(32) DEFAULT NULL,
  `image_w` varchar(100) DEFAULT NULL,
  `image_b` varchar(100) DEFAULT NULL,
  `orderBy` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`bid`),
  KEY `orderBy` (`orderBy`),
  KEY `cid` (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

该表设计体现了多个技术亮点:使用定长字符型主键bid提升索引效率;pricecurrPrice分别记录原价与当前售价,支持灵活的价格策略;discount字段独立存储折扣信息,便于促销活动管理;通过cid外键关联分类表,建立完整的图书分类体系。特别值得注意的是orderBy自增字段的引入,为图书排序展示提供了技术基础。

订单管理表(t_order)的设计则体现了事务处理的完整性要求:

CREATE TABLE `t_order` (
  `oid` char(32) NOT NULL,
  `ordertime` char(19) DEFAULT NULL,
  `total` decimal(10,2) DEFAULT NULL,
  `status` int(11) DEFAULT NULL,
  `address` varchar(1000) DEFAULT NULL,
  `uid` char(32) DEFAULT NULL,
  PRIMARY KEY (`oid`),
  KEY `uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

该表通过status字段实现订单状态机管理,支持待付款、已发货、已完成等状态流转;total字段采用精确小数存储,确保金额计算的准确性;address字段的大容量设计适应了详细地址信息的存储需求。

系统用户表(tb_user)采用多角色设计架构:

CREATE TABLE `tb_user` (
  `uid` char(32) NOT NULL,
  `loginname` varchar(50) DEFAULT NULL,
  `loginpass` varchar(50) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `status` tinyint(1) DEFAULT NULL,
  `activationCode` char(64) DEFAULT NULL,
  PRIMARY KEY (`uid`),
  UNIQUE KEY `loginname` (`loginname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

通过statusactivationCode字段的配合,实现了用户账户的激活验证机制;loginname唯一索引约束确保了用户标识的唯一性。

在核心功能实现方面,系统通过精细的代码设计实现了完整的业务流程。图书查询功能通过组合查询条件构建动态SQL:

public class BookDao {
    public PageBean<Book> findByCriteria(CriteriaBook criteriaBook, int pageCode) {
        PageBean<Book> pageBean = new PageBean<Book>();
        pageBean.setPageCode(pageCode);
        pageBean.setPageSize(8);
        
        StringBuilder condition = new StringBuilder(" where 1=1");
        List<Object> params = new ArrayList<Object>();
        
        if(criteriaBook.getCategory() != null && !criteriaBook.getCategory().trim().isEmpty()) {
            condition.append(" and cid=?");
            params.add(criteriaBook.getCategory());
        }
        
        if(criteriaBook.getPress() != null && !criteriaBook.getPress().trim().isEmpty()) {
            condition.append(" and press like ?");
            params.add("%" + criteriaBook.getPress() + "%");
        }
        
        String sql = "select count(*) from book" + condition.toString();
        Number number = (Number) qr.query(sql, new ScalarHandler(), params.toArray());
        int totalRecord = number.intValue();
        pageBean.setTotalRecord(totalRecord);
        
        sql = "select * from book" + condition.toString() + " order by orderBy limit ?,?";
        params.add((pageCode-1) * pageBean.getPageSize());
        params.add(pageBean.getPageSize());
        
        List<Book> beanList = qr.query(sql, new BeanListHandler<Book>(Book.class), params.toArray());
        pageBean.setBeanList(beanList);
        return pageBean;
    }
}

该方法通过动态拼接SQL条件实现多维度图书检索,结合分页参数构建高效的数据查询机制。

购物车管理采用Session存储技术,确保用户操作的实时性:

public class CartItem {
    private Book book;
    private int quantity;
    private double subtotal;
    
    public double getSubtotal() {
        return book.getCurrPrice() * quantity;
    }
    
    public void setQuantity(int quantity) {
        this.quantity = quantity;
        this.subtotal = book.getCurrPrice() * quantity;
    }
}

public class Cart {
    private Map<String, CartItem> map = new LinkedHashMap<String, CartItem>();
    
    public void add(CartItem cartItem) {
        String bid = cartItem.getBook().getBid();
        if(map.containsKey(bid)) {
            CartItem _cartItem = map.get(bid);
            _cartItem.setQuantity(_cartItem.getQuantity() + cartItem.getQuantity());
            map.put(bid, _cartItem);
        } else {
            map.put(bid, cartItem);
        }
    }
    
    public void clear() {
        map.clear();
    }
}

购物车实体通过Map结构维护商品项,自动计算小计金额,支持商品数量的动态调整。

订单生成过程体现了事务处理的完整性:

public class OrderService {
    public void createOrder(Order order) {
        try {
            JDBCUtils.beginTransaction();
            
            OrderDao orderDao = new OrderDao();
            orderDao.add(order);
            
            OrderItemDao orderItemDao = new OrderItemDao();
            for(OrderItem orderItem : order.getOrderItemList()) {
                orderItemDao.add(orderItem);
            }
            
            BookDao bookDao = new BookDao();
            for(OrderItem orderItem : order.getOrderItemList()) {
                Book book = bookDao.load(orderItem.getBook().getBid());
                book.setQuantity(book.getQuantity() - orderItem.getQuantity());
                bookDao.updateQuantity(book);
            }
            
            JDBCUtils.commitTransaction();
        } catch (Exception e) {
            JDBCUtils.rollbackTransaction();
            throw new RuntimeException(e);
        }
    }
}

该方法通过事务保证订单数据与库存更新的一致性,避免超卖现象的发生。

用户认证模块采用过滤器实现访问控制:

@WebFilter("/*")
public class LoginFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        
        String path = request.getRequestURI();
        if(path.contains("/js/") || path.contains("/css/") || 
           path.contains("/images/") || path.contains("/login")) {
            chain.doFilter(request, response);
            return;
        }
        
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("sessionUser");
        if(user == null) {
            response.sendRedirect(request.getContextPath() + "/login");
            return;
        }
        
        chain.doFilter(request, response);
    }
}

过滤器对静态资源放行,对需要认证的请求进行会话验证,确保系统安全性。

图书信息管理 图书信息管理界面采用表格形式展示图书详情,支持按条件筛选和分页浏览,管理员可进行信息编辑和库存调整。

购物车页面 购物车界面清晰展示选购商品、数量、单价及小计金额,支持商品删除和数量修改,实时计算订单总额。

订单管理 订单管理面板提供全视角订单状态监控,支持按时间、状态等多维度筛选,便于进行发货处理和异常订单跟踪。

在实体模型设计方面,系统通过精细的对象关系映射实现业务逻辑封装。Book实体类完整呈现图书属性:

public class Book {
    private String bid;
    private String bname;
    private String author;
    private double price;
    private double currPrice;
    private double discount;
    private String press;
    private String publishTime;
    private int edition;
    private int pageNum;
    private int wordNum;
    private String printTime;
    private int bookSize;
    private String paper;
    private Category category;
    private String image_w;
    private String image_b;
    
    // Getter和Setter方法
    public double getCurrPrice() {
        return currPrice;
    }
    
    public void setCurrPrice(double currPrice) {
        this.currPrice = currPrice;
        this.discount = this.currPrice / this.price * 10;
    }
}

实体类通过计算方法自动维护折扣信息,确保数据逻辑的一致性。

订单实体采用组合模式设计:

public class Order {
    private String oid;
    private String orderTime;
    private double total;
    private int status;
    private String address;
    private User owner;
    private List<OrderItem> orderItemList = new ArrayList<OrderItem>();
    
    public void addOrderItem(OrderItem orderItem) {
        orderItemList.add(orderItem);
    }
}

这种设计支持订单项的灵活管理,便于实现订单金额的自动计算。

针对系统的未来演进,可从以下几个方向进行功能深化:

首先,引入Redis缓存机制提升系统性能。将热点图书数据、分类信息等加载到缓存中,减少数据库访问压力:

@Component
public class BookCacheService {
    @Autowired
    private RedisTemplate redisTemplate;
    
    public Book getBookById(String bid) {
        String key = "book:" + bid;
        Book book = (Book) redisTemplate.opsForValue().get(key);
        if(book == null) {
            book = bookDao.load(bid);
            redisTemplate.opsForValue().set(key, book, Duration.ofHours(1));
        }
        return book;
    }
}

其次,构建数据统计分析模块。通过定时任务生成销售报表,为经营决策提供数据支持:

CREATE TABLE `sales_statistics` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `stat_date` date NOT NULL,
  `category_id` char(32) DEFAULT NULL,
  `sales_volume` int(11) DEFAULT NULL,
  `sales_amount` decimal(12,2) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_date_category` (`stat_date`,`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

第三,实现分布式会话管理。采用Spring Session配合Redis实现集群环境下的会话共享:

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

第四,开发移动端适配界面。采用响应式设计技术,使系统能够自适应不同尺寸的移动设备:

@media screen and (max-width: 768px) {
    .book-list {
        grid-template-columns: repeat(2, 1fr);
    }
    .order-table {
        font-size: 0.8em;
    }
}

最后,集成第三方支付接口。增加支付宝、微信支付等现代化支付方式,提升用户购物体验:

public class PaymentService {
    public PaymentResult pay(Order order, PaymentChannel channel) {
        // 调用支付网关接口
        // 处理支付结果回调
        // 更新订单支付状态
    }
}

该系统通过严谨的架构设计和精细的代码实现,构建了完整的图书销售与库存管理生态。从技术实现角度看,其采用的传统JSP+Servlet组合虽非最新技术栈,但体现的MVC思想、事务控制、分层架构等核心概念具有持久价值。对于中小型图书管理场景而言,该系统提供了稳定可靠的技术基础,具备良好的可扩展性和维护性。

本文关键词
JSPServlet图书销售库存管理系统源码解析

上下篇

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