1. 程式人生 > >mybatis獲取剛剛插入到資料庫的資料的id

mybatis獲取剛剛插入到資料庫的資料的id

很多時候,我們需要獲取到剛剛插入到資料庫的資料的id是什麼,這裡的id可能有兩種情況,一種是自增長的id,另外一種情況是使用者自定義的id,例如生成的uuid。

思路:insert完成之後再去查詢得到id,這樣顯然不行,很可能獲取到的id不是自己想要的那條資料的id,只有在insert的過程中獲取到id,再將其包裝在結果集中一起返回,這樣才能萬無一失,保證返回id的準確性。

實現方法:mybatis的selectKey標籤配合sql語句就可以實現這一需求;或者是在insert標籤中加入useGeneratedKeys和keyProperty屬性也可以(useGeneratedKeys是使用生成的主鍵的意思)。

寫法如下:

第一種寫法:

第二種寫法:

第一種寫法詳解:

keyProperty屬性表示要查詢的主鍵的名字,就是主鍵欄位對應實體類的屬性。

order屬性有兩個值,即after,before;after表示在insert之後執行SELECT LAST_INSERT_ID(),一般用於主鍵自增時,得到的就是自增長生成的id,而before表示在insert之前執行SELECT LAST_INSERT_ID(),一般用於非自增主鍵,得到的是傳入的物件中主鍵的值,一般是使用者生成的uuid。

resultType屬性表示主鍵的型別,一般要麼是Integer,要麼是String

將該selectKey標籤的內容放入insert標籤語句中就ok了,例如:

<insert id="insertSelective" parameterType="com.rkxch.studypaper.po.StoryComments">
      
    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
      SELECT LAST_INSERT_ID()
    </selectKey>
    
    insert into story_comments
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="storyId != null">
        story_id,
      </if>
      <if test="userId != null">
        user_id,
      </if>
      <if test="isDisplayName != null">
        is_display_name,
      </if>
      <if test="isSupport != null">
        is_support,
      </if>
      <if test="likeCount != null">
        like_count,
      </if>
      <if test="auditUserId != null">
        audit_user_id,
      </if>
      <if test="auditStatus != null">
        audit_status,
      </if>
      <if test="auditTime != null">
        audit_time,
      </if>
      <if test="dislikeCount != null">
        dislike_count,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="updateTime != null">
        update_time,
      </if>
      <if test="commentsContent != null">
        comments_content,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="storyId != null">
        #{storyId,jdbcType=INTEGER},
      </if>
      <if test="userId != null">
        #{userId,jdbcType=INTEGER},
      </if>
      <if test="isDisplayName != null">
        #{isDisplayName,jdbcType=INTEGER},
      </if>
      <if test="isSupport != null">
        #{isSupport,jdbcType=INTEGER},
      </if>
      <if test="likeCount != null">
        #{likeCount,jdbcType=INTEGER},
      </if>
      <if test="auditUserId != null">
        #{auditUserId,jdbcType=INTEGER},
      </if>
      <if test="auditStatus != null">
        #{auditStatus,jdbcType=INTEGER},
      </if>
      <if test="auditTime != null">
        #{auditTime,jdbcType=TIMESTAMP},
      </if>
      <if test="dislikeCount != null">
        #{dislikeCount,jdbcType=INTEGER},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="updateTime != null">
        #{updateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="commentsContent != null">
        #{commentsContent,jdbcType=LONGVARCHAR},
      </if>
    </trim>
  </insert>

執行效果:

筆者的這個專案,資料庫的表結構主鍵都是自增長,所以selectKey標籤中order屬性必須是AFTER,而且是大寫。

如果,將order屬性改成BEFORE會怎樣呢?

執行效果如下:

這裡查詢的主鍵id是物件的id的值,而不是自增長生成的id的值,物件的屬性未賦值,自動初始化的值是0,所以此處主鍵的值為0,改成BEFORE取的就是物件主鍵的值。

筆者習慣在寫insert語句時將selectKey標籤帶上,方便使用。

另外:再強調一下,AFTER     BEFORE必須大寫

否則,執行如下:

第二種寫法詳解:

在insert標籤中加入useGeneratedKeys和keyProperty屬性即可,即:useGeneratedKeys="true" keyProperty="id"

例如:

<insert id="insertSelective" parameterType="com.rkxch.studypaper.po.StoryComments" useGeneratedKeys="true" keyProperty="id">
    insert into story_comments
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="storyId != null">
        story_id,
      </if>
      <if test="userId != null">
        user_id,
      </if>
      <if test="isDisplayName != null">
        is_display_name,
      </if>
      <if test="isSupport != null">
        is_support,
      </if>
      <if test="likeCount != null">
        like_count,
      </if>
      <if test="auditUserId != null">
        audit_user_id,
      </if>
      <if test="auditStatus != null">
        audit_status,
      </if>
      <if test="auditTime != null">
        audit_time,
      </if>
      <if test="dislikeCount != null">
        dislike_count,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="updateTime != null">
        update_time,
      </if>
      <if test="commentsContent != null">
        comments_content,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="storyId != null">
        #{storyId,jdbcType=INTEGER},
      </if>
      <if test="userId != null">
        #{userId,jdbcType=INTEGER},
      </if>
      <if test="isDisplayName != null">
        #{isDisplayName,jdbcType=INTEGER},
      </if>
      <if test="isSupport != null">
        #{isSupport,jdbcType=INTEGER},
      </if>
      <if test="likeCount != null">
        #{likeCount,jdbcType=INTEGER},
      </if>
      <if test="auditUserId != null">
        #{auditUserId,jdbcType=INTEGER},
      </if>
      <if test="auditStatus != null">
        #{auditStatus,jdbcType=INTEGER},
      </if>
      <if test="auditTime != null">
        #{auditTime,jdbcType=TIMESTAMP},
      </if>
      <if test="dislikeCount != null">
        #{dislikeCount,jdbcType=INTEGER},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="updateTime != null">
        #{updateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="commentsContent != null">
        #{commentsContent,jdbcType=LONGVARCHAR},
      </if>
    </trim>
  </insert>

效果如下: