日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

【Java开发】 Mybatis-Plus 02:Mapper-CRUD+自动填充+乐观锁

發(fā)布時間:2023/12/15 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java开发】 Mybatis-Plus 02:Mapper-CRUD+自动填充+乐观锁 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天正好學(xué)習(xí)了Mybatis-Plus Mapper的Insert、Update 及自動填充功能的使用,特來和大家分享一下,需要注意的是我用的Mybatis-Plus版本是3.5.2,基礎(chǔ)配置可見01。

目錄

1?Insert

1.1 測試插入

1.2?主鍵生成策略

1.2.1?主鍵自增:

1.2.2?手動輸入:

2?Update

3?自動填充

3.1 方式一:數(shù)據(jù)庫級別

①數(shù)據(jù)表增加字段:create_time,update_time

②實體類中同步!

③查看結(jié)果

3.2 方式二:通過代碼

①取消數(shù)據(jù)庫的默認(rèn)值,更新操作!

②實體類字段屬性上需要增加注解

③編寫處理器來處理注解!

④測試插入/更新,觀察時間:

⑤輸出結(jié)果

4?樂觀鎖

4.1?數(shù)據(jù)庫中增加version字段

4.2?實體類加對應(yīng)的字段

4.3?注冊組件

4.4?測試

① 測試樂觀鎖成功

② 測試樂觀鎖失敗

5 Select

5.1 普通查詢

① 通過id查詢單個用戶

② 通過id查詢多個用戶

③?條件查詢 通過map封裝

5.2 分頁查詢

① 配置攔截器組件

②?直接使用page對象

③ 查看結(jié)果

6 Delete

6.1 普通刪除

6.2?邏輯刪除

① 數(shù)據(jù)表增加deleted字段

② 實體類中添加對應(yīng)屬性

③?配置!

④?測試邏輯刪除


源碼地址:尹煜 / mybatis_plus_study · GitCode

1?Insert

1.1 測試插入

路徑:src/test/java/com/yinyu/MybatisPlusApplicationTests.java

//測試插入 @Test public void testInsert(){User user = new User();user.setName("尹煜");user.setAge(3);user.setEmail("yinyu@163.com");int result = userMapper.insert(user);//幫助用戶自動生成idSystem.out.println(result);//受影響的行數(shù)System.out.println(user);//通過日志發(fā)現(xiàn)id會自動回填 }

輸出結(jié)果:

需要注意的是,數(shù)據(jù)庫插入的id的默認(rèn)值為全局的唯—id,而且是自動生成的。

1.2?主鍵生成策略

分布式系統(tǒng)唯一Id生成方案鏈接分布式系統(tǒng)唯一ID生成方案匯總

源碼解釋:

