基于SSM框架的药品信息管理平台 - 源码深度解析

JavaJavaScriptHTMLCSSSSM框架MavenMySQL
2026-02-087 浏览

文章摘要

本项目是一款基于SSM(Spring+SpringMVC+MyBatis)框架构建的药品信息管理平台,旨在为医疗机构、药房及医药流通企业提供高效、准确的药品数据管理解决方案。其核心业务价值在于通过数字化手段,彻底解决传统人工记录或Excel表格管理药品信息时普遍存在的效率低下、数据易出错、查询不便以...

在医疗信息化快速发展的今天,药品管理作为医疗机构运营的核心环节,其效率与准确性直接关系到医疗质量与患者安全。传统的人工记录或Excel表格管理方式已难以满足现代医疗机构对药品信息实时性、准确性和安全性的高标准要求。药品信息管理平台应运而生,通过数字化手段彻底解决药品信息分散、更新滞后、查询困难等痛点,为医疗机构提供全面的药品数据管理解决方案。

系统架构与技术栈

该平台采用经典的SSM(Spring+SpringMVC+MyBatis)框架组合,构建了层次清晰、易于维护的企业级应用架构。Spring框架作为核心容器,通过依赖注入和面向切面编程实现组件解耦,其声明式事务管理确保了药品数据操作的原子性和一致性。SpringMVC负责请求分发和视图解析,采用注解驱动的控制器设计简化了开发流程。MyBatis作为数据持久层框架,通过灵活的SQL映射提供了高效的数据库访问能力。

技术栈配置如下:

<!-- Spring核心依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.18</version>
</dependency>

<!-- SpringMVC依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.18</version>
</dependency>

<!-- MyBatis整合Spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.7</version>
</dependency>

项目采用Maven进行依赖管理,确保第三方库版本的一致性。前端使用HTML+CSS+JavaScript技术栈,结合JSP实现动态页面渲染,形成了完整的前后端分离架构。

数据库设计亮点

药品类型表(t_medicinetype)的设计优化

CREATE TABLE `t_medicinetype` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_mtype` varchar(255) DEFAULT NULL COMMENT '药品类型',
  `t_bz` longtext DEFAULT NULL COMMENT '备注',
  `addTime` datetime DEFAULT NULL COMMENT '插入数据库时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='药品类型表'

该表设计体现了几个重要优化点:使用utf8mb4字符集支持完整的Unicode字符,确保特殊药品名称的正确存储;addTime字段采用datetime类型精确记录操作时间;主键自增设计保证数据唯一性。在实际业务中,可为t_mtype字段添加唯一索引防止重复药品类型:

CREATE UNIQUE INDEX idx_medicinetype_mtype ON t_medicinetype(t_mtype);

用户权限关联设计

公告管理表(t_gonggao)通过外键关联用户表,实现数据完整性约束:

CREATE TABLE `t_gonggao` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_title` varchar(255) DEFAULT NULL COMMENT '标题',
  `t_content` varchar(255) DEFAULT NULL COMMENT '内容',
  `t_shijian` varchar(255) DEFAULT NULL COMMENT '发布时间',
  `user_id` int(11) DEFAULT NULL COMMENT '对应User表的ID,在这里作为外键',
  PRIMARY KEY (`id`),
  KEY `FK2B14C9A92D852AE4` (`user_id`),
  CONSTRAINT `FK2B14C9A92D852AE4` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='公告管理表'

外键约束确保公告数据与用户数据的引用完整性,避免孤儿记录的产生。索引优化显著提升了基于用户ID的查询性能。

出库管理的事务安全性

t_medicineout表设计包含完整的审计字段和业务关联:

CREATE TABLE `t_medicineout` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_outNo` varchar(255) DEFAULT NULL COMMENT '出库编号',
  `t_outDate` varchar(255) DEFAULT NULL COMMENT '出库时间',
  `t_outNum` int(11) DEFAULT NULL COMMENT '出库数量',
  `medicineManage_id` int(11) DEFAULT NULL COMMENT '药品管理ID外键',
  `user_id` int(11) DEFAULT NULL COMMENT '操作用户ID外键',
  PRIMARY KEY (`id`),
  KEY `FKCC9877492D852AE4` (`user_id`),
  KEY `FKCC9877498B398204` (`medicineManage_id`),
  CONSTRAINT `FKCC9877492D852AE4` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`),
  CONSTRAINT `FKCC9877498B398204` FOREIGN KEY (`medicineManage_id`) REFERENCES `t_medicinemanage` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='出库管理表'

