随着电子商务的快速发展,传统图书销售模式面临着诸多挑战。实体书店受限于营业时间与物理空间,客户购书体验不够便捷,商家手动管理库存和订单效率低下。针对这些痛点,我们设计并实现了一个基于SSM框架的企业级图书电商平台,为图书零售商提供完整的数字化销售解决方案。
系统架构与技术栈
该平台采用经典的三层架构设计,表现层使用Spring MVC框架处理前端请求,业务逻辑层由Spring IoC容器统一管理服务组件,数据持久层基于MyBatis实现高效的数据库操作。技术栈包括Java 8、MySQL 5.7、Maven 3.6、HTML5、CSS3和JavaScript,确保系统的稳定性和可扩展性。
// Spring MVC控制器示例
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping("/list")
public String getBookList(Model model,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
PageInfo<Book> pageInfo = bookService.getBookList(pageNum, pageSize);
model.addAttribute("pageInfo", pageInfo);
return "book/list";
}
}
数据库设计亮点分析
订单信息表设计
dingdanxinxi表作为系统的核心业务表,采用了合理的字段设计和索引策略:
CREATE TABLE `dingdanxinxi` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`dingdanbianhao` varchar(50) NOT NULL COMMENT '订单编号',
`dingdanxinxi` text NOT NULL COMMENT '订单信息',
`zongjijine` decimal(18,2) NOT NULL COMMENT '总计金额',
`shouhuoren` varchar(50) NOT NULL COMMENT '收货人',
`dianhua` varchar(50) NOT NULL COMMENT '电话',
`dizhi` varchar(255) NOT NULL COMMENT '地址',
`beizhu` text NOT NULL COMMENT '备注',
`zhuangtai` varchar(255) NOT NULL COMMENT '状态',
`xiadanren` varchar(50) NOT NULL COMMENT '下单人',
`iszf` varchar(10) NOT NULL DEFAULT '否' COMMENT '是否支付',
`addtime` timestamp NOT NULL DEFAULT current_timestamp() COMMENT '添加时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COMMENT='订单信息表'
该表设计的亮点包括:
- 使用
decimal(18,2)类型精确存储金额数据,避免浮点数精度问题 dingdanbianhao字段采用varchar类型,支持灵活的订单编号规则- 添加时间字段设置默认值为当前时间戳,确保数据完整性
- 预留了扩展字段如
beizhu,支持业务需求变化
购物车表优化设计
gouwuche表的设计体现了高性能查询的考量:
CREATE TABLE `gouwuche` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`shujixinxiid` int(10) unsigned NOT NULL COMMENT '书籍信息id',
`shujibianhao` varchar(50) NOT NULL COMMENT '书籍编号',
`shujimingcheng` varchar(255) NOT NULL COMMENT '书籍名称',
`fenlei` int(10) unsigned NOT NULL COMMENT '分类',
`xiaoshoujiage` decimal(18,2) NOT NULL COMMENT '销售价格',
`goumaishuliang` int(11) NOT NULL COMMENT '购买数量',
`xiaoji` decimal(18,2) NOT NULL COMMENT '小计',
`goumairen` varchar(50) NOT NULL COMMENT '购买人',
`addtime` timestamp NOT NULL DEFAULT current_timestamp() COMMENT '添加时间',
PRIMARY KEY (`id`),
KEY `gouwuche_shujixinxiid_index` (`shujixinxiid`),
KEY `gouwuche_fenlei_index` (`fenlei`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COMMENT='购物车'
索引策略分析:
- 为
shujixinxiid和fenlei字段建立索引,优化商品查询性能 - 复合索引设计考虑到了用户按分类浏览商品的常见场景
- 自增主键确保数据插入的有序性,提高写入性能

核心功能实现
购物车管理功能
购物车功能采用Session与数据库结合的方式实现,既保证性能又确保数据持久化:
@Service
public class ShoppingCartServiceImpl implements ShoppingCartService {
@Autowired
private ShoppingCartMapper shoppingCartMapper;
@Override
@Transactional
public void addToCart(ShoppingCartItem item) {
// 检查商品库存
Book book = bookMapper.selectById(item.getShujixinxiid());
if (book.getKucun() < item.getGoumaishuliang()) {
throw new BusinessException("库存不足");
}
// 检查购物车中是否已存在该商品
ShoppingCartItem existingItem = shoppingCartMapper
.selectByUserAndBook(item.getGoumairen(), item.getShujixinxiid());
if (existingItem != null) {
// 更新数量
existingItem.setGoumaishuliang(
existingItem.getGoumaishuliang() + item.getGoumaishuliang());
existingItem.setXiaoji(existingItem.getXiaoshoujiage()
* existingItem.getGoumaishuliang());
shoppingCartMapper.updateById(existingItem);
} else {
// 新增商品
item.setXiaoji(item.getXiaoshoujiage() * item.getGoumaishuliang());
shoppingCartMapper.insert(item);
}
}
@Override
public List<ShoppingCartItem> getCartItems(String username) {
return shoppingCartMapper.selectByUser(username);
}
}
订单处理流程
订单创建涉及复杂的业务逻辑,需要保证事务的一致性:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private BookMapper bookMapper;
@Autowired
private ShoppingCartMapper shoppingCartMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Order createOrder(Order order, List<OrderDetail> details) {
// 生成订单编号
order.setDingdanbianhao(generateOrderNumber());
order.setAddtime(new Date());
// 保存订单主信息
orderMapper.insert(order);
BigDecimal totalAmount = BigDecimal.ZERO;
for (OrderDetail detail : details) {
// 扣减库存
Book book = bookMapper.selectById(detail.getShujixinxiid());
if (book.getKucun() < detail.getGoumaishuliang()) {
throw new BusinessException("商品[" + book.getShujimingcheng() + "]库存不足");
}
book.setKucun(book.getKucun() - detail.getGoumaishuliang());
bookMapper.updateById(book);
// 计算小计
detail.setXiaoji(detail.getXiaoshoujiage()
.multiply(new BigDecimal(detail.getGoumaishuliang())));
detail.setDingdanid(order.getId());
orderDetailMapper.insert(detail);
totalAmount = totalAmount.add(detail.getXiaoji());
}
// 更新订单总金额
order.setZongjijine(totalAmount);
orderMapper.updateById(order);
// 清空购物车
shoppingCartMapper.deleteByUser(order.getXiadanren());
return order;
}
private String generateOrderNumber() {
return "DD" + System.currentTimeMillis() +
String.format("%04d", new Random().nextInt(10000));
}
}

