基于SSM框架的药品进销存管理系统 - 源码深度解析
在医药流通领域,高效的库存管理是企业运营的生命线,直接决定了成本控制能力与服务质量水平。传统依赖人工记录的方式普遍存在数据更新滞后、库存信息不准、业务流程繁琐等痛点。对于中小型药店和诊所而言,这些问题尤为突出,极易导致药品过期损耗、缺货或积压等经营风险。为此,我们设计并开发了这套医药流通智能管理平台,旨在通过数字化、系统化的手段,对药品从采购、入库、存储到销售的全流程实现精细化管控。
系统架构与技术栈
本平台采用业界成熟且经典的SSM(Spring + SpringMVC + MyBatis)框架组合,构建了清晰、松耦合的三层架构体系,确保了系统的高内聚、低耦合特性。
- 表现层(Web Layer):基于 SpringMVC 框架,采用注解驱动(
@Controller,@RequestMapping)的方式构建控制器,实现了灵活且清晰的请求映射与视图解析。它负责接收前端请求、进行参数绑定与基本验证,并返回相应的视图或数据(如 JSON)。 - 业务逻辑层(Service Layer):依托 Spring 框架的核心 IoC(控制反转)容器,统一管理所有业务服务组件(
@Service)。利用 Spring 的声明式事务管理(@Transactional),确保了如药品入库、出库等核心业务操作的原子性、一致性、隔离性和持久性(ACID)。 - 数据持久层(DAO Layer):采用 MyBatis 框架作为 ORM 解决方案。通过 XML 配置文件或注解方式灵活地实现 SQL 与 Java 对象之间的映射,极大简化了数据库操作。同时,集成 PageHelper 分页插件,有效优化了大量数据查询时的性能与用户体验。
技术选型明细
| 层次 | 技术/工具 | 版本/说明 |
|---|---|---|
| 后端 | Java | 8 |
| Spring Framework | 5.x | |
| SpringMVC | 5.x | |
| MyBatis | 3.x | |
| 项目管理 | Maven | 用于项目构建与依赖管理 |
| 数据库 | MySQL | 5.7 |
| 前端 | HTML5 + CSS3 + JavaScript (ES5+) | 基础三件套 |
| Bootstrap | 3.x/4.x,提供响应式布局与UI组件 |
整个项目严格遵循 MVC 设计模式,层次分明,极大地提升了代码的可读性、可维护性和未来的可扩展性。
数据库设计亮点
优秀的数据库设计是系统稳定高效运行的基石。以下通过两个核心表展示其设计思路。
1. 订单管理表 (t_ordermanage):关联设计与业务完整性
CREATE TABLE `t_ordermanage` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`t_code` varchar(255) DEFAULT NULL COMMENT '销售编号',
`t_num` int(11) DEFAULT NULL COMMENT '销售数量',
`t_time` varchar(255) DEFAULT NULL COMMENT '销售时间',
`t_xprice` double DEFAULT NULL COMMENT '销售单价',
`t_tel` varchar(255) DEFAULT NULL COMMENT '联系电话',
`t_bz` longtext DEFAULT NULL COMMENT '备注',
`addTime` datetime DEFAULT NULL COMMENT '插入数据库时间',
`user_id` int(11) DEFAULT NULL COMMENT '对应User表的ID,在这里作为外键',
`medicine_id` int(11) DEFAULT NULL COMMENT '对应Medicine表的ID,在这里作为外键',
PRIMARY KEY (`id`),
KEY `FKA79AD6E8AFC3CB84` (`medicine_id`),
KEY `FKA79AD6E82D852AE4` (`user_id`),
CONSTRAINT `FKA79AD6E82D852AE4` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`),
CONSTRAINT `FKA79AD6E8AFC3CB84` FOREIGN KEY (`medicine_id`) REFERENCES `t_medicine` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单管理表'
设计亮点解析:
- 外键关联与数据完整性:通过
user_id和medicine_id两个外键字段,分别与用户表 (t_user) 和药品信息表 (t_medicine) 建立关联。这不仅清晰地构建了“谁(用户)卖了什么(药品)”的完整业务链条,还通过FOREIGN KEY约束强制保证了数据的引用完整性,防止出现“幽灵”订单。 - 索引优化:为外键字段创建了索引 (
KEY),显著提高了基于用户或药品查询相关订单的联表查询性能。 - 字段类型选择:
t_code采用varchar类型,支持灵活的销售单编号规则(如包含日期、流水号等)。t_xprice使用double类型,满足财务核算对单价精度的要求。addTime记录数据创建时间,便于审计和数据分析。
2. 用户表 (t_user):可扩展性与灵活性设计
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`u_username` varchar(255) DEFAULT NULL COMMENT '用户名',
`u_password` varchar(255) DEFAULT NULL COMMENT '密码',
`u_name` varchar(255) DEFAULT NULL COMMENT '姓名',
`u_birthday` varchar(255) DEFAULT NULL COMMENT '生日',
`u_sex` varchar(255) DEFAULT NULL COMMENT '性别',
`u_tel` varchar(255) DEFAULT NULL COMMENT '电话',
`u_qq` varchar(255) DEFAULT NULL COMMENT 'QQ',
`u_phone` varchar(255) DEFAULT NULL COMMENT '手机',
`u_jg` varchar(255) DEFAULT NULL COMMENT '机构',
`u_address` varchar(255) DEFAULT NULL COMMENT '地址',
`u_bm` varchar(255) DEFAULT NULL COMMENT '部门',
`u_type` varchar(255) DEFAULT NULL COMMENT '类型',
`u_by_1` int(11) DEFAULT NULL COMMENT '自定义1',
`u_by_2` varchar(255) DEFAULT NULL COMMENT '自定义2',
`u_by_3` varchar(255) DEFAULT NULL COMMENT '自定义3',
`u_bz` varchar(255) DEFAULT NULL COMMENT '备注',
`u_photo` varchar(255) DEFAULT NULL COMMENT '照片',
`u_percent` varchar(255) DEFAULT NULL COMMENT '比例',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表'
设计亮点解析:
- 预留扩展字段:特意设计的
u_by_1,u_by_2,u_by_3等自定义字段,为未来可能新增的用户属性(如工号、等级、特定业务标识)提供了极大的灵活性,无需频繁修改表结构,体现了良好的前瞻性设计。 - 角色权限控制:
u_type字段用于区分用户角色(如超级管理员、库存管理员、销售员等),是后端实现基于角色的访问控制(RBAC) 的基础。 - 个性化支持:
u_photo字段用于存储用户头像的文件路径或URL,增强了系统的用户体验。

核心功能实现
1. 出库管理控制器的设计:MVC模式的典型应用
@Controller // 声明该类为一个SpringMVC控制器
@RequestMapping(value = "Chuku") // 映射根路径为/Chuku的请求
public class ChukuController {
@Autowired // 依赖注入:自动装配出库服务
private ChukuService chukuService;
@Autowired // 依赖注入:自动装配用户服务
private UserService userService;
@Autowired // 依赖注入:自动装配订单管理服务
private OrderManageService orderManageService;
@Autowired // 依赖注入:自动装配药品服务
private MedicineService medicineService;
@RequestMapping(value = "/initPage.do") // 映射初始化页面的请求
public String initPage(HttpServletRequest request, Model model) {
// 1. 获取当前登录用户信息
int id = Integer.parseInt(String.valueOf(request.getSession().getAttribute("user_id")));
User user = userService.getById(id);
List<User> listUser = new ArrayList<>();
listUser.add(user);
model.addAttribute("listUser", listUser); // 将用户列表放入模型,供前端页面使用
// 2. 获取所有订单数据
List<OrderManage> listOrderManage = orderManageService.getList(null, null);
model.addAttribute("listOrderManage", listOrderManage);
// 3. 获取所有药品数据
List<Medicine> listMedicine = medicineService.getList(null, null);
model.addAttribute("listMedicine", listMedicine);
// 返回逻辑视图名,由视图解析器定位到具体JSP页面
return "Chuku/saveOrUpdate";
}
}
代码解析:
- 注解驱动:全面使用 SpringMVC 注解,如
@Controller,@RequestMapping,@Autowired,使得代码简洁且配置方便。 - 依赖注入(DI):通过
@Autowired自动注入所需的业务层服务,降低了组件间的耦合度。 - 模型传递:使用
Model对象将业务数据(用户、订单、药品列表)传递给视图(JSP),实现了控制器与视图的分离。 - 会话管理:从
HttpSession中获取当前登录用户的ID,确保操作的安全性。
2. 订单管理与库存联动:事务确保数据一致性
@Service // 声明该类为Spring的业务服务组件
public class OrderManageServiceImpl implements OrderManageService {
@Autowired
private OrderManageMapper orderManageMapper; // MyBatis映射接口
@Autowired
private MedicineMapper medicineMapper; // MyBatis映射接口
@Transactional // 声明式事务注解:此方法内的所有数据库操作作为一个事务执行
public void saveOrder(OrderManage order) {
// 步骤1:保存订单记录
orderManageMapper.insert(order);
// 步骤2:同步更新对应药品的库存
Medicine medicine = medicineMapper.selectById(order.getMedicineId());
medicine.setStock(medicine.getStock() - order.getTNum()); // 扣减库存
medicineMapper.updateById(medicine);
}
}
代码解析:
- 声明式事务管理:
@Transactional注解是保证业务逻辑原子性的关键。如果订单保存成功但库存更新失败,整个事务将回滚,订单也不会被创建,从而避免了数据不一致(如库存虚高)的情况。 - 业务逻辑封装:将订单创建和库存更新这两个紧密相关的操作封装在同一个服务方法中,符合高内聚的设计原则。
- MyBatis操作:通过注入的 Mapper 接口执行 SQL 映射,代码简洁。
这是进销存系统的核心逻辑之一,它确保了“销售”与“库存”这两个核心模块的实时联动与高度一致性。
