关于mybatis(insert插入)返回主键的问题

本文记录了在使用SSM框架中MyBatis时遇到的返回主键问题及解决方案,详细解析了错误信息提示,并提供了正确的mapper.xml配置示例。

近来使用ssm框架中的mybatis遇到返回主键的问题,在使用mybatis的过程中遇到各种问题,在此发帖持续更新,在此发帖的原因一来是是为了方便以后回顾,二来是为了给遇到同样问题的同学们一个提示,废话不多说了 开始正题。

首先来看一下控制台提示的错误信息:

错误一:

Caused by: org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object.

这句错误信息提示是说: 获得的关键参数是由参数对象产生的,说到这里可能有些同学已经知道解决方法了(不明白的同学继续)

错误二:

org.apache.ibatis.binding.BindingException: Parameter 'CR_ID' not found.

这句话的意思是说:定义的参数 ‘CR_ID’没有找到

mapper.xml 文件配置


    <insert id="addCustomerReceive" keyProperty="CR_ID" useGeneratedKeys="true">
   
    </insert>

上述的mapper是错误的配置,一经运行就会抛上述的两个异常,耽误了大半天的时间,在网上查找各种资料 写法都相同 要么说‘CR_ID’ 没有setter,getter 访问器,要没说加上keyColumn=" "  等等这都不是重要的病因,最终没有找到错误原因,看了二十七杯奶茶的博客突然明白了,

回顾错误信息一提示参数是由参数对象产生的,立马去查看Controller 方法传递的参数,恍然大悟 原来传递的是一个对象并不是一个字段或者一个map的载体,所以找不到CR_ID,一切原因终归粗心大意

正确的 mapper.xml 把keyProperty=" 对象.CR_ID "

文件配置:

<insert id="addCustomerReceive" keyProperty="对象.CR_ID" useGeneratedKeys="true">
   
 </insert>



 

### 可能的原因分析 在使用 MyBatis 执行 `INSERT` 操作并尝试返回自增主键时,如果发现数据未成功插入,可能涉及以下几个方面的问题: #### 1. **SQL 配置错误** MyBatis 的配置文件中需要正确设置 `useGeneratedKeys="true"` 和 `keyProperty` 属性来支持自动获取自增主键[^2]。如果没有正确配置这些属性,则可能导致虽然方法返回主键值,但实际上并未执行真正的插入操作。 ```xml <insert id="insertUser" useGeneratedKeys="true" keyProperty="id"> INSERT INTO users (name, age) VALUES (#{name}, #{age}) </insert> ``` #### 2. **事务管理问题** 如果当前环境启用了事务机制,而该事务未被提交或回滚,则可能会导致数据看似未插入的情况。即使 MyBatis 成功执行了 `INSERT` 并返回主键值,在事务未完成之前,数据不会持久化到数据库中[^3]。 #### 3. **数据库引擎限制** 某些数据库存储引擎(如 MySQL 中的 InnoDB 支持事务,而 MyISAM 不支持),如果不小心选择了不支持事务的存储引擎,可能会引发异常行为。例如,InnoDB 是默认推荐使用的存储引擎,但如果表使用的是 MyISAM,则可能出现无法正常插入数据的现象[^1]。 --- ### 解决方案 针对以上提到的各种可能性,可以采取以下措施解决问题: #### 方案一:检查 SQL 映射文件中的配置 确认 `<insert>` 节点是否设置了 `useGeneratedKeys="true"` 和指定了正确的 `keyProperty` 值。以下是标准写法示例: ```xml <insert id="insertStorehouse" parameterType="com.example.Storehouse" useGeneratedKeys="true" keyProperty="storehouseId"> INSERT INTO storehouses (name, location) VALUES (#{name}, #{location}) </insert> ``` 此配置会告诉 MyBatis 自动填充对象对应的字段(由 `keyProperty` 定义)为主键值。 #### 方案二:验证事务状态 确保调用 `insertReturnId()` 后手动或者通过框架完成了事务提交。如果是 Spring 管理的事务,可以通过如下方式开启声明式事务控制: ```java @Transactional(rollbackFor = Exception.class) public void saveWithTransaction() { Storehouse storehouse = new Storehouse(); storehouse.setName("New Warehouse"); storehouse.setLocation("Location A"); int rowsAffected = storehouseMapper.insertStorehouse(storehouse); } ``` 这里的关键在于 `@Transactional` 注解能够保证整个过程处于同一个事务上下文中,并且只有当没有抛出受检异常时才会提交事务[^3]。 #### 方案三:排查目标表的存储引擎类型 对于 MySQL 用户来说,务必核实所操作的数据表采用的是适合其业务逻辑需求的存储引擎。建议始终优先选用支持 ACID 特性的 InnoDB 引擎而非较老版本遗留下来的 MyISAM 引擎。 可通过运行下面这条命令查看现有表格的具体情况: ```sql SHOW TABLE STATUS WHERE Name='your_table_name'; ``` 假如显示的结果表明 Engine 列标注为 MYISAM ,则应考虑转换成 INNODB 。具体做法可参考官方文档说明链接。 --- ### 总结 综上所述,造成 MyBatis 插入记录失败却仍反馈主键的主要因素集中在三个方面——映射规则设定失误、缺少必要的事务处理以及底层物理结构设计不当之上。逐一排除这些问题之后即可恢复正常运作流程。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值