若依框架学习Day02:功能改造与问题攻坚实战
若依框架学习第二天:功能改造与问题攻坚实战
书接上文,若依框架学习进入第二天,今天的核心任务是围绕业务需求完成多个模块的改造与功能开发,同时解决数据完整性相关的Bug。一整天下来,从合作商管理到人员管理,从功能新增到问题排查,对若依框架的使用逻辑和实际开发技巧有了更深入的掌握,特此记录关键过程与思考。
一、合作商管理模块改造:功能新增与核心要点
合作商管理模块是今天改造的首个重点,主要新增了三个实用功能,其中功能二的实现思路具有通用性,值得详细拆解。
1.1 新增功能清单
-
查询详情按钮:点击后展示合作商核心信息,包括合作商名称、联系人、联系电话及分成比例,满足业务方快速查看详情的需求。
-
合作商列表显示点位数量:在查询合作商列表时,同步展示每个合作商关联的点位总数,这是本次改造的重点功能。
-
重置密码按钮:为合作商账号提供密码重置入口,提升系统运维便捷性。
1.2 重点功能实现:合作商关联点位数量查询
该功能与之前的区域管理改造思路类似,核心是通过“自定义Vo类+多表联查”实现数据封装与返回,具体步骤如下:
- 新建实体类RegionVo:在原有实体类基础上新增
nodeCount属性,用于存储点位数量。代码示例如下:
import lombok.Data;
import com.ruoyi.common.core.domain.BaseEntity;// 必须继承BaseEntity保证基础字段完整
@Data // Lombok注解,生成getter/setter等方法
public class RegionVo extends BaseEntity {private Long id;private String regionName;// 新增点位数量属性private Integer nodeCount;// 无参构造函数(Jackson反序列化必需)public RegionVo() {}// 有参构造函数(按需使用)public RegionVo(Long id, String regionName, Integer nodeCount) {this.id = id;this.regionName = regionName;this.nodeCount = nodeCount;}
}
- 多表联查SQL编写:在Mapper接口中编写联查SQL,关联合作商表与点位表,通过
COUNT()函数统计每个合作商的点位数量,别名设为node_count。代码示例如下:
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;@Mapper
public interface RegionMapper {// 合作商列表查询(含点位数量)List<RegionVo> selectRegionWithNodeCount(@Param("regionName") String regionName);
}
对应的Mapper XML文件SQL:`<select id="selectRegionWithNodeCount" resultType="com.ruoyi.project.area.vo.RegionVo">SELECT r.id, r.region_name, COUNT(n.id) AS node_countFROM t_region rLEFT JOIN t_node n ON r.id = n.region_id<where><if test="regionName != null and regionName != ''">AND r.region_name LIKE CONCAT('%', #{regionName}, '%')</if></where>GROUP BY r.id, r.region_name
</select>
- 数据封装与返回:查询结果直接封装到RegionVo的
nodeCount属性中,返回给前端即可实现列表展示。
1.3 关键注意点:序列化相关问题
在开发过程中遇到了前端无法解析返回数据的问题,排查后发现是序列化环节出了问题,总结两个核心注意事项:
-
无参构造函数的必要性:Jackson在反序列化时需要通过无参构造函数实例化对象,如果Vo类中只写了有参构造而省略无参构造,Jackson将无法创建对象并设置属性值,导致序列化失败。
-
@Data注解与父类继承:创建Vo类时必须添加
@Data注解(Lombok注解),否则无法生成getter/setter方法,前端无法获取属性值;同时要记得继承若依框架的父类(如BaseEntity),避免基础字段(如创建时间、更新时间)缺失导致数据显示不全。
二、点位管理改造:难点突破与思路复用
点位管理改造的难点是“查询点位的设备数量”,但仔细分析后发现,其解决思路与合作商管理的“点位数量查询”高度一致,体现了“思路复用”的开发技巧。
具体实现逻辑:新建NodeVo实体类,新增deviceCount属性用于存储设备数量;在Mapper中编写点位表与设备表的联查SQL,通过COUNT()统计设备数量并封装到NodeVo中,最后返回给前端。代码示例如下:
NodeVo类:`import lombok.Data;
import com.ruoyi.common.core.domain.BaseEntity;@Data
public class NodeVo extends BaseEntity {private Long id;private String nodeName;private Integer deviceCount; // 设备数量
` `}`
NodeMapper接口方法:`List<NodeVo> selectNodeWithDeviceCount();`
XML SQL:`<select id="selectNodeWithDeviceCount" resultType="com.ruoyi.project.node.vo.NodeVo">SELECT n.id, n.node_name, COUNT(d.id) AS device_countFROM t_node nLEFT JOIN t_device d ON n.id = d.node_idGROUP BY n.id, n.node_name
` `</select>`
这种“自定义Vo+联查SQL”的模式在若依框架中非常常用,掌握后能快速解决类似的数据统计需求。
三、Bug修复:数据完整性问题的解决
今天遇到的核心Bug是“删除区域时,对应点位被同步删除”,经排查是数据库级联约束配置不当导致的。
解决方案:将区域表与点位表之间的“级联删除”约束改为普通“外键约束”,确保删除区域时不会自动删除关联点位;同时通过若依框架的全局异常处理器,在删除操作触发外键约束时,返回友好的提示信息。全局异常处理器代码示例:
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.ruoyi.common.core.domain.AjaxResult;
import java.sql.SQLIntegrityConstraintViolationException;@RestControllerAdvice
public class GlobalExceptionHandler {// 处理外键约束异常@ExceptionHandler(SQLIntegrityConstraintViolationException.class)public AjaxResult handleForeignKeyException(SQLIntegrityConstraintViolationException e) {if (e.getMessage().contains("foreign key constraint")) {return AjaxResult.error("该数据下有关联子数据,无法删除");}return AjaxResult.error("操作失败:" + e.getMessage());}
` `}
,提升用户体验。
四、人员管理模块:从0到1的功能开发
下午重点完成了人员管理模块的开发,完整走了一遍若依框架“生成代码+业务改造”的流程:
-
库表设计:根据业务需求设计人员表,包含姓名、所属区域、联系方式等字段,其中“所属区域名称”为冗余字段。
-
基础代码生成:通过若依框架的“代码生成器”功能,导入人员表结构,生成Controller、Service、Mapper等基础代码,并创建人员管理菜单。
-
列表改造与事务控制:对人员列表进行改造,实现“所属区域名称”的同步更新。这里需要特别注意,冗余字段的同步更新必须使用事务,通过
@Transactional注解确保区域名称修改时,人员表中的关联字段能同步更新,避免数据不一致。代码示例:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;@Service
public class RegionService {@Resourceprivate RegionMapper regionMapper;@Resourceprivate PersonMapper personMapper;// 事务注解:保证区域修改和人员表同步更新原子性@Transactional(rollbackFor = Exception.class)public int updateRegion(Region region) {// 1. 更新区域表int rows = regionMapper.updateById(region);// 2. 同步更新人员表中的区域名称(冗余字段)if (rows > 0) {personMapper.updateRegionNameByRegionId(region.getId(), region.getRegionName());}return rows;}
` `}`
- 接口开发:完成人员的新增、编辑、删除、查询等接口开发,整体流程与之前的模块一致,进一步熟悉了若依框架的接口规范。
五、今日总结与收获
今天的学习让我在若依框架的实际应用上又进了一步,主要收获有:
-
掌握了“自定义Vo+多表联查”实现数据统计的核心思路,能快速解决类似的功能需求;
-
理解了Jackson序列化的关键要点,避免因构造函数、注解缺失导致的前端数据解析问题;
-
学会了数据库约束与全局异常处理器结合解决数据完整性问题;
-
熟练了若依框架“代码生成+业务改造”的开发流程,同时注意到事务在数据同步中的重要性;
-
另外,在遇到问题时,对AI提问的技巧也更熟练了——学会了精准描述问题场景(如“若依框架中Vo类序列化失败”),能更快获取有效的解决方案。
最后补充一个小细节:在编写多参数的简单SQL时,一定要给参数加上@Param()注解,并且括号内的名称要与SQL中的占位符一致,否则会出现参数绑定错误。
明天计划继续深入若依框架的权限管理和文件上传功能,期待更多的实战与突破!
