mybatis使用@Insert @SelectKey 执行插入语句时获得主键自增长值

 

@Insert(" insert into table(c1,c2) " +
        " values (#{c1},#{c2}) ")
@SelectKey(resultType = long.class,keyColumn = "id",before = false,statement = "SELECT LAST_INSERT_ID() AS id",keyProperty = "id")
int addQuestion(Instance instance);
/** public class Instance{
 
private  long id;
 private String c1;
     private String c2;
}
**/

      before=false:由于mysql支持自增长主键,所以先执行插入语句,再获取自增长主键值。

      keyColumn:自增长主键的字段名

      keyProperty: 实体类对应存放字段,注意数据类型和resultType一致

     statement:实际执行的sql语句

   SelectKey返回的值存在实体类中,线程安全,所以不论插入成功与否id都会安全自增

 

### MyBatis 主键自动生成配置及使用 #### 配置 `useGeneratedKeys` 实现主键自动生成 当希望在插入记录之后立即获得由数据库生成的主键,可以在映射文件中的 `<insert>` 标签内设置 `useGeneratedKeys="true"` 和 `keyProperty` 属性。前者告知 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来获取主键;后者指定将返回的主键赋给实体类中哪个字段。 对于 MySQL 数据库而言,在执行完 insert 操作后,MyBatis 可以自动填充新创建的对象实例的 ID 字段[^1]: ```xml <insert id="insertPerson" parameterType="com.example.Person" useGeneratedKeys="true" keyProperty="id"> INSERT INTO person (name, age) VALUES (#{name}, #{age}) </insert> ``` 这段 XML 定义了一个名为 `insertPerson` 的 Insert 映射语,并指定了它应该接收一个 Person 类型参数。同启用了 `useGeneratedKeys=true` 来指示 MyBatis 获取数据库产生的主键,并将其存储到传入对象的 `id` 属性里。 #### 利用 Sequence 或者其他方式预先分配主键 如果使用的不是支持自增列特性的数据库(比如 Oracle),则可以采用定义 sequence 序列的方式来自增长主键。此可以通过添加 `order="BEFORE"` 参数让 MyBatis 在实际执行插入操作前先取得新的主键并填入待插数据之中[^2]。 下面是一个例子展示如何结合 selectKey 元素以及 order 属性实现这一点: ```xml <insert id="insertStudent" parameterType="java.util.Map"> <selectKey resultType="int" keyProperty="student.studId" order="BEFORE"> SELECT seq_student.NEXTVAL FROM DUAL </selectKey> INSERT INTO STUDENT(STUDID, NAME, AGE) VALUES(#{student.studId}, #{student.name}, #{student.age}); </insert> ``` 这里展示了针对 Oracle 数据库的一个场景,其中 `seq_student` 是预设好的序列名称用于生产唯一的 studId 。此代码片段会在真正做插入动作之前就准备好要插入的新纪录所需的唯一标识符。 #### 自定义主键生成器 除了上述两种常见情况外,还可以通过编写自己的 TypeHandler 并注册至 MyBatis 中去处理更复杂的业务逻辑下的主键生成需求。这种方式允许开发者完全掌控主键是如何被计算出来的过程,甚至可以从外部服务调用来决定最终的结果[^3]。 例如,假设有一个基于 UUID 的全局唯一识别码的需求,则可能需要如下所示的方式来构建相应的处理器: ```java public class UuidGenerator implements TypeHandler<String> { @Override public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { if(parameter == null){ ps.setNull(i,jdbcType.TYPE_CODE); }else{ ps.setString(i,UUID.randomUUID().toString()); } } // ... other methods ... } ``` 随后就可以像这样应用这个 type handler : ```xml <resultMap id="baseResultMap" type="com.example.EntityWithUuid"> <!-- fields mapping --> <id column="uuid_column_name" property="uuidField" javaType="String" jdbcType="VARCHAR"/> </resultMap> <insert id="insertEntity" parameterType="com.example.EntityWithUuid"> INSERT INTO entity_table(uuid_column_name,...) VALUES (<foreach item="item" collection="list" separator=",">#{item.uuidField}</foreach>,...) </insert> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值