mybatis?plus常用注解的具體使用
1、@TableName
經(jīng)過(guò)以上的測(cè)試,在使用MyBatis-Plus實(shí)現(xiàn)基本的CRUD時(shí),我們并沒(méi)有指定要操作的表,只是在
Mapper接口繼承BaseMapper時(shí),設(shè)置了泛型User,而操作的表為user表。
由此得出結(jié)論,MyBatis-Plus在確定操作的表時(shí),由BaseMapper的泛型決定,即實(shí)體類型決
定,且默認(rèn)操作的表名和實(shí)體類型的類名一致。
a>問(wèn)題
若實(shí)體類類型的 類名 和要操作的表的 表名不一致 ,會(huì)出現(xiàn)什么問(wèn)題?
我們將表user更名為t_user,測(cè)試查詢功能
此時(shí)程序會(huì)報(bào)錯(cuò)
Cause: java.sql.SQLSyntaxErrorException: Table 'mybatis_plus.user' doesn't exist
因?yàn)楝F(xiàn)在的表名為t_user,而默認(rèn)操作 的表名和實(shí)體類型的類名一致,即user表。
b>通過(guò)@TableName解決問(wèn)題(推薦)
在實(shí)體類類型上添加@TableName("t_user"),標(biāo)識(shí)實(shí)體類對(duì)應(yīng)的表,即可成功執(zhí)行SQL語(yǔ)句
c>通過(guò)全局配置解決問(wèn)題(了解)
在開(kāi)發(fā)的過(guò)程中,我們經(jīng)常遇到以上的問(wèn)題,即實(shí)體類所對(duì)應(yīng)的表都有固定的前綴,例如t_或tbl_ 此時(shí),可以使用MyBatis-Plus提供的全局配置,為實(shí)體類所對(duì)應(yīng)的表名設(shè)置默認(rèn)的前綴,那么就 不需要在每個(gè)實(shí)體類上通過(guò)@TableName標(biāo)識(shí)實(shí)體類對(duì)應(yīng)的表 。
2、@TableId
經(jīng)過(guò)以上的測(cè)試,MyBatis-Plus在實(shí)現(xiàn)CRUD時(shí),會(huì)默認(rèn)將id作為主鍵列,并在插入數(shù)據(jù)時(shí),默認(rèn) 基于雪花算法的策略生成id 。
a>問(wèn)題
若實(shí)體類和表中表示主鍵的不是id,而是其他字段,例如uid,MyBatis-Plus會(huì)自動(dòng)識(shí)別uid為主 鍵列嗎? 我們實(shí)體類中的屬性id改為uid,將表中的字段id也改為uid,測(cè)試添加功能。 Cause: java.sql.SQLException: Field 'uid' doesn't have a default value 說(shuō)明MyBatis-Plus沒(méi)有將uid作為主鍵賦值。
b>通過(guò)@TableId解決問(wèn)題
在實(shí)體類中uid屬性上通過(guò)@TableId將其標(biāo)識(shí)為主鍵,即可成功執(zhí)行SQL語(yǔ)句 。
c>@TableId的value屬性
若實(shí)體類中主鍵對(duì)應(yīng)的屬性為id,而表中表示主鍵的字段為uid,此時(shí)若只在屬性id上添加注解 @TableId,則拋出異常Unknown column 'id' in 'field list',即MyBatis-Plus仍然會(huì)將id作為表的 主鍵操作,而表中表示主鍵的是字段uid 此時(shí)需要通過(guò)@TableId注解的value屬性,指定表中的主鍵字段,@TableId("uid")或 @TableId(value="uid")
d>@TableId的type屬性
e>雪花算法
背景
需要選擇合適的方案去應(yīng)對(duì)數(shù)據(jù)規(guī)模的增長(zhǎng),以應(yīng)對(duì)逐漸增長(zhǎng)的訪問(wèn)壓力和數(shù)據(jù)量。 數(shù)據(jù)庫(kù)的擴(kuò)展方式主要包括:業(yè)務(wù)分庫(kù)、主從復(fù)制,數(shù)據(jù)庫(kù)分表。 數(shù)據(jù)庫(kù)分表 將不同業(yè)務(wù)數(shù)據(jù)分散存儲(chǔ)到不同的數(shù)據(jù)庫(kù)服務(wù)器,能夠支撐百萬(wàn)甚至千萬(wàn)用戶規(guī)模的業(yè)務(wù),但如果業(yè)務(wù) 繼續(xù)發(fā)展,同一業(yè)務(wù)的單表數(shù)據(jù)也會(huì)達(dá)到單臺(tái)數(shù)據(jù)庫(kù)服務(wù)器的處理瓶頸。例如,淘寶的幾億用戶數(shù)據(jù), 如果全部存放在一臺(tái)數(shù)據(jù)庫(kù)服務(wù)器的一張表中,肯定是無(wú)法滿足性能要求的,此時(shí)就需要對(duì)單表數(shù)據(jù)進(jìn) 行拆分。 單表數(shù)據(jù)拆分有兩種方式:垂直分表和水平分表。示意圖如下:
垂直分表
垂直分表適合將表中某些不常用且占了大量空間的列拆分出去。
例如,前面示意圖中的 nickname 和 description 字段,假設(shè)我們是一個(gè)婚戀網(wǎng)站,用戶在篩選其他用 戶的時(shí)候,主要是用 age 和 sex 兩個(gè)字段進(jìn)行查詢,而 nickname 和 description 兩個(gè)字段主要用于展 示,一般不會(huì)在業(yè)務(wù)查詢中用到。description 本身又比較長(zhǎng),因此我們可以將這兩個(gè)字段獨(dú)立到另外 一張表中,這樣在查詢 age 和 sex 時(shí),就能帶來(lái)一定的性能提升。
水平分表
水平分表適合表行數(shù)特別大的表,有的公司要求單表行數(shù)超過(guò) 5000 萬(wàn)就必須進(jìn)行分表,這個(gè)數(shù)字可以 作為參考,但并不是絕對(duì)標(biāo)準(zhǔn),關(guān)鍵還是要看表的訪問(wèn)性能。對(duì)于一些比較復(fù)雜的表,可能超過(guò) 1000 萬(wàn)就要分表了;而對(duì)于一些簡(jiǎn)單的表,即使存儲(chǔ)數(shù)據(jù)超過(guò) 1 億行,也可以不分表。
但不管怎樣,當(dāng)看到表的數(shù)據(jù)量達(dá)到千萬(wàn)級(jí)別時(shí),作為架構(gòu)師就要警覺(jué)起來(lái),因?yàn)檫@很可能是架構(gòu)的性 能瓶頸或者隱患。 水平分表相比垂直分表,會(huì)引入更多的復(fù)雜性,例如要求全局唯一的數(shù)據(jù)id該如何處理。
主鍵自增
①以最常見(jiàn)的用戶 ID 為例,可以按照 1000000 的范圍大小進(jìn)行分段,1 ~ 999999 放到表 1中, 1000000 ~ 1999999 放到表2中,以此類推。
②復(fù)雜點(diǎn):分段大小的選取。分段太小會(huì)導(dǎo)致切分后子表數(shù)量過(guò)多,增加維護(hù)復(fù)雜度;分段太大可能會(huì) 導(dǎo)致單表依然存在性能問(wèn)題,一般建議分段大小在 100 萬(wàn)至 2000 萬(wàn)之間,具體需要根據(jù)業(yè)務(wù)選取合適 的分段大小。
③優(yōu)點(diǎn):可以隨著數(shù)據(jù)的增加平滑地?cái)U(kuò)充新的表。例如,現(xiàn)在的用戶是 100 萬(wàn),如果增加到 1000 萬(wàn), 只需要增加新的表就可以了,原有的數(shù)據(jù)不需要?jiǎng)印?/p>
④缺點(diǎn):分布不均勻。假如按照 1000 萬(wàn)來(lái)進(jìn)行分表,有可能某個(gè)分段實(shí)際存儲(chǔ)的數(shù)據(jù)量只有 1 條,而 另外一個(gè)分段實(shí)際存儲(chǔ)的數(shù)據(jù)量有 1000 萬(wàn)條。
取模
①同樣以用戶 ID 為例,假如我們一開(kāi)始就規(guī)劃了 10 個(gè)數(shù)據(jù)庫(kù)表,可以簡(jiǎn)單地用 user_id % 10 的值來(lái) 表示數(shù)據(jù)所屬的數(shù)據(jù)庫(kù)表編號(hào),ID 為 985 的用戶放到編號(hào)為 5 的子表中,ID 為 10086 的用戶放到編號(hào) 為 6 的子表中。
②復(fù)雜點(diǎn):初始表數(shù)量的確定。表數(shù)量太多維護(hù)比較麻煩,表數(shù)量太少又可能導(dǎo)致單表性能存在問(wèn)題。
③優(yōu)點(diǎn):表分布比較均勻。
④缺點(diǎn):擴(kuò)充新的表很麻煩,所有數(shù)據(jù)都要重分布。
雪花算法
雪花算法是由Twitter公布的分布式主鍵生成算法,它能夠保證不同表的主鍵的不重復(fù)性,以及相同表的 主鍵的有序性。
①核心思想:
長(zhǎng)度共64bit(一個(gè)long型)。 首先是一個(gè)符號(hào)位,1bit標(biāo)識(shí),由于long基本類型在Java中是帶符號(hào)的,最高位是符號(hào)位,正數(shù)是0,負(fù) 數(shù)是1,所以id一般是正數(shù),最高位是0。
41bit時(shí)間截(毫秒級(jí)),存儲(chǔ)的是時(shí)間截的差值(當(dāng)前時(shí)間截 - 開(kāi)始時(shí)間截),結(jié)果約等于69.73年。 10bit作為機(jī)器的ID(5個(gè)bit是數(shù)據(jù)中心,5個(gè)bit的機(jī)器ID,可以部署在1024個(gè)節(jié)點(diǎn))。 12bit作為毫秒內(nèi)的流水號(hào)(意味著每個(gè)節(jié)點(diǎn)在每毫秒可以產(chǎn)生 4096 個(gè) ID)。
②優(yōu)點(diǎn):整體上按照時(shí)間自增排序,并且整個(gè)分布式系統(tǒng)內(nèi)不會(huì)產(chǎn)生ID碰撞,并且效率較高。
3、@TableField
經(jīng)過(guò)以上的測(cè)試,我們可以發(fā)現(xiàn),MyBatis-Plus在執(zhí)行SQL語(yǔ)句時(shí),要保證實(shí)體類中的屬性名和 表中的字段名一致 。 如果實(shí)體類中的屬性名和字段名不一致的情況,會(huì)出現(xiàn)什么問(wèn)題呢?
a>情況1
若實(shí)體類中的屬性使用的是駝峰命名風(fēng)格,而表中的字段使用的是下劃線命名風(fēng)格。 例如實(shí)體類屬性u(píng)serName,表中字段user_name。 此時(shí)MyBatis-Plus會(huì)自動(dòng)將下劃線命名風(fēng)格轉(zhuǎn)化為駝峰命名風(fēng)格。 相當(dāng)于在MyBatis中配置。
b>情況2
若實(shí)體類中的屬性和表中的字段不滿足情況1。 例如實(shí)體類屬性name,表中字段username。 此時(shí)需要在實(shí)體類屬性上使用@TableField("username")設(shè)置屬性所對(duì)應(yīng)的字段名。
4、@TableLogic
a>邏輯刪除
物理刪除:真實(shí)刪除,將對(duì)應(yīng)數(shù)據(jù)從數(shù)據(jù)庫(kù)中刪除,之后查詢不到此條被刪除的數(shù)據(jù)。 邏輯刪除:假刪除,將對(duì)應(yīng)數(shù)據(jù)中代表是否被刪除字段的狀態(tài)修改為“被刪除狀態(tài)”,之后在數(shù)據(jù)庫(kù)中仍舊能看到此條數(shù)據(jù)記錄。 使用場(chǎng)景:可以進(jìn)行數(shù)據(jù)恢復(fù)。
b>實(shí)現(xiàn)邏輯刪除
step1:數(shù)據(jù)庫(kù)中創(chuàng)建邏輯刪除狀態(tài)列,設(shè)置默認(rèn)值為0
step2:實(shí)體類中添加邏輯刪除屬性
step3:測(cè)試
刪除的方法
@Test public void testDelete(){ int i = userMapper.deleteById(2L);//根據(jù)主鍵id進(jìn)行刪除 System.out.println(i); }
其sql語(yǔ)句不是delete而是改成了update
UPDATE t_user SET is_deleted=1 WHERE uid=? AND is_deleted=0
數(shù)據(jù)庫(kù)中我們可以看到確實(shí)修改了
查詢的方法
@Test public void testSelectList(){ List<User> userList = userMapper.selectList(null); // 這個(gè)地方的輸出是使用的Java8新特性的方法引用,如果想學(xué)習(xí)Java8新特性的可以看我前面 // 介紹的有關(guān)Java8新特性的介紹 userList.forEach(System.out::println); }
其sql語(yǔ)句是
SELECT uid AS id,name,age,email,is_deleted FROM t_user WHERE is_deleted=0
自動(dòng)過(guò)濾掉邏輯刪除的了。
到此這篇關(guān)于mybatis plus常用注解的具體使用的文章就介紹到這了,更多相關(guān)mybatis plus常用注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于SpringBoot + Redis實(shí)現(xiàn)密碼暴力破解防護(hù)
在現(xiàn)代應(yīng)用程序中,保護(hù)用戶密碼的安全性是至關(guān)重要的,密碼暴力破解是指通過(guò)嘗試多個(gè)密碼組合來(lái)非法獲取用戶賬戶的密碼,為了保護(hù)用戶密碼不被暴力破解,我們可以使用Spring Boot和Redis來(lái)實(shí)現(xiàn)一些防護(hù)措施,本文將介紹如何利用這些技術(shù)來(lái)防止密碼暴力破解攻擊2023-06-06springboot中生成文件路徑的問(wèn)題及解決方法
這篇文章主要介紹了springboot中生成文件路徑的問(wèn)題及解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01如何從eureka獲取服務(wù)的ip和端口號(hào)進(jìn)行Http的調(diào)用
這篇文章主要介紹了如何從eureka獲取服務(wù)的ip和端口號(hào)進(jìn)行Http的調(diào)用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03SpringCloud?Gateway實(shí)現(xiàn)API接口加解密
這篇文章主要為大家介紹了SpringCloud?Gateway如何實(shí)現(xiàn)API接口加解密的,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定的幫助,需要的可以參考一下2022-06-06解析ConcurrentHashMap: 紅黑樹(shù)的代理類(TreeBin)
ConcurrentHashMap是由Segment數(shù)組結(jié)構(gòu)和HashEntry數(shù)組結(jié)構(gòu)組成。Segment的結(jié)構(gòu)和HashMap類似,是一種數(shù)組和鏈表結(jié)構(gòu),今天給大家普及java面試常見(jiàn)問(wèn)題---ConcurrentHashMap知識(shí),一起看看吧2021-06-06