mybatis的insert(pojo),会返回pojo吗
在 MyBatis 中,执行 insert
操作时,Mapper 接口的 insert
方法本身不会直接返回一个包含数据库生成字段的 POJO 对象。其默认返回值是受影响的数据库行数(通常是 int
或 Integer
)。以下是具体分析和解决方案:
1. 默认行为
- 返回值类型:
insert
方法返回的是受影响的行数(整数),不是插入后的 POJO 对象。 - POJO 状态:执行插入后,如果数据库生成了自增 ID 或其他字段(如创建时间),POJO 对象中对应的属性值不会自动更新(除非显式配置)。
2. 如何获取数据库生成的字段值?
通过配置 **useGeneratedKeys
和 keyProperty
**,可以让 MyBatis 将数据库生成的值(如自增 ID)回填到 POJO 对象的属性中:
配置示例(XML 方式):
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">INSERT INTO user(name, email) VALUES(#{name}, #{email})
</insert>
配置说明:
- **
useGeneratedKeys="true"
**:启用数据库自动生成主键功能。 - **
keyProperty="id"
**:将生成的值回填到 POJO 的id
属性中。 - 支持同时回填多个字段(如 Oracle 序列),需结合
<selectKey>
子标签。
3. 执行后的效果
- 返回值:仍然是整数(如
1
,表示成功插入一行)。 - POJO 对象更新:数据库生成的值(如
id
)会自动注入到 传入的 POJO 对象 中,可通过原对象访问:User user = new User("Alice", "alice@example.com"); int rows = userMapper.insertUser(user); // 返回行数 System.out.println("生成的主键ID: " + user.getId()); // 直接访问更新后的属性
4. 注解配置方式
使用 @Options
注解实现相同效果:
@Insert("INSERT INTO user(name, email) VALUES(#{name}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUser(User user); // 执行后 user.getId() 获取主键
5. 特殊场景:非自增主键(如 Oracle)
使用 <selectKey>
提前查询序列值:
<insert id="insertUser" parameterType="User"><selectKey order="BEFORE" keyProperty="id" resultType="long">SELECT user_seq.nextval FROM dual</selectKey>INSERT INTO user(id, name, email) VALUES(#{id}, #{name}, #{email})
</insert>
总结
行为 | 是否支持 | 说明 |
---|---|---|
insert 方法直接返回 POJO | ❌ 否 | 返回值类型是整数(受影响行数)。 |
获取数据库生成的主键 | ✅ 是 | 通过 useGeneratedKeys + keyProperty 将值注入到 传入的 POJO 对象属性 中。 |
获取其他生成字段(如时间戳) | ✅ 是 | 通过 <selectKey> 或数据库触发器实现回填(需结合触发器逻辑)。 |
结论:插入后需访问 原 POJO 对象 的属性获取生成值,而非通过方法返回值。