首页/新闻资讯/正文详情

SpringBoot水产养殖管理系统开发实践

发布时间:2026/11/3 16:02:08 来源:云帆数科 栏目:资讯中心
SpringBoot水产养殖管理系统开发实践
1. 项目概述水产养殖行业正经历从传统人工管理向数字化、智能化转型的关键阶段。作为一名长期从事农业信息化系统开发的工程师我在实际项目中发现大多数中小型养殖场仍在使用纸质记录本和Excel表格来管理养殖过程这种方式不仅效率低下而且难以应对突发状况。基于SpringBoot的水产养殖管理系统正是为解决这些问题而设计。系统通过物联网传感器实时采集水质数据结合后台业务逻辑处理实现了养殖环境监控、饲料投喂管理、疾病预警等核心功能。我在开发过程中特别注重系统的实用性和易用性确保即使是没有IT背景的养殖人员也能快速上手。2. 系统架构设计2.1 整体技术栈选型经过多次技术评估和实际项目验证我们最终确定了以下技术组合后端框架选择SpringBoot 2.7.x版本主要基于以下考虑内嵌Tomcat服务器简化部署流程自动配置机制大幅减少XML配置丰富的Starter依赖快速集成常用组件完善的文档和活跃的社区支持数据库采用MySQL 8.0主要优势在于对事务的完整支持确保数据一致性JSON数据类型支持便于存储半结构化数据窗口函数等高级特性简化复杂查询前端采用Vue3 Element Plus组合这种选择基于组件化开发模式提高代码复用率响应式设计适配多种终端设备丰富的UI组件库加速界面开发2.2 核心模块划分系统采用模块化设计主要包含以下功能模块基础信息管理模块养殖场信息维护池塘基础数据管理设备信息登记环境监控模块水质数据实时采集异常预警通知历史数据查询生产管理模块饲料投喂计划投喂记录统计生长周期跟踪疾病防控模块疾病症状库治疗方案记录疫情预警数据分析模块养殖效益分析饲料转化率计算环境参数关联分析3. 数据库设计与实现3.1 核心表结构设计数据库设计遵循第三范式原则同时兼顾查询性能。以下是几个关键表的设计CREATE TABLE pond ( id bigint NOT NULL AUTO_INCREMENT, farm_id bigint NOT NULL COMMENT 所属养殖场ID, name varchar(50) NOT NULL COMMENT 池塘名称, area decimal(10,2) DEFAULT NULL COMMENT 面积(亩), depth decimal(5,2) DEFAULT NULL COMMENT 平均水深(米), create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_farm_id (farm_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT池塘信息表; CREATE TABLE water_quality ( id bigint NOT NULL AUTO_INCREMENT, pond_id bigint NOT NULL COMMENT 池塘ID, temperature decimal(5,2) DEFAULT NULL COMMENT 水温(℃), ph_value decimal(4,2) DEFAULT NULL COMMENT PH值, oxygen decimal(6,2) DEFAULT NULL COMMENT 溶解氧(mg/L), turbidity int DEFAULT NULL COMMENT 浊度(NTU), record_time datetime NOT NULL COMMENT 记录时间, device_id varchar(50) DEFAULT NULL COMMENT 采集设备ID, PRIMARY KEY (id), KEY idx_pond_id (pond_id), KEY idx_record_time (record_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT水质监测表;3.2 实体关系映射使用JPA注解实现对象关系映射以下是核心实体类定义Entity Table(name pond) DynamicUpdate public class Pond { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; ManyToOne(fetch FetchType.LAZY) JoinColumn(name farm_id) private Farm farm; Column(nullable false, length 50) private String name; Column(precision 10, scale 2) private BigDecimal area; Column(precision 5, scale 2) private BigDecimal depth; OneToMany(mappedBy pond, cascade CascadeType.ALL, orphanRemoval true) private ListWaterQuality waterQualities new ArrayList(); // 省略getter/setter } Entity Table(name water_quality) public class WaterQuality { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; ManyToOne(fetch FetchType.LAZY) JoinColumn(name pond_id, nullable false) private Pond pond; Column(precision 5, scale 2) private BigDecimal temperature; Column(name ph_value, precision 4, scale 2) private BigDecimal phValue; Column(precision 6, scale 2) private BigDecimal oxygen; Column private Integer turbidity; Column(name record_time, nullable false) private LocalDateTime recordTime; // 省略getter/setter }4. 核心功能实现4.1 水质监测与预警水质监测是系统的核心功能之一我们实现了以下关键特性数据采集接口RestController RequestMapping(/api/water-quality) RequiredArgsConstructor public class WaterQualityController { private final WaterQualityService waterQualityService; PostMapping public ResponseEntityWaterQuality createRecord( Valid RequestBody WaterQualityDTO dto) { WaterQuality record waterQualityService.createRecord(dto); return ResponseEntity.ok(record); } GetMapping(/pond/{pondId}) public ResponseEntityPageWaterQuality getRecordsByPond( PathVariable Long pondId, RequestParam(required false) DateTimeFormat(iso DateTimeFormat.ISO.DATE_TIME) LocalDateTime start, RequestParam(required false) DateTimeFormat(iso DateTimeFormat.ISO.DATE_TIME) LocalDateTime end, PageableDefault(sort recordTime, direction Direction.DESC) Pageable pageable) { PageWaterQuality records waterQualityService.getRecordsByPond(pondId, start, end, pageable); return ResponseEntity.ok(records); } }预警服务实现Service RequiredArgsConstructor Slf4j public class WaterQualityAlertService { private final WaterQualityRepository waterQualityRepository; private final AlertService alertService; private final PondRepository pondRepository; Scheduled(cron ${aquaculture.alert.check-interval}) Transactional public void checkAbnormalWaterQuality() { ListPond activePonds pondRepository.findByStatus(PondStatus.ACTIVE); activePonds.forEach(pond - { OptionalWaterQuality latestRecord waterQualityRepository .findTopByPondIdOrderByRecordTimeDesc(pond.getId()); latestRecord.ifPresent(record - { if (isAbnormal(record)) { String message buildAlertMessage(record); alertService.createAlert(pond.getId(), AlertType.WATER_QUALITY, message); } }); }); } private boolean isAbnormal(WaterQuality record) { return record.getTemperature().compareTo(BigDecimal.valueOf(30)) 0 || record.getTemperature().compareTo(BigDecimal.valueOf(10)) 0 || record.getPhValue().compareTo(BigDecimal.valueOf(8.5)) 0 || record.getPhValue().compareTo(BigDecimal.valueOf(6.5)) 0 || record.getOxygen().compareTo(BigDecimal.valueOf(5)) 0; } }4.2 饲料投喂管理饲料成本通常占养殖总成本的60%以上因此精准投喂管理至关重要投喂计划服务Service RequiredArgsConstructor public class FeedingServiceImpl implements FeedingService { private final FeedingPlanRepository planRepository; private final FeedingRecordRepository recordRepository; private final PondRepository pondRepository; Override Transactional public FeedingRecord createFeedingRecord(FeedingRecordDTO dto) { Pond pond pondRepository.findById(dto.getPondId()) .orElseThrow(() - new BusinessException(池塘不存在)); FeedingRecord record new FeedingRecord(); record.setPond(pond); record.setFeedType(dto.getFeedType()); record.setAmount(dto.getAmount()); record.setFeedingTime(dto.getFeedingTime()); record.setOperator(dto.getOperator()); return recordRepository.save(record); } Override public ListFeedingStatistic getFeedingStatistics(Long pondId, LocalDate startDate, LocalDate endDate) { return recordRepository.statisticByPondAndDateRange( pondId, startDate.atStartOfDay(), endDate.plusDays(1).atStartOfDay()); } }饲料转化率计算public BigDecimal calculateFCR(Long pondId, LocalDate startDate, LocalDate endDate) { BigDecimal totalFeed recordRepository.sumFeedAmountByPondAndDateRange( pondId, startDate, endDate); BigDecimal weightGain growthRecordRepository.calculateWeightGain( pondId, startDate, endDate); if (weightGain.compareTo(BigDecimal.ZERO) 0) { return BigDecimal.ZERO; } return totalFeed.divide(weightGain, 2, RoundingMode.HALF_UP); }5. 系统部署与优化5.1 性能优化策略在实际部署中我们采取了以下优化措施数据库层面为高频查询字段添加适当索引对大表进行分区处理按时间范围分区使用连接池HikariCP管理数据库连接应用层面启用二级缓存Ehcache减少数据库访问异步处理耗时操作如数据统计分析采用DTO模式减少网络传输数据量前端优化接口数据分页加载图表数据懒加载本地缓存常用数据5.2 安全防护措施认证授权Configuration EnableWebSecurity RequiredArgsConstructor public class SecurityConfig extends WebSecurityConfigurerAdapter { private final UserDetailsService userDetailsService; Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers(/api/auth/**).permitAll() .antMatchers(/api/**).authenticated() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilter(new JwtAuthenticationFilter(authenticationManager())) .addFilter(new JwtAuthorizationFilter(authenticationManager())); } Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }数据安全敏感字段加密存储如用户密码、养殖场位置操作日志完整记录定期数据备份机制6. 常见问题与解决方案6.1 水质数据采集延迟问题现象传感器数据上传到系统存在明显延迟排查步骤检查网络连接状况验证MQTT服务是否正常运行查看消息队列积压情况解决方案增加本地缓存网络恢复后重传优化消息队列配置采用心跳机制监测设备在线状态6.2 批量操作超时问题现象导出大量历史数据时请求超时优化方案Async Transactional(readOnly true) public CompletableFutureFile exportWaterQualityData(Long pondId, LocalDateTime start, LocalDateTime end) { try (StreamWaterQuality stream waterQualityRepository .streamByPondAndDateRange(pondId, start, end)) { Path tempFile Files.createTempFile(water-quality-, .csv); try (BufferedWriter writer Files.newBufferedWriter(tempFile); CSVPrinter printer new CSVPrinter(writer, CSVFormat.DEFAULT .withHeader(时间, 水温, PH值, 溶解氧))) { stream.forEach(record - { try { printer.printRecord( record.getRecordTime(), record.getTemperature(), record.getPhValue(), record.getOxygen()); } catch (IOException e) { throw new UncheckedIOException(e); } }); } return CompletableFuture.completedFuture(tempFile.toFile()); } catch (IOException e) { throw new BusinessException(导出失败, e); } }6.3 高并发场景下的性能问题优化措施数据库读写分离引入Redis缓存热点数据使用Cacheable注解优化方法调用Service RequiredArgsConstructor public class PondServiceImpl implements PondService { private final PondRepository pondRepository; Override Cacheable(value pond, key #id) public Pond getPondById(Long id) { return pondRepository.findById(id) .orElseThrow(() - new BusinessException(池塘不存在)); } Override CacheEvict(value pond, key #pond.id) public Pond updatePond(Pond pond) { return pondRepository.save(pond); } }在实际项目开发过程中我们遇到了许多技术挑战和业务需求变化。通过采用模块化设计和持续重构系统保持了良好的可维护性和扩展性。对于计划开发类似系统的同行我建议在项目初期就充分考虑以下方面设备兼容性不同厂商的传感器数据格式可能不同需要设计灵活的协议适配层离线操作支持养殖场网络条件可能不稳定应提供本地数据存储和同步机制用户权限设计养殖场通常有多种角色管理员、技术员、饲养员等需要精细的权限控制系统上线后我们持续收集用户反馈并进行迭代优化。目前该系统已在多个养殖场稳定运行显著提高了管理效率和养殖效益。

相关推荐

5G NR覆盖优化指导:SS-RSRP门限、RF调整与波束权值实战
5G NR覆盖优化指导:SS-RSRP门限、RF调整与波束权值实战

简介:《5G NR无线网络覆盖优化指导书》面向5G网络规划优化工程师、工程交付与运维人员,以及需要系统梳理覆盖评估与验收标准的通信从业者,重点解决弱覆盖、覆盖空洞、越区覆盖和导频污染等现场问题。覆盖优化贯穿实验网、预商用、工程优化与日… · 2026/11/3 16:02:08

双向链表节点删除操作详解与优化技巧
双向链表节点删除操作详解与优化技巧

1. 双向链表删除节点的核心逻辑双向链表作为一种基础数据结构,相比单向链表最大的特点在于每个节点同时保存了前驱和后继指针。这种设计使得删除操作不再需要像单向链表那样遍历查找前驱节点,但也带来了指针维护的复杂性。在实际工程中,正确处… · 2026/11/3 16:01:06

Agnes 3.0认知架构升级:轻量Agent如何实现任务拆解与意图对齐
Agnes 3.0认知架构升级:轻量Agent如何实现任务拆解与意图对齐

1. 从“能跑通”到“会思考”:Agnes 3.0 的本质跃迁不是参数堆砌,而是认知架构重构 你有没有过这种体验:调用一个大模型API,输入“写一封辞职信”,它真给你生成了一封格式工整、措辞得体的信——但当你把上下文换成“我… · 2026/11/3 16:01:06

Opus 5.5、Grok 4.7与GPT-5.6 Sol实测对比:谁是最强AI模型?
Opus 5.5、Grok 4.7与GPT-5.6 Sol实测对比:谁是最强AI模型?

从昨天开始,AI圈的朋友应该都没睡好。Opus 5.5、Grok 4.7、GPT-5.6 Sol,三家重量级选手在两天内先后放榜,节奏紧凑得像是商量好的。我刷完三场发布的技术报告和实测数据,第一反应是:这哪是发布,分明是三场复… · 2026/11/3 16:36:58

RTL8367S五口千兆交换机原理图设计:GPIO复用与上电避坑
RTL8367S五口千兆交换机原理图设计:GPIO复用与上电避坑

简介:面向硬件工程师、嵌入式开发者和网络设备学习者,基于RTL8367S芯片的五口交换机参考原理图,可用于理解以太网交换机的硬件架构、接口定义与外围电路组织,适合原理图评审、方案预研和教学参考。压缩包内共1个PDF文件&#xff0… · 2026/11/3 16:36:58

Prometheus告警规则模板:四层分级与阈值推导实战
Prometheus告警规则模板:四层分级与阈值推导实战

告警规则写得好不好,直接决定了值班那晚能不能睡个整觉。我见过太多团队把 Prometheus 部署起来、Grafana 面板拉得漂漂亮亮,结果告警规则要么是从别处抄来的一堆 up 0 ,要么是阈值拍脑袋定的,上线第一周就被误报淹没&#xff… · 2026/11/3 16:36:58

渗透测试高阶技巧与实战经验分享
渗透测试高阶技巧与实战经验分享

1. 渗透测试进阶学习路径解析最近完成了为期四天的渗透测试强化训练,这套课程设计针对已有基础的安全从业人员,重点突破Web应用和系统渗透中的高阶技术难点。不同于入门阶段的基础工具使用,本次课程更注重攻击链路的完整构建和对抗思维的培养… · 2026/11/3 16:36:58

DC-4靶机渗透实战:从Web漏洞到Root提权
DC-4靶机渗透实战:从Web漏洞到Root提权

1. 靶机渗透实战概述DC-4是Vulnhub平台上经典的Linux靶机环境,专为渗透测试实战训练设计。这个靶场模拟了企业环境中常见的Web应用漏洞、权限提升路径和系统配置缺陷,特别适合中高级安全爱好者练习综合渗透技巧。与DC系列前作相比,DC-4在权限… · 2026/11/3 16:36:58

Swisslog百年转型:从电气小厂到物流自动化巨头的历程
Swisslog百年转型:从电气小厂到物流自动化巨头的历程

1. Swisslog百年转型史:从配电小厂到物流自动化巨头的蜕变1900年,瑞士阿尔劳小镇上,两位电气工程师创立了一家名为SprecherSchuh的小型配电设备厂。谁曾想到,这家最初生产电气控制柜的小作坊,会在125年后发展成为全球物… · 2026/11/3 16:35:57

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码