Mybatis插入數(shù)據(jù)后自增id獲取方式
需求
我們需要把插入數(shù)據(jù)后的id(有數(shù)據(jù)庫(kù)自增主鍵生成)返回來(lái),以便我們下一次操作。
like this
/**
* 測(cè)試插入后獲取id
*/
@Test
public void testinsertStudentCacheId(){
Student student=new Student("helloworld",17,85);
System.out.println("插入前:student="+student);
dao.insertStudentCacheId(student);
System.out.println("插入后:student id="+student.getId());
}了解一下mybatis基本信息
mybatis 可配置的屬性
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<!-- mapper 為根元素節(jié)點(diǎn), 一個(gè)namespace對(duì)應(yīng)一個(gè)dao -->
<!--
Mapper元素只有一個(gè)屬性namespace,它有兩個(gè)作用:`一是用于區(qū)分不同的mapper`(在不同的mapper文件里,子元素的id可以相同,mybatis通過(guò)namespace和子元素的id聯(lián)合區(qū)分),`二是與接口關(guān)聯(lián)`(應(yīng)用程序通過(guò)接口訪問(wèn)mybatis時(shí),mybatis通過(guò)接口的完整名稱(chēng)查找對(duì)應(yīng)的mapper配置,因此namespace的命名務(wù)必小心一定要某接口同名)。
-->
<mapper namespace="com.dy.dao.UserDao">
<!--
cache- 配置本定命名空間的緩存。
type- cache實(shí)現(xiàn)類(lèi),默認(rèn)為PERPETUAL,可以使用自定義的cache實(shí)現(xiàn)類(lèi)(別名或完整類(lèi)名皆可)
eviction- 回收算法,默認(rèn)為L(zhǎng)RU,可選的算法有:
LRU– 最近最少使用的:移除最長(zhǎng)時(shí)間不被使用的對(duì)象。
FIFO– 先進(jìn)先出:按對(duì)象進(jìn)入緩存的順序來(lái)移除它們。
SOFT– 軟引用:移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對(duì)象。
WEAK– 弱引用:更積極地移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對(duì)象。
flushInterval- 刷新間隔,默認(rèn)為1個(gè)小時(shí),單位毫秒
size- 緩存大小,默認(rèn)大小1024,單位為引用數(shù)
readOnly- 只讀
-->
<cache type="PERPETUAL" eviction="LRU" flushInterval="60000"
size="512" readOnly="true" />
<!--
cache-ref–從其他命名空間引用緩存配置。
如果你不想定義自己的cache,可以使用cache-ref引用別的cache。因?yàn)槊總€(gè)cache都以namespace為id,所以cache-ref只需要配置一個(gè)namespace屬性就可以了。需要注意的是,如果cache-ref和cache都配置了,以cache為準(zhǔn)。
-->
<cache-ref namespace="com.someone.application.data.SomeMapper"/>
<insert
<!-- 1. id (必須配置)
id是命名空間中的唯一標(biāo)識(shí)符,可被用來(lái)代表這條語(yǔ)句。
一個(gè)命名空間(namespace) 對(duì)應(yīng)一個(gè)dao接口,
這個(gè)id也應(yīng)該對(duì)應(yīng)dao里面的某個(gè)方法(相當(dāng)于方法的實(shí)現(xiàn)),因此id 應(yīng)該與方法名一致 -->
id="insertUser"
<!-- 2. parameterType (可選配置, 默認(rèn)為mybatis自動(dòng)選擇處理)
將要傳入語(yǔ)句的參數(shù)的完全限定類(lèi)名或別名, 如果不配置,mybatis會(huì)通過(guò)ParameterHandler 根據(jù)參數(shù)類(lèi)型默認(rèn)選擇合適的typeHandler進(jìn)行處理
parameterType 主要指定參數(shù)類(lèi)型,可以是int, short, long, string等類(lèi)型,也可以是復(fù)雜類(lèi)型(如對(duì)象) -->
parameterType="com.demo.User"
<!-- 3. flushCache (可選配置,默認(rèn)配置為true)
將其設(shè)置為 true,任何時(shí)候只要語(yǔ)句被調(diào)用,都會(huì)導(dǎo)致本地緩存和二級(jí)緩存都會(huì)被清空,默認(rèn)值:true(對(duì)應(yīng)插入、更新和刪除語(yǔ)句) -->
flushCache="true"
<!-- 4. statementType (可選配置,默認(rèn)配置為PREPARED)
STATEMENT,PREPARED 或 CALLABLE 的一個(gè)。這會(huì)讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認(rèn)值:PREPARED。 -->
statementType="PREPARED"
<!-- 5. keyProperty (可選配置, 默認(rèn)為unset)
(僅對(duì) insert 和 update 有用)唯一標(biāo)記一個(gè)屬性,MyBatis 會(huì)通過(guò) getGeneratedKeys 的返回值或者通過(guò) insert 語(yǔ)句的 selectKey 子元素設(shè)置它的鍵值,默認(rèn):unset。如果希望得到多個(gè)生成的列,也可以是逗號(hào)分隔的屬性名稱(chēng)列表。 -->
keyProperty=""
<!-- 6. keyColumn (可選配置)
(僅對(duì) insert 和 update 有用)通過(guò)生成的鍵值設(shè)置表中的列名,這個(gè)設(shè)置僅在某些數(shù)據(jù)庫(kù)(像 PostgreSQL)是必須的,當(dāng)主鍵列不是表中的第一列的時(shí)候需要設(shè)置。如果希望得到多個(gè)生成的列,也可以是逗號(hào)分隔的屬性名稱(chēng)列表。 -->
keyColumn=""
<!-- 7. useGeneratedKeys (可選配置, 默認(rèn)為false)
(僅對(duì) insert 和 update 有用)這會(huì)令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來(lái)取出由數(shù)據(jù)庫(kù)內(nèi)部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)的自動(dòng)遞增字段),默認(rèn)值:false。 -->
useGeneratedKeys="false"
<!-- 8. timeout (可選配置, 默認(rèn)為unset, 依賴(lài)驅(qū)動(dòng))
這個(gè)設(shè)置是在拋出異常之前,驅(qū)動(dòng)程序等待數(shù)據(jù)庫(kù)返回請(qǐng)求結(jié)果的秒數(shù)。默認(rèn)值為 unset(依賴(lài)驅(qū)動(dòng))。 -->
timeout="20">
<update
id="updateUser"
parameterType="com.demo.User"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteUser"
parameterType="com.demo.User"
flushCache="true"
statementType="PREPARED"
timeout="20">
</mapper>很明顯啊,keyProperty、keyColumn、useGeneratedKeys 這個(gè)三個(gè)屬性就是我們實(shí)現(xiàn)需求的切入點(diǎn)
開(kāi)始實(shí)現(xiàn)
方法一 useGeneratedKeys 設(shè)置主鍵自增
<insert id="insertStudentCacheId" useGeneratedKeys="true" keyProperty="id" parameterType="Student">
insert into student(name,age,score) values(#{name},#{age},#{score})
</insert>需要注意的地方:
- useGeneratedKeys="true"表示設(shè)置屬性自增,數(shù)據(jù)庫(kù)表字段需要設(shè)置
- keyProperty="id"設(shè)置主鍵的字段
- parameterType="Student"設(shè)置傳入的類(lèi)型
- 注意:雖然有返回類(lèi)型,但是我們不需要手動(dòng)設(shè)置返回的類(lèi)型,這個(gè)是由框架幫我們實(shí)現(xiàn)的,所以對(duì)應(yīng)的接口方法也是沒(méi)有返回值的,會(huì)自動(dòng)修改我們插入的對(duì)象,設(shè)置id值。所以mapper返回值是影響行數(shù)。
- 實(shí)體類(lèi)中id屬性字段一定需要set以及get方法
方法二 selectKey 查詢(xún)主鍵
selectKey 介紹
<selectKey
<!-- selectKey 語(yǔ)句結(jié)果應(yīng)該被設(shè)置的目標(biāo)屬性。如果希望得到多個(gè)生成的列,也可以是逗號(hào)分隔的屬性名稱(chēng)列表。 -->
keyProperty="id"
<!-- 結(jié)果的類(lèi)型。MyBatis 通??梢酝扑愠鰜?lái),但是為了更加確定寫(xiě)上也不會(huì)有什么問(wèn)題。MyBatis 允許任何簡(jiǎn)單類(lèi)型用作主鍵的類(lèi)型,包括字符串。如果希望作用于多個(gè)生成的列,則可以使用一個(gè)包含期望屬性的 Object 或一個(gè) Map。 -->
resultType="int"
<!-- 這可以被設(shè)置為 BEFORE 或 AFTER。如果設(shè)置為 BEFORE,那么它會(huì)首先選擇主鍵,設(shè)置 keyProperty 然后執(zhí)行插入語(yǔ)句。如果設(shè)置為 AFTER,那么先執(zhí)行插入語(yǔ)句,然后是 selectKey 元素 - 這和像 Oracle 的數(shù)據(jù)庫(kù)相似,在插入語(yǔ)句內(nèi)部可能有嵌入索引調(diào)用。 -->
order="BEFORE"
<!-- 與前面相同,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 語(yǔ)句的映射類(lèi)型,分別代表 PreparedStatement 和 CallableStatement 類(lèi)型。 -->
statementType="PREPARED">
- selectKey給了你一個(gè)簡(jiǎn)單的行為在你的數(shù)據(jù)庫(kù)中來(lái)處理自動(dòng)生成的主鍵,而不需要使你的Java代碼變得復(fù)雜。
- selectKey節(jié)點(diǎn)生成的KeyGenerator優(yōu)先級(jí)高于statement節(jié)點(diǎn)的useGeneratedKeys屬性生成的KeyGenerator對(duì)象,也就是說(shuō)配置了SelectKey子節(jié)點(diǎn)就不需要再配置useGeneratedKeys屬性了。
獲取主鍵操作
<insert id="insertStudentCacheId" parameterType="Student">
insert into student(name,age,score) values(#{name},#{age},#{score})
<!-- 指定結(jié)果類(lèi)型resultType,keyProperty是屬性,自動(dòng)返回到屬性id中,order是次序,after是指獲取id是在于插入后 -->
<selectKey resultType="int" keyProperty="id" order="AFTER">
select @@identity
</selectKey>
</insert>或者
<insert id="insertStudentCacheId" parameterType="Student">
insert into student(name,age,score) values(#{name},#{age},#{score})
<!-- 指定結(jié)果類(lèi)型resultType,keyProperty是屬性,自動(dòng)返回到屬性id中,order是次序,after是指獲取id是在于插入后 -->
<selectKey resultType="int" keyProperty="id" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
</insert>注意要點(diǎn):
- 最外層的沒(méi)有返回屬性(resultType),但是里面的是有返回值類(lèi)型的。
- order="AFTER"表示先執(zhí)行插入,之后才執(zhí)行selectkey語(yǔ)句的。
- select @@identity和select LAST_INSERT_ID()都表示選出剛剛插入的最后一條數(shù)據(jù)的id。
- 實(shí)體類(lèi)中id屬性字段一定需要set以及get方法
- 此時(shí),接口中仍不需要有返回值,框架會(huì)自動(dòng)將值注入到我們insert的那個(gè)對(duì)象中,我們可以直接使用就可以了。
同樣,我們的接口中可以有返回值,但是這個(gè)返回值不是id,而是表示插入后影響的行數(shù),此時(shí)sql中仍和上面一樣,不需要寫(xiě)返回值。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Tomcat服務(wù)器中文亂碼及Swagger亂碼相關(guān)配置解決過(guò)程
文章主要介紹了如何在IDEA中配置UTF-8編碼以解決編碼問(wèn)題,并提供了設(shè)置Tomcat服務(wù)器和Swagger的一些配置建議,希望能對(duì)大家有所幫助2025-11-11
Springcloud Eureka配置及集群代碼實(shí)例
這篇文章主要介紹了Springcloud Eureka配置及集群代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
HashMap在JDK7與JDK8中的實(shí)現(xiàn)過(guò)程解析
這幾天學(xué)習(xí)了HashMap的底層實(shí)現(xiàn),但是發(fā)現(xiàn)好幾個(gè)版本的,代碼不一,很多文章都是舊版本JDK1.6.JDK1.7的?,F(xiàn)在我來(lái)分析下JDK7與JDK8中HashMap的實(shí)現(xiàn)過(guò)程2021-09-09
SpringBoot使用讀寫(xiě)鎖解決緩存一致性的問(wèn)題
本文主要介紹了SpringBoot使用讀寫(xiě)鎖解決緩存一致性的問(wèn)題,通過(guò)在緩存類(lèi)中維護(hù)一個(gè)讀寫(xiě)鎖,可以在讀多寫(xiě)少的場(chǎng)景下提高并發(fā)訪問(wèn)效率,感興趣的可以了解一下2025-03-03
如何在Java中調(diào)用python文件執(zhí)行詳解
豐富的第三方庫(kù)使得python非常適合用于進(jìn)行數(shù)據(jù)分析,最近在項(xiàng)目中就涉及到j(luò)ava調(diào)用python實(shí)現(xiàn)的算法,下面這篇文章主要給大家介紹了關(guān)于如何在Java中調(diào)用python文件執(zhí)行的相關(guān)資料,需要的朋友可以參考下2022-05-05
springboot+thymeleaf+shiro標(biāo)簽的實(shí)例
這篇文章主要介紹了springboot+thymeleaf+shiro標(biāo)簽的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
關(guān)于Java中try finally return語(yǔ)句的執(zhí)行順序淺析
這篇文章主要介紹了關(guān)于Java中try finally return語(yǔ)句的執(zhí)行順序淺析,需要的朋友可以參考下2017-08-08
Java基礎(chǔ)類(lèi)之ArrayUtils工具類(lèi)詳解
這篇文章主要介紹了java.ArrayDeque類(lèi)使用方法,java.ArrayDeque類(lèi)提供了可調(diào)整大小的陣列,并實(shí)現(xiàn)了Deque接口,感興趣的小伙伴們可以參考一下2021-09-09
Java 實(shí)戰(zhàn)項(xiàng)目錘煉之IT設(shè)備固定資產(chǎn)管理系統(tǒng)的實(shí)現(xiàn)流程
讀萬(wàn)卷書(shū)不如行萬(wàn)里路,只學(xué)書(shū)上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java+SSM+jsp+mysql+maven實(shí)現(xiàn)一個(gè)IT設(shè)備固定資產(chǎn)管理系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平2021-11-11
基于SpringBoot2.0默認(rèn)使用Redis連接池的配置操作
這篇文章主要介紹了基于SpringBoot2.0默認(rèn)使用Redis連接池的配置操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12

