dao层和service层和control_关于mybatis-plus中Service和Mapper的分析

文章探讨了Mybatis-Plus的Service和Mapper接口,指出尽管两者在基础CRUD操作上相似,但Service提供了更多的批处理功能和业务逻辑支持,而复杂的SQL查询通常在Mapper的XML文件中编写。ServiceImpl继承了BaseMapper和Iservice,增加了代码冗余,但遵循了功能区分的原则。

关于mybatis-plus中Service和Mapper的分析

在后端开发过程中,如果有用到mybatis-plus,肯定会发现在其内部存在着两种数据库操作接口,Iservice和BaseMapper,如果只是用增删改查会发现两者的功能是一致的,除了方法名称有所不同,其他的基本相似。对此,我颇为好奇,便打开两个接口的源码进行对比。

先演示一下基本开发中的继承关系,手动创建的Service继承于ServiceImpl,并加载自己创建的Mapper

 @Service
public class RestDeptService extends ServiceImpl<RestDeptMapper, RestDept> {
 
    @Resource
    private RestDeptMapper restDeptMapper;
 
 }
 @Mapper
 public interface RestDeptMapper extends BaseMapper<RestDept> {
 
 }

如上,就是一般开发的基本模版代码,足以满足各种需求功能,但点开源码时,便进入新世界的大门。

先看一下继承结构

这样看,是不是很神奇,我们继承的ServiceImpl依旧实现了BaseMapper接口和Iservice接口,这就感觉有点啰嗦了,明明我们单独写了RestDeptMapper,并且继承了BaseMapper,现在ServiceImpl还是实现了BaseMapper,那我直接一个Service用下来不就行了,创建两套类,功能相似,还容易混乱,代码结构冗余。

本着“存在即合理”的理念,我们对比一下两个接口的方法。

果然,Service简直是BaseMapper的大扩充,不但包含了所有基本方法,还加入了很多批处理功能,我们可以看一下官网对这两种接口的说明。

官网链接:https://mp.baomidou.com/guide/crud-interface.html#remove

Service CRUD 接口

说明:

  • 通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行 remove 删除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆,

  • 泛型 T 为任意实体对象

  • 建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承 Mybatis-Plus 提供的基类

  • 对象 Wrapper 为 条件构造器

Mapper CRUD 接口

说明:

  • 通用 CRUD 封装BaseMapper接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器

  • 泛型 T 为任意实体对象

  • 参数 Serializable 为任意类型主键 Mybatis-Plus 不推荐使用复合主键约定每一张表都有自己的唯一 id 主键

  • 对象 Wrapper 为 条件构造器

最后本文还是比较水的,只是简单的看了一下结构而已,没有太多的深入,总结一下,以我平时粘贴复制的经验来看,Service虽然加入了数据库的操作,但还是以业务功能为主,而更加复杂的SQL查询,还是要靠Mapper对应的XML文件里去编写SQL语句。

nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Error SQL: update SYS_NPI_FEASIBILITY_INFO SET NPI_ID = ?, DIF_FILE_PATH = ?, CTM_DEVICE_ID = ?, CTM_CODE = ?, GROSS_DIE = ?, SHIP_CODE = ?, CPFLOW_TEMPERATURE = ?, WAFER_GOLDEN_MAP = ?, WAFER_SIZE = ?, BUMP_PAD_TYPE = ?, DIE_SIZE = ?, CHIP_SIZE = ?, PRODUCT_CONFIG = ?, TEST_PLATFORM = ?, PTE_MANAGER = ?, PTE_OWNER = ?, PTE_BACKUP = ?, EE_OWNER = ?, HW_OWNER = ?, MPC_OWNER = ?, CTM_PE = ?, CTM_MTE = ?, CPC_OWNER = ?, CE_OWNER = ?, BP_OWNER = ?, BE2_OWNER = ?, FMEA_STANDARD_SPECIAL = ?, CONTROL_PLAN_STANDARD_SPECIAL = ?, IQC_OQC_STANDARD_SPECIAL = ?, PAK_STANDARD_SPECIAL = ?, MAT_STORE_STANDARD_SPECIAL = ?, MAP_DATA_STANDARD_SPECIAL = ?, TRA_EVALUATE_RESULT = ?, DIF_FILE_DATE = ?, DIF_FILE_AUTHOR = ?, WAFER_FILE_AUTHOR = ?, PROBER_CARD_FILE_AUTHOR = ?, PRODUCT_ID = ?, DIE_SIZE_WIDE =?, CHIP_SIZE_WIDE=?, WAFER_GOLDEN_MAP_AUTHOR = ? CTM_PE_EMAIL = ? , CTM_PE_TEL = ? , CTM_MTE_EMAIL = ? , CTM_MTE_TEL = ? where FEASIBILITY_ID = ? ### The error may exist in file [D:\development\Sjsemi-master-NPI\sjsemi-system\target\classes\mapper\system\SysNpiFeasibilityInfoMapper.xml] ### The error may involve com.sjsemi.system.mapper.SysNpiFeasibilityInfoMapper.updateSysNpiFeasibilityInfo ### The error occurred while executing an update ### Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Error SQL: update SYS_NPI_FEASIBILITY_INFO SET NPI_ID = ?, DIF_FILE_PATH = ?, CTM_DEVICE_ID = ?, CTM_CODE = ?, GROSS_DIE = ?, SHIP_CODE = ?, CPFLOW_TEMPERATURE = ?, WAFER_GOLDEN_MAP = ?, WAFER_SIZE = ?, BUMP_PAD_TYPE = ?, DIE_SIZE = ?, CHIP_SIZE = ?, PRODUCT_CONFIG = ?, TEST_PLATFORM = ?, PTE_MANAGER = ?, PTE_OWNER = ?, PTE_BACKUP = ?, EE_OWNER = ?, HW_OWNER = ?, MPC_OWNER = ?, CTM_PE = ?, CTM_MTE = ?, CPC_OWNER = ?, CE_OWNER = ?, BP_OWNER = ?, BE2_OWNER = ?, FMEA_STANDARD_SPECIAL = ?, CONTROL_PLAN_STANDARD_SPECIAL = ?, IQC_OQC_STANDARD_SPECIAL = ?, PAK_STANDARD_SPECIAL = ?, MAT_STORE_STANDARD_SPECIAL = ?, MAP_DATA_STANDARD_SPECIAL = ?, TRA_EVALUATE_RESULT = ?, DIF_FILE_DATE = ?, DIF_FILE_AUTHOR = ?, WAFER_FILE_AUTHOR = ?, PROBER_CARD_FILE_AUTHOR = ?, PRODUCT_ID = ?, DIE_SIZE_WIDE =?, CHIP_SIZE_WIDE=?, WAFER_GOLDEN_MAP_AUTHOR = ? CTM_PE_EMAIL = ? , CTM_PE_TEL = ? , CTM_MTE_EMAIL = ? , CTM_MTE_TEL = ? where FEASIBILITY_ID = ?这个错误是什么
最新发布
11-08
这个错误信息是一个典型的 **MyBatis-Plus** 框架在执行数据库更新操作时抛出的异常,核心问题是 SQL 语句语法错误或 MyBatis-Plus 解析失败。我们来逐步分析并定位问题。 --- ### ❌ 错误摘要 ```text nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Error SQL: update SYS_NPI_FEASIBILITY_INFO SET ... where FEASIBILITY_ID = ? ``` 关键点: - 使用了 `MyBatis-Plus` 进行数据库更新。 - 报错提示 “Failed to process” “Error SQL”,说明 SQL 构造过程中出现了问题。 - 实际报错位置指向一个 XML 映射文件: `SysNpiFeasibilityInfoMapper.xml` - 出错的 SQL 是一条 `UPDATE` 语句。 --- ## 🔍 问题定位:SQL 语法错误(逗号缺失) 观察你提供的 SQL 片段: ```sql SET ... DIE_SIZE_WIDE =?, CHIP_SIZE_WIDE=?, WAFER_GOLDEN_MAP_AUTHOR = ? CTM_PE_EMAIL = ? , CTM_PE_TEL = ? , ... where FEASIBILITY_ID = ? ``` 🔍 **问题就在这里!** 在字段 `WAFER_GOLDEN_MAP_AUTHOR = ?` 下一个字段 `CTM_PE_EMAIL = ?` 之间 **缺少了一个英文逗号 `,`**! 正确的法应该是: ```sql WAFER_GOLDEN_MAP_AUTHOR = ?, CTM_PE_EMAIL = ? , ... ``` 但你的 SQL 中是: ```sql WAFER_GOLDEN_MAP_AUTHOR = ? CTM_PE_EMAIL = ? ``` 这会导致 SQL 语法错误,变成非法 SQL,数据库无法解析。 --- ## ✅ 解决方案 ### 修改 `SysNpiFeasibilityInfoMapper.xml` 文件中的 SQL 语句 找到如下代码片段(大概率是动态 SQL): ```xml <set> <if test="npiId != null">NPI_ID = #{npiId},</if> <if test="difFilePath != null">DIF_FILE_PATH = #{difFilePath},</if> ... <if test="waferGoldenMapAuthor != null">WAFER_GOLDEN_MAP_AUTHOR = #{waferGoldenMapAuthor}</if> <if test="ctmPeEmail != null">CTM_PE_EMAIL = #{ctmPeEmail},</if> ... </set> ``` ### ❌ 错误原因: 最后一个 `<if>` 前没有加逗号分隔符,导致拼接成了: ```sql WAFER_GOLDEN_MAP_AUTHOR = ? CTM_PE_EMAIL = ? ``` 而不是: ```sql WAFER_GOLDEN_MAP_AUTHOR = ?, CTM_PE_EMAIL = ? ``` --- ### ✅ 正确做法:确保每个字段后加逗号,或者使用 MyBatis 安全方式 #### ✔️ 推荐方案一:让 MyBatis 自动处理逗号(推荐) MyBatis 的 `<set>` 标签会自动去除多余的逗号,所以你应该 **在每个字段后面都加上逗号**,由框架处理: ```xml <set> <if test="npiId != null">NPI_ID = #{npiId},</if> <if test="difFilePath != null">DIF_FILE_PATH = #{difFilePath},</if> <if test="ctmDeviceId != null">CTM_DEVICE_ID = #{ctmDeviceId},</if> <!-- 其他字段 --> <if test="waferGoldenMapAuthor != null">WAFER_GOLDEN_MAP_AUTHOR = #{waferGoldenMapAuthor},</if> <if test="ctmPeEmail != null">CTM_PE_EMAIL = #{ctmPeEmail},</if> <if test="ctmPeTel != null">CTM_PE_TEL = #{ctmPeTel},</if> <if test="ctmMteEmail != null">CTM_MTE_EMAIL = #{ctmMteEmail},</if> <if test="ctmMteTel != null">CTM_MTE_TEL = #{ctmMteTel},</if> </set> where FEASIBILITY_ID = #{feasibilityId} ``` ✅ `<set>` 标签会智能去除最后一个多余的逗号,所以即使最后也有逗号也没关系。 > ⚠️ 如果你自己手动拼接而不依赖 `<set>`,那就必须小心逗号逻辑。 --- #### ✔️ 方案二:检查是否误删了逗号(常见于手 SQL) 如果你不是用 `<set>` 而是直接的 SQL,请检查所有字段间是否有逗号: ```sql UPDATE SYS_NPI_FEASIBILITY_INFO SET NPI_ID = ?, DIF_FILE_PATH = ?, ... WAFER_GOLDEN_MAP_AUTHOR = ?, -- 必须有逗号 CTM_PE_EMAIL = ?, -- 否则这里会出错 ... WHERE FEASIBILITY_ID = ? ``` --- ## 🧩 总结错误原因 | 项目 | 内容 | |------|------| | **根本原因** | SQL 字段赋值之间缺少逗号 `,` 导致语法错误 | | **具体位置** | `WAFER_GOLDEN_MAP_AUTHOR = ?` 后面没有逗号,紧接着 `CTM_PE_EMAIL = ?` | | **框架行为** | MyBatis-Plus 尝试解析该 SQL 失败 → 抛出 `MybatisPlusException` | | **解决方案** | 在每个字段更新后添加逗号,并利用 `<set>` 标签自动管理 | --- ## ✅ 示例修正后的 XML 片段 ```xml <update id="updateSysNpiFeasibilityInfo" parameterType="com.sjsemi.system.domain.SysNpiFeasibilityInfo"> UPDATE SYS_NPI_FEASIBILITY_INFO <set> <if test="npiId != null">NPI_ID = #{npiId},</if> <if test="difFilePath != null">DIF_FILE_PATH = #{difFilePath},</if> <if test="ctmDeviceId != null">CTM_DEVICE_ID = #{ctmDeviceId},</if> <if test="ctmCode != null">CTM_CODE = #{ctmCode},</if> <if test="grossDie != null">GROSS_DIE = #{grossDie},</if> <if test="shipCode != null">SHIP_CODE = #{shipCode},</if> <!-- 更多字段... --> <if test="waferGoldenMapAuthor != null">WAFER_GOLDEN_MAP_AUTHOR = #{waferGoldenMapAuthor},</if> <if test="ctmPeEmail != null">CTM_PE_EMAIL = #{ctmPeEmail},</if> <if test="ctmPeTel != null">CTM_PE_TEL = #{ctmPeTel},</if> <if test="ctmMteEmail != null">CTM_MTE_EMAIL = #{ctmMteEmail},</if> <if test="ctmMteTel != null">CTM_MTE_TEL = #{ctmMteTel},</if> </set> WHERE FEASIBILITY_ID = #{feasibilityId} </update> ``` 这样就能避免因少逗号导致的 SQL 解析失败。 --- ## 💡 额外建议 1. **启用 MyBatis 日志打印完整 SQL**(便于调试) ```yaml # application.yml mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ``` 2. **使用 IDE 插件如 MyBatisX** 可高亮 SQL 并检测语法错误。 3. **单元测试 DAO 方法**,提前暴露 SQL 错误。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值