书籍信息管理
书籍信息管理采用富文本编辑器支持详细的商品描述:
@Controller
@RequestMapping("/admin/book")
public class AdminBookController {
@Autowired
private BookService bookService;
@PostMapping("/add")
@ResponseBody
public Result addBook(@Valid Book book,
@RequestParam("file") MultipartFile imageFile) {
try {
// 处理图片上传
if (!imageFile.isEmpty()) {
String imagePath = fileService.uploadImage(imageFile);
book.setShujitupian(imagePath);
}
book.setTianjiaren(getCurrentUsername());
bookService.addBook(book);
return Result.success("添加成功");
} catch (Exception e) {
return Result.error("添加失败: " + e.getMessage());
}
}
@GetMapping("/list")
public String bookList(Model model,
@RequestParam(defaultValue = "1") Integer page,
BookQuery query) {
PageInfo<Book> pageInfo = bookService.getBooksByQuery(query, page, 10);
model.addAttribute("pageInfo", pageInfo);
model.addAttribute("query", query);
return "admin/book/list";
}
}
相应的MyBatis映射文件配置:
<!-- BookMapper.xml -->
<mapper namespace="com.bookstore.mapper.BookMapper">
<resultMap id="BaseResultMap" type="com.bookstore.entity.Book">
<id column="id" property="id" />
<result column="shujibianhao" property="shujibianhao" />
<result column="shujimingcheng" property="shujimingcheng" />
<result column="fenlei" property="fenlei" />
<result column="shujitupian" property="shujitupian" />
<result column="xiaoshoujiage" property="xiaoshoujiage" />
<result column="kucun" property="kucun" />
<result column="zuozhe" property="zuozhe" />
<result column="chubanshe" property="chubanshe" />
<result column="shujixiangqing" property="shujixiangqing" />
<result column="tianjiaren" property="tianjiaren" />
<result column="addtime" property="addtime" />
</resultMap>
<select id="selectByQuery" resultMap="BaseResultMap">
SELECT * FROM shujixinxi
<where>
<if test="query.shujimingcheng != null and query.shujimingcheng != ''">
AND shujimingcheng LIKE CONCAT('%', #{query.shujimingcheng}, '%')
</if>
<if test="query.fenlei != null">
AND fenlei = #{query.fenlei}
</if>
<if test="query.zuozhe != null and query.zuozhe != ''">
AND zuozhe LIKE CONCAT('%', #{query.zuozhe}, '%')
</if>
</where>
ORDER BY addtime DESC
</select>
</mapper>

用户权限管理
系统采用基于角色的访问控制(RBAC)模型:
@Component
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login")
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
实体模型设计
系统采用领域驱动设计(DDD)思想,核心实体模型包括:
// 书籍实体类
@Entity
@Table(name = "shujixinxi")
public class Book {
private Integer id;
private String shujibianhao;
private String shujimingcheng;
private Integer fenlei;
private String shujitupian;
private BigDecimal xiaoshoujiage;
private Integer kucun;
private String zuozhe;
private String chubanshe;
private String shujixiangqing;
private String tianjiaren;
private Date addtime;
// getter/setter方法
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
// 其他getter/setter...
}
// 订单实体类
@Entity
@Table(name = "dingdanxinxi")
public class Order {
private Integer id;
private String dingdanbianhao;
private String dingdanxinxi;
private BigDecimal zongjijine;
private String shouhuoren;
private String dianhua;
private String dizhi;
private String beizhu;
private String zhuangtai;
private String xiadanren;
private String iszf;
private Date addtime;
private List<OrderDetail> details;
// 关联关系配置
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
public List<OrderDetail> getDetails() { return details; }
}
功能展望与优化建议
1. 缓存层优化
引入Redis作为缓存层,提升系统性能:
@Service
public class BookServiceWithCache {
@Autowired
private RedisTemplate<String, Book> redisTemplate;
@Autowired
private BookMapper bookMapper;
public Book getBookById(Integer id) {
String cacheKey = "book:" + id;
Book book = redisTemplate.opsForValue().get(cacheKey);
if (book == null) {
book = bookMapper.selectById(id);
if (book != null) {
redisTemplate.opsForValue().set(cacheKey, book, 30, TimeUnit.MINUTES);
}
}
return book;
}
}
2. 消息队列异步处理
使用RabbitMQ处理高并发订单:
@Component
public class OrderMessageProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendOrderMessage(Order order) {
rabbitTemplate.convertAndSend("order.exchange",
"order.create",
order);
}
}
@Component
public class OrderMessageConsumer {
@RabbitListener(queues = "order.queue")
public void processOrder(Order order) {
// 异步处理库存扣减、发送邮件通知等
inventoryService.deductStock(order);
emailService.sendOrderConfirmation(order);
}
}
3. 微服务架构改造
将单体应用拆分为微服务:
# docker-compose.yml 微服务部署配置
version: '3.8'
services:
user-service:
image: bookstore/user-service:latest
ports:
- "8081:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
book-service:
image: bookstore/book-service:latest
ports:
- "8082:8080"
order-service:
image: bookstore/order-service:latest
ports:
- "8083:8080"
4. 搜索引擎集成
集成Elasticsearch提供更强大的搜索功能:
@Repository
public class BookSearchRepository {
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
public List<Book> searchBooks(String keyword, Integer page, Integer size) {
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
queryBuilder.withQuery(QueryBuilders.multiMatchQuery(keyword,
"shujimingcheng", "zuozhe", "chubanshe", "shujixiangqing"));
queryBuilder.withPageable(PageRequest.of(page, size));
return elasticsearchTemplate.queryForList(queryBuilder.build(), Book.class);
}
}
5. 移动端适配
开发响应式前端界面,支持移动端访问:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图书商城</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<style>
@media (max-width: 768px) {
.book-item {
width: 100%;
margin-bottom: 20px;
}
.search-form {
flex-direction: column;
}
}
</style>
</head>
该图书电商平台通过合理的架构设计和细致的功能实现,为中小型书店提供了完整的线上销售解决方案。系统具有良好的扩展性和维护性,为后续的功能扩展和技术升级奠定了坚实基础。