双外键设计实现了药品出库与库存管理、用户权限的紧密关联,为复杂的业务事务提供了数据一致性保障。

核心功能实现

顾客信息管理模块

顾客信息管理是药品销售环节的重要基础,系统提供了完整的CRUD操作功能。控制器层通过注解驱动实现请求映射:

@Controller
@RequestMapping(value = "Customer")
public class CustomerController {
    
    @Autowired
    private CustomerService customerService;

    @RequestMapping(value = "/initPage.do")
    public String initPage(HttpServletRequest request, Model model) {
        return "Customer/saveOrUpdate";
    }

    @RequestMapping(value = "/selectList.do")
    public String selectList(HttpServletRequest request, Customer customer, Model model) {
        customer = customerService.getById(customer.getId());
        model.addAttribute("util", customer);
        return "Customer/saveOrUpdate";
    }
}

业务逻辑层实现复杂的数据处理逻辑:

@Service
public class CustomerServiceImpl implements CustomerService {
    
    @Autowired
    private CustomerMapper customerMapper;
    
    @Override
    @Transactional(readOnly = true)
    public Customer getById(Integer id) {
        return customerMapper.selectByPrimaryKey(id);
    }
    
    @Override
    @Transactional
    public int saveCustomer(Customer customer) {
        customer.setAddTime(new Date());
        return customerMapper.insert(customer);
    }
}

顾客信息管理

分页查询与条件筛选

系统实现了高效的分页查询机制,支持多条件组合筛选:

@RequestMapping(value = "/getAllDataInPage.do")
public String getAllDataInPage(HttpServletRequest request, Model model) {
    String field = request.getParameter("field");
    String fieldValue = request.getParameter("fieldValue");
    
    try {
        fieldValue = new String(fieldValue.getBytes("UTF-8"), "UTF-8");
    } catch (Exception e) {}
    
    String pageNo = request.getParameter("pageModel.currentPageNo");
    int currentPageNo = 1;
    
    try{
        currentPageNo = Integer.parseInt(pageNo);
    }catch(Exception e){}
    
    Map<String, Object> params = new HashMap<>();
    if(field != null && fieldValue != null && !"".equals(fieldValue)){
        params.put(field, fieldValue);
    }
    
    PageModel pageModel = new PageModel();
    pageModel.setCurrentPageNo(currentPageNo);
    
    List<Customer> customerList = customerService.getCustomerList(params, pageModel);
    model.addAttribute("list", customerList);
    model.addAttribute("pageModel", pageModel);
    
    return "Customer/CustomerList";
}

药品入库管理

入库管理模块确保药品信息的准确录入和库存更新:

@Controller
@RequestMapping(value = "MedicineIn")
public class MedicineInController {
    
    @Autowired
    private MedicineInService medicineInService;
    
    @RequestMapping(value = "/save.do")
    @ResponseBody
    public Map<String, Object> save(MedicineIn medicineIn, HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>();
        
        try {
            // 设置入库时间
            medicineIn.setAddTime(new Date());
            
            // 生成唯一入库编号
            String inNo = "IN" + System.currentTimeMillis();
            medicineIn.setT_inNo(inNo);
            
            int result = medicineInService.save(medicineIn);
            if(result > 0) {
                map.put("success", true);
                map.put("msg", "入库成功");
            } else {
                map.put("success", false);
                map.put("msg", "入库失败");
            }
        } catch (Exception e) {
            map.put("success", false);
            map.put("msg", "系统错误:" + e.getMessage());
        }
        
        return map;
    }
}

药品入库管理

公告发布系统

公告管理支持富文本编辑和权限控制,确保信息发布的规范性:

@Entity
@Table(name = "t_gonggao")
public class Gonggao {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name = "t_title")
    private String title;
    
    @Column(name = "t_content", length = 1000)
    private String content;
    
    @Column(name = "t_shijian")
    private String publishTime;
    
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User publisher;
    
    @Column(name = "addTime")
    private Date addTime;
    
    // Getter和Setter方法
}

公告管理

实体模型设计

系统采用面向对象的实体设计,每个数据库表对应一个实体类,通过注解实现ORM映射:

@Entity
@Table(name = "t_customer")
public class Customer {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name = "t_name")
    private String name;
    
    @Column(name = "t_card")
    private String idCard;
    
    @Column(name = "t_sex")
    private String gender;
    
    @Column(name = "t_age")
    private Integer age;
    
    @Column(name = "t_phone")
    private String phone;
    
    @Column(name = "t_history")
    private String medicalHistory;
    
    @Column(name = "addTime")
    private Date addTime;
    
    // 完整的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方法
}

