mybatis插入语句执行后返回结果

本文介绍使用MyBatis进行数据库插入操作时,如何获取并设置刚插入记录的主键ID,涵盖自增主键及非自增主键场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一种方法: 

<!-- ***************重点掌握插入语句返回结果的做法**************** -->

  <insert id="insertUser" parameterType="cn.com.gjw.pojo.User">
  <!-- 将插入数据的主键返回,由SELECT LAST_INSERT_ID()得到,只适用于自增主键 
  keyProperty:指定将查询到的结果返回到parameterType所指的对象的对应属性中
  order:指的是执行顺序,即为AFTER时,则在insert语句执行之后执行。
  -->
  <selectKey keyProperty="id" order="AFTER" resultType="int">
  SELECT LAST_INSERT_ID()
  </selectKey>
  insert into user(userName, sex, address, birthday) values(#{userName}, #{sex}, #{address}, #{birthday})

  </insert>


第二种方法:

<insert id="insertUser" parameterType="cn.com.gjw.pojo.User" useGeneratedKeys="true" keyProperty="id">
  insert into user(userName, sex, address, birthday) values(#{userName}, #{sex}, #{address}, #{birthday})
</insert>


第三种方法:如果id不是自增的,当表中没有记录式,设置id值为1,否则取id的最大值加2作为新的主键,设置方式为:

<insert id="insertUser" parameterType="cn.com.gjw.pojo.User" useGeneratedKeys="true" keyProperty="id">
  <selectKey keyProperty="id" order="BEFORE" resultType="int">
  select if(max(id) is null, 1, max(id) + 2) as newId from user
  </selectKey>
  insert into user(userName, sex, address, birthday) values(#{userName}, #{sex}, #{address}, #{birthday})
</insert>


代码中,执行完插入操作后可以打印测试是否取到了刚插入的记录的id:

System.out.println(user.getId());

### 解决 MyBatis 插入语中键与值数量不匹配的问题 当遇到 `org.mybatis.spring.MyBatisSystemException` 或类似的异常时,通常是因为在执行插入操作时,MyBatis 尝试获取自动生成的主键或其他字段值失败。以下是可能导致此问题的原因以及解决方案: #### 1. 错误的根本原因分析 - **错误描述**: 当 MyBatis 执行插入操作并尝试通过 `useGeneratedKeys=true` 获取生成的主键时,可能会因为目标对象的数量不足而抛出异常[^1]。 - **具体表现**: 如果 SQL 中定义了多个列需要返回,但实际的目标对象只有一个,则会触发 “Too many keys are generated” 的错误。 #### 2. 可能的解决方案 ##### 方法一:调整 `keyProperty` 和 `keyColumn` 确保 `keyProperty` 映射到 Java 对象中的属性名,同时 `keyColumn` 映射到数据库表中的列名。例如: ```xml <insert id="insertUser" parameterType="com.example.User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user(username, birthday, sex, address) VALUES (#{username}, #{birthday}, #{sex}, #{address}) </insert> ``` 在此配置下,假设 `id` 是自动增长的主键,那么 MyBatis 会在插入完成后将其赋值给对应的 Java 属性 `id`[^3]。 ##### 方法二:验证 SQL 语法 如果问题是由于 SQL 语法错误引起的(如拼写错误或结构不当),则需仔细检查 SQL 语句。例如,在某些情况下,MySQL 不允许直接嵌套 `INSERT` 语句,这可能引发类似于 `bad SQL grammar` 的异常[^2]。 正确的 SQL 应该像这样: ```sql INSERT INTO t_user_role(userid, roleid) VALUES (?, ?); ``` ##### 方法三:PostgreSQL 特定处理 对于 PostgreSQL 数据库,可以利用其特有的 `RETURNING` 子来显式指定要返回结果集。例如: ```java public PreparedStatement prepareStatement(String sql, String[] columnNames) { if (columnNames != null && columnNames.length != 0) { sql = AbstractJdbc3Statement.addReturning(this, sql, columnNames, true); } } ``` 这种机制可以通过修改驱动程序的行为来支持更复杂的场景,比如返回多个字段而非仅限于单个主键[^3]。 ##### 方法四:初始化测试数据 确认所使用的测试环境已正确设置好基础数据。例如,创建名为 `mybatisdemo` 的数据库及其关联表格,并填充必要的记录以便调试期间能够正常运行[^4]: ```sql CREATE DATABASE mybatisdemo; USE mybatisdemo; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `username` VARCHAR(32) NOT NULL COMMENT '用户名称', `birthday` DATE DEFAULT NULL COMMENT '生日', `sex` CHAR(1) DEFAULT NULL COMMENT '性别', `address` VARCHAR(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8; -- 测试数据 INSERT INTO `user`(`id`, `username`, `birthday`, `sex`, `address`) VALUES('1', '张三', '2018-07-10', '1', '北京'); ``` #### 3. 示例代码片段 下面是一个完整的 XML 配置示例,展示如何正确地使用 `useGeneratedKeys` 来完成插入操作: ```xml <mapper namespace="com.example.mapper.UserMapper"> <insert id="insertUser" parameterType="com.example.model.User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user(username, birthday, sex, address) VALUES (#{username}, #{birthday}, #{sex}, #{address}); </insert> </mapper> ``` #### 4. 总结 通过对以上几种方法的应用,应该可以有效解决因键值不一致而导致的各种异常情况。务必注意每一步的具体细节,尤其是涉及到不同数据库类型的特殊需求时。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值