关于自增型主键的表中插入新数据后同时获取主键的值,useGeneratedKeys和keyProperty

20 篇文章 1 订阅
10 篇文章 0 订阅

在开发项目中遇到一个问题,就是在A表插入一条新的数据后,同时插入该条数据相关联的B表中一条数据,关联字段为A表中的主键,而这个主键时自增的,那么我如何在插入这条新数据的同时获取该数据主键id的值。

在我看来要在插入的同时获得这个主键id的值一步是完成不了的,可能需要两部,先插入,后查询出来获取id的值,但这样两次访问数据库感觉有点不太安全,于是,而且插入数据后,你怎么知道查询后取出来的时你刚刚插入的那条数据,这些都没法判断,万一插入的数据时相同的没有一些显著的区分条件,你无法从A表中找到刚刚才新插入的数据,除非你用多个判断的字段查询,这样又对数据造成滥用,为了减少数据库的访问,我们在处理这样的问题时,需要用到mybatis中的useGeneratedKeys和keyProperty这两个参数。

在MyBatis中,允许设置名称为“useGeneratedKeys”参数存在3个位置:

  1. 在settings元素中设置useGeneratedKeys参数
  2. 在xml映射器中设置useGeneratedKeys参数
  3. 在接口映射器中设置useGeneratedKeys参数

在不同位置设置的useGeneratedKeys参数,最终结果相同,但是影响范围不同。

在settings元素中设置useGeneratedKeys参数

官方的说法是该参数的作用是:“允许JDBC支持自动生成主键,需要驱动兼容”,如何理解这句话的意思?
其本意是说:对于支持自动生成记录主键的数据库,如:MySQL,SQL Server,此时设置useGeneratedKeys参数值为true,在执行添加记录之后可以获取到数据库自动生成的主键ID。
实际上,在settings元素中设置useGeneratedKeys是一个全局参数,但是只会对接口映射器产生影响,对xml映射器不起效。

<settings>
<!-- 
允许JDBC支持自动生成主键,需要驱动兼容。 
如果设置为true则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 
-->
<setting name="useGeneratedKeys" value="true" />
</settings>

此时,在接口映射中添加记录之后将返回主键ID。

public interface TestMapper {
    // 受全局useGeneratedKeys参数控制,添加记录之后将返回主键id
    @Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())")
    Integer insertOneTest(Test test);
}

但是,请注意如果此时在接口映射器中又明确设置了useGeneratedKeys参数,那么注解映射器中的useGeneratedKeys参数值将覆盖settings元素中设置的全局useGeneratedKeys参数值。
举个例子:先在settings元素中设置全局useGeneratedKeys参数值为true,再在接口映射器中设置useGeneratedKeys参数值为false,添加记录之后将不能返回注解ID。

// 在接口映射器中设置的useGeneratedKeys参数值将会覆盖在settings元素中设置全局useGeneratedKeys参数值
@Options(useGeneratedKeys = false, keyProperty = "id", keyColumn = "id")
@Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())")
int insertOneTest(Test test);

mapper.xml中的用法
<insert id="insertOneTest" parameterType="对应的实体或map" useGeneratedKeys="false" keyProperty="id"  keyColumn = "id">
insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())
</insert>

另外,在settings元素中设置的全局useGeneratedKeys参数对于xml映射器无效。如果希望在xml映射器中执行添加记录之后返回主键ID,则必须在xml映射器中明确设置useGeneratedKeys参数值为true。

在xml映射器中配置useGeneratedKeys参数

<!-- 插入数据:返回记录的id值 -->
<insert id="insertOneTest" parameterType="org.chench.test.mybatis.model.Test" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
    insert into test(name,descr,url,create_time,update_time) 
    values(#{name},#{descr},#{url},now(),now())
</insert>

xml映射器中配置的useGeneratedKeys参数只会对xml映射器产生影响,且在settings元素中设置的全局useGeneratedKeys参数值对于xml映射器不产生任何作用。

在接口映射器中设置useGeneratedKeys参数

// 设置useGeneratedKeys为true,返回数据库自动生成的记录主键id
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
@Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())")
Integer insertOneTest(Test test);

注意: 在接口映射器中设置的useGeneratedKeys参数会覆盖在<settings>元素中设置的对应参数值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值