数据访问层采用MyBatis的Mapper接口设计:

@Mapper
public interface CustomerMapper {
    
    @Select("SELECT * FROM t_customer WHERE id = #{id}")
    Customer selectByPrimaryKey(Integer id);
    
    @Insert("INSERT INTO t_customer(t_name, t_card, t_sex, t_age, t_phone, t_history, addTime) " +
            "VALUES(#{name}, #{idCard}, #{gender}, #{age}, #{phone}, #{medicalHistory}, #{addTime})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(Customer customer);
    
    @Update("UPDATE t_customer SET t_name=#{name}, t_card=#{idCard}, t_sex=#{gender}, " +
            "t_age=#{age}, t_phone=#{phone}, t_history=#{medicalHistory} WHERE id=#{id}")
    int updateByPrimaryKey(Customer customer);
    
    @Delete("DELETE FROM t_customer WHERE id = #{id}")
    int deleteByPrimaryKey(Integer id);
}

功能展望与优化

缓存优化策略

引入Redis缓存层,显著提升药品查询性能:

@Service
public class MedicineServiceWithCache {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private MedicineMapper medicineMapper;
    
    private static final String MEDICINE_CACHE_KEY = "medicine:";
    private static final long CACHE_EXPIRE_TIME = 3600; // 1小时
    
    public Medicine getMedicineByIdWithCache(Integer id) {
        String cacheKey = MEDICINE_CACHE_KEY + id;
        
        // 先从缓存获取
        Medicine medicine = (Medicine) redisTemplate.opsForValue().get(cacheKey);
        if (medicine != null) {
            return medicine;
        }
        
        // 缓存未命中,查询数据库
        medicine = medicineMapper.selectByPrimaryKey(id);
        if (medicine != null) {
            redisTemplate.opsForValue().set(cacheKey, medicine, 
                CACHE_EXPIRE_TIME, TimeUnit.SECONDS);
        }
        
        return medicine;
    }
}

微服务架构改造

将单体应用拆分为微服务架构:

# docker-compose.yml 微服务部署配置
version: '3.8'
services:
  medicine-service:
    image: medicine-service:1.0
    ports:
      - "8081:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - EUREKA_SERVER=http://eureka:8761/eureka
    
  user-service:
    image: user-service:1.0
    ports:
      - "8082:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
    
  gateway-service:
    image: gateway-service:1.0
    ports:
      - "80:8080"
    depends_on:
      - medicine-service
      - user-service

移动端适配与PWA支持

开发响应式界面,支持移动端访问:

<!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/mobile.css">
    <link rel="manifest" href="manifest.json">
</head>
<body>
    <div class="mobile-container">
        <header class="mobile-header">
            <h1>药品信息管理</h1>
        </header>
        <main class="mobile-main">
            <!-- 移动端优化界面 -->
        </main>
    </div>
    <script src="js/pwa.js"></script>
</body>
</html>

大数据分析模块

集成数据分析功能,提供药品销售趋势分析:

@Service
public class MedicineAnalysisService {
    
    @Autowired
    private MedicineSalesMapper salesMapper;
    
    public SalesTrend analyzeSalesTrend(Date startDate, Date endDate) {
        List<SalesData> salesData = salesMapper.getSalesByDateRange(startDate, endDate);
        
        SalesTrend trend = new SalesTrend();
        trend.setTotalSales(calculateTotalSales(salesData));
        trend.setTopMedicines(identifyTopSellingMedicines(salesData));
        trend.setSalesForecast(generateSalesForecast(salesData));
        
        return trend;
    }
    
    private BigDecimal calculateTotalSales(List<SalesData> salesData) {
        return salesData.stream()
            .map(SalesData::getAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

安全增强措施

加强系统安全性,防止SQL注入和XSS攻击:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/**").authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/dashboard")
            .and()
            .logout()
            .logoutSuccessUrl("/login")
            .and()
            .headers()
            .xssProtection()
            .and()
            .contentSecurityPolicy("script-src 'self'");
    }
    
    @Bean
    public Filter xssFilter() {
        return new XSSFilter();
    }
}

该药品信息管理平台通过严谨的架构设计、完善的业务功能和前瞻的技术规划,为医疗机构提供了可靠的药品管理解决方案。系统在保证数据安全性和业务完整性的同时,具备良好的扩展性和维护性,能够适应未来业务发展的需求。随着技术的不断进步,平台将持续优化升级,为医疗信息化建设贡献更大价值。

本文关键词
药品信息管理平台SSM框架源码解析数据库设计药品管理

上下篇

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