public enum IdType {AUTO, //數(shù)據(jù)庫id自增NONE;//未設(shè)置主鍵INPUT, //手動輸入ID_WORKER, //默認(rèn)的全局唯一idUUID, //全局唯一id uuidID_WORKER_STR, //字符串表示法** } Mybatis-Plus用的是Twitter的snowflake算法:

snowflake是Twitter開源的分布式ID生成算法,結(jié)果是一個long型的ID。其核心思想是:使用41bit作為毫秒數(shù),10bit作為機器的ID(5個bit是數(shù)據(jù)中心(北京、香港···),5個bit的機器ID),12bit作為毫秒內(nèi)的流水號(意味著每個節(jié)點在每毫秒可以產(chǎn)生 4096 個 ID),最后還有一個符號位,永遠是0。

1.2.1?主鍵自增:

AUTO 我們需要配置主鍵自增

在實體類字段上配置@TableId(type = IdType.AUTO)

數(shù)據(jù)庫字段設(shè)置自增

我用的是DBeaver可視化軟件

?③執(zhí)行testInsert,輸出結(jié)果:

1.2.2?手動輸入:

INPUT 就需要自己寫id ①在實體類字段上配置@TableId(type = IdType.INPUT)

?②執(zhí)行testInsert(id:null)

?可以看到插入成功,但是id為null,不過mysql會匹配成自增輸入id形式,所以也沒有報錯。

執(zhí)行testInsert(id:6)

?

2?Update

路徑:src/test/java/com/yinyu/MybatisPlusApplicationTests.java

//測試更新 public void testUpdate(){User user = new User();user.setId(6L);user.setName("無關(guān)風(fēng)月");//updateById,但是參數(shù)是個user!!int result = userMapper.updateById(user);System.out.println(result);System.out.println(user); }

輸出結(jié)果:

3?自動填充

創(chuàng)建時間、更改時間! 這些操作一般都是自動化完成,我們不希望手動更新

阿里巴巴開發(fā)手冊︰幾乎所有的表都要配置 gmt_create、gmt_modified !而且需要自動化

3.1 方式一:數(shù)據(jù)庫級別

注意:工作中不允許修改數(shù)據(jù)庫級別,不推薦此種方式

①數(shù)據(jù)表增加字段:create_time,update_time

?②實體類中同步!

路徑:src/main/java/com/yinyu/pojo/User.java

private Date createTime;//駝峰命名 private Date updateTime;

查看結(jié)果

3.2 方式二:通過代碼

取消數(shù)據(jù)庫的默認(rèn)值,更新操作!

?注意不是刪掉字段,而是取消默認(rèn)值等👇

?②實體類字段屬性上需要增加注解

路徑:src/main/java/com/yinyu/pojo/User.java

//字段 字段添加填充內(nèi)容 @TableField(fill = FieldFill.INSERT)//value = ("create_time"), private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;

③編寫處理器來處理注解!

自動填充功能官方文檔:自動填充功能 | MyBatis-Plus

官方已更新setFieldValByName方法為strictInsertFill或fillStrategy等,不過需要將mybatis-plus版本升級到3.3.0及以上,由于本文mybatis-plus版本在3.5.2,采用官網(wǎng)推薦的方法👇

路徑:src/main/java/com/yinyu/handler/MyMetaObjectHandler.java

@Slf4j//日志 @Component public class MyMetaObjectHandler implements MetaObjectHandler {@Override//插入時的填充策略public void insertFill(MetaObject metaObject) {log.info("==start insert ······==");//setFieldValByName(java.lang.String fieldName, java.lang.Object fieldVal, org.apache.ibatis.reflection.MetaObject metaObject)this.strictInsertFill(metaObject,"createTime",Date.class, new Date());this.strictInsertFill(metaObject,"updateTime",Date.class, new Date());}@Override//更新時的填充策略public void updateFill(MetaObject metaObject) {log.info("==start update ······==");this.strictUpdateFill(metaObject,"updateTime",Date.class, new Date());} }

測試插入/更新,觀察時間:

//測試插入@Testpublic void testInsert(){User user = new User();user.setName("testMetaObjectInsert");user.setAge(3);user.setEmail("yinyu@163.com");int result = userMapper.insert(user);//幫助用戶自動生成idSystem.out.println(result);//受影響的行數(shù)System.out.println(user);//通過日志發(fā)現(xiàn)id會自動回填}//測試更新@Testpublic void testUpdate(){User user = new User();user.setId(6L);user.setName("testMetaObjectUpdate");int result = userMapper.updateById(user);System.out.println(result);System.out.println(user);}

⑤輸出結(jié)果

4?樂觀鎖

面試過程中經(jīng)常被問到樂觀鎖/悲觀鎖👇

樂觀鎖:顧名思義十分樂觀,他總是認(rèn)為不會出現(xiàn)問題,無論干什么都不上鎖!如果出現(xiàn)了問題,再次更新值測試。

悲觀鎖:顧名思義十分悲觀,他總是認(rèn)為出現(xiàn)問題,無論干什么都會上鎖!再去操作!

樂觀鎖實現(xiàn)方式:

  • 取出記錄時,獲取當(dāng)前version

  • 更新時,帶上這個version

  • 執(zhí)行更新時,set version = newVersion where version = oldVersion

  • 如果version不對,就更新失敗

樂觀鎖:先查詢,獲得版本號 -- A update user set name = "yinyu",version = version+1 where id = 1 and version = 1 -- B (B線程搶先完成,此時version=2,會導(dǎo)致A線程修改失敗!) update user set name = "yinyu",version = version+1 where id = 1 and version = 1

接下里實踐一下~

4.1?數(shù)據(jù)庫中增加version字段

4.2?實體類加對應(yīng)的字段

路徑:src/main/java/com/yinyu/pojo/User.java

@Version//樂觀鎖version注解 private Integer version;

說明:

  • 支持的數(shù)據(jù)類型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整數(shù)類型下?newVersion = oldVersion + 1
  • newVersion?會回寫到?entity?中
  • 僅支持?updateById(id)?與?update(entity, wrapper)?方法
  • 在?update(entity, wrapper)?方法下,?wrapper?不能復(fù)用!!!

4.3?注冊組件

路徑:src/main/java/com/yinyu/config/MyBatisPlusConfig.java

@MapperScan("com.yinyu.mapper")//交給mybatis做的,可以讓這個配置類做掃描 @EnableTransactionManagement//自動管理事務(wù) @Configuration//配置類 public class MyBatisPlusConfig {/*** 新版*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;} }

4.4?測試

① 測試樂觀鎖成功

@Test//測試樂觀鎖成功 public void testOptimisticLocker1(){//1、查詢用戶信息User user = userMapper.selectById(1L);//2、修改用戶信息user.setAge(18);user.setEmail("yinyu@qq.com");//3、執(zhí)行更新操作userMapper.updateById(user); } 首先執(zhí)行查詢sql,然后進行修改,version加1

測試樂觀鎖失敗

@Test//測試樂觀鎖失敗 多線程下 public void testOptimisticLocker2(){//線程1User user1 = userMapper.selectById(2L);user1.setAge(18);user1.setEmail("yinyu@qq.com");//線程2,模擬另外一個線程執(zhí)行了插隊操作User user2 = userMapper.selectById(2L);user2.setAge(17);user2.setEmail("yinyu17@qq.com");userMapper.updateById(user2);//自旋鎖來多次嘗試提交!userMapper.updateById(user1);//如果沒有樂觀鎖就會覆蓋插隊線程的值 }

?

由于自旋鎖多次提交,最后覆蓋的是線程1的數(shù)據(jù),不過version依舊為2。

5 Select

5.1 普通查詢

① 通過id查詢單個用戶

@Test//通過id查詢單個用戶 public void testSelectById(){User user = userMapper.selectById(1L);System.out.println(user); }

② 通過id查詢多個用戶

@Test//通過id查詢多個用戶 public void testSelectBatchIds(){List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));users.forEach(System.out::println); }

③?條件查詢 通過map封裝

關(guān)于復(fù)雜的查詢之后會用wrapper操作 @Test//通過條件查詢之一 map public void testMap(){HashMap<String, Object> map = new HashMap<>();//自定義要查詢的map.put("name","尹煜");map.put("age",3);List<User> users = userMapper.selectByMap(map);users.forEach(System.out::println); }

5.2 分頁查詢

分頁在網(wǎng)站的使用非常之多!

1、原始的limit分頁

2、pageHelper第三方插件

3、MybatisPlus其實也內(nèi)置了分頁插件!!!

① 配置攔截器組件

路徑:src/main/java/com/yinyu/config/MyBatisPlusConfig.java

//新的分頁插件,,一緩和二緩遵循mybatis的規(guī)則 mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); 將上述代碼插入下邊就行

②?直接使用page對象

@Test//測試分頁查詢 public void testPage(){//參數(shù)一current:當(dāng)前頁 參數(shù)二size:頁面大小//使用了分頁插件之后,所有的分頁操作都變得簡單了Page<User> page = new Page<>(2,3);userMapper.selectPage(page,null);page.getRecords().forEach(System.out::println);System.out.println("總頁數(shù)==>"+page.getPages()); }

③ 查看結(jié)果

6 Delete

6.1 普通刪除

類似select~

@Test public void testDeleteById(){userMapper.deleteById(1L); } @Test public void testDeleteBatchIds(){userMapper.deleteBatchIds(Arrays.asList(2L,3L)); } @Test public void testD(){HashMap<String, Object> map = new HashMap<>();map.put("age","18");map.put("name","john");userMapper.deleteByMap(map); }

6.2?邏輯刪除

物理刪除:從數(shù)據(jù)庫中直接刪除

邏輯刪除:在數(shù)據(jù)庫中沒有被刪除,而是通過一個變量來使他失效! deleted=0 ==> deleted=1

場景:管理員可以查看被刪除的記錄!防止數(shù)據(jù)的丟失,類似于回收站!

① 數(shù)據(jù)表增加deleted字段

② 實體類中添加對應(yīng)屬性

路徑:src/main/java/com/yinyu/pojo/User.java @TableLogic//邏輯刪除注解 private Integer deleted;

③?配置!

3.3版本后只需要在下邊或yaml中配置即可

路徑:src/main/resources/application.properties

#配置邏輯刪除 沒刪除的為0 刪除的為1 mybatis-plus.global-config.db-config.logic-delete-field: flag mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0

④?測試邏輯刪除

@Test public void testDeleteById(){userMapper.deleteById(4L); }

發(fā)現(xiàn): 記錄還在,deleted變?yōu)?

再次測試查詢被刪除的用戶,發(fā)現(xiàn)查詢?yōu)榭?/span>

@Test public void testselect(){User user = userMapper.selectById(4);System.out.println(user); }

👇

說明邏輯刪除已成功

以上所有的CRUD及其擴展操作,我們都必須精通掌握!會大大提高工作寫項目的效率!


總結(jié)

大家如果有疑問都可以評論提出,有不足之處請大家批評指正,希望能多結(jié)識這方面的朋友,共同學(xué)習(xí)、共同進步。

總結(jié)

以上是生活随笔為你收集整理的【Java开发】 Mybatis-Plus 02:Mapper-CRUD+自动填充+乐观锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。