添加记录后获取主键ID,这是一个很常见的需求,特别是在一次前端调用中需要插入多个表的场景。
添加单一记录时返回主键ID
添加一条记录时返回主键值,在xml映射器和接口映射器中都可以实现。
- 在mapper.xml中配置获取记录主键值
- 在mapper.java中配置获取记录主键值
在xml映射器中配置获取记录主键值
- UserMapper.xml
- 在定义xml映射器时设置属性useGeneratedKeys值为true
- 并分别指定属性keyProperty和keyColumn为对应的数据库记录主键字段与Java对象的主键属性。
示例
<mapper namespace="com.mybatis.dao.UsersMapper">
<!-- 插入数据:返回记录主键id值
-->
<insert id="add" parameterType="Users" useGeneratedKeys="true" keyProperty="id" keyColumn="id"
>
insert into user(id,name,adress)
values(#{id},#{name},#{adress})
</insert>
</mapper>
在接口映射器中配置获取记录主键值
- UserMapper.java
- 在接口映射器中通过注解@Options分别设置参数useGeneratedKeys,keyProperty,keyColumn值
示例
// 返回主键字段id值
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn =
"id")
@Insert("insert into test(id,name,adress) values(#{id},#{name},#{adress}")
Integer add(Users user);
注
在MyBatis中添加操作返回的是记录数并非记录主键id。因此,如果需要获取新添加记录的主键值,需要在执行添加操作之后,直接读取Java对象的主键属性。
Integer rows = sqlSession.getMapper(TestMapper.class).add(user);
System.out.println("rows = " + rows); // 添加操作返回记录数
System.out.println("id = " + user.getId()); // 执行添加操作之后通过Java对象获取主键属性值
添加批量记录时返回主键ID
- 如果希望执行批量添加并返回各记录主键字段值,只能在xml映射器中实现,在接口映射器中无法做到。
示例
<!-- 批量添加数据,并返回主键字段 -->
<insert id="add" useGeneratedKeys="true" keyProperty="id">
INSERT INTO test(id,name,adress)
VALUES
<foreach collection="list" separator="," item="t">
(#{t.id},#{t.name},#{t.adress})
</foreach>
</insert>
可以看到,执行批量添加并返回记录主键值的xml映射器配置,跟添加单条记录时是一致的。
不同的地方仅仅是使用了foreach元素构建批量添加语句。
获取主键ID实现原理
需要注意的是,不论在xml映射器还是在接口映射器中,添加记录的主键值并非添加操作的返回值。实际上,在MyBatis中执行添加操作时只会返回当前添加的记录数
示例
public class PreparedStatementHandler extends BaseStatementHandler {
@Override
public int update(Statement statement)
throws SQLException {
PreparedStatement ps =
(PreparedStatement) statement;
//
真正执行添加操作的SQL语句
ps.execute();
int rows =
ps.getUpdateCount();
Object parameterObject =
boundSql.getParameterObject();
KeyGenerator keyGenerator =
mappedStatement.getKeyGenerator();
// 在执行添加操作完毕之后,再处理记录主键字段值
keyGenerator.processAfter(executor, mappedStatement, ps,
parameterObject);
//
添加记录时返回的是记录数,而并非记录的主键字段值
return rows;
}
}