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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MyBatis-Plus 乐观锁 防止超卖、逻辑删除、自动填充、Id自增

發布時間:2025/3/19 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MyBatis-Plus 乐观锁 防止超卖、逻辑删除、自动填充、Id自增 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

MyBatis-Plus 樂觀鎖 防止超賣、邏輯刪除、自動填充 Day3

前面的簡單的講了一下mybatis-plus的使用 當然有很多不足 我寫博客就是想促進大家一起學習 也想讓這些內容更簡單一些。

介紹

這次就主要講樂觀鎖、邏輯刪除、自動填充。這幾項在項目是用的非常多的。

先講一下主要應用 之后再講理論和實現。

  • 樂觀鎖:

    主要用于防止商品超賣的方面

  • 邏輯刪除:

    邏輯刪除主要是用于用戶對于數據的誤刪的一種撤銷機制。

    刪除分為兩種

    • 一種是物理刪除 就是數據庫層面的刪除 徹底的從磁盤中刪除
    • 另外一種就是今天講的 邏輯刪除 刪除后還是會在數據庫里保存著 只是查詢的時候 需要帶上參數才能查到
    • 當然徹底刪除的時候也是需要帶上那個參數才能徹底刪除的。
  • 自動填充:

    • 我之前看阿里的那個規范的時候 有看到就是說在數據庫里面建立每一張表 都需要有創建時間和修改時間

    • 所以MP就提供自動填充的功能,幫助自定設置這些字段的值,提升開發效率,代碼也會顯得特別優雅。

  • 樂觀鎖

    當要更新一條記錄的時候,希望這條記錄沒有被別人更新
    樂觀鎖實現方式:

    • 取出記錄時,獲取當前version
    • 更新時,帶上這個version
    • 執行更新時, set version = newVersion where version = oldVersion
    • 如果version不對,就更新失敗

    能夠保證數據的安全性和一致性。

    因為后面還有邏輯刪除、自動填充 環境就全部搭好拉。

    使用方法

    字段上加上@Version注解

    @Version private Integer version;

    mybatis配置注入下面這個bean

    @Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}

    環境搭建 :

    • DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',`age` int(11) NULL DEFAULT NULL COMMENT '年齡',`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '郵箱',`version` int(10) NULL DEFAULT 1 COMMENT '樂觀鎖',`deleted` int(10) NULL DEFAULT 0 COMMENT '邏輯刪除',`create_time` datetime(0) NULL DEFAULT NULL COMMENT '創建時間',`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新時間',PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1337575143814062086 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    • 要導入的依賴 這里就不說了 我之前的博客也有。

    • user層

      @Data @AllArgsConstructor @NoArgsConstructor @Accessors(chain = true) @TableName(value = "user") public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private Integer age;private String email;@Version // 這里是樂觀鎖的注解private Integer version;@TableLogic // 這是邏輯刪除的注解private Integer deleted;@TableField(fill = FieldFill.INSERT) //這里是自動填充的注解private Date createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime; }
    • mapper層

      public interface UserMapper extends BaseMapper<User> {}
    • MyBatisPlusConfig

      @Configuration public class MybatisPlusConfig {// 分頁@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();// 這里是注冊分頁插件mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 注冊樂觀鎖 插件mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;} }
    • yaml

      server:port: 8484 spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=UTC&useSSL=false&characterEncoding=utf8&serverTimezone=GMT

    樂觀鎖測試

    先測試一下 沒有加樂觀鎖的 會是什么樣

    @Testpublic void updateOptimisticLockerInterceptor(){//A 線程User user = userMapper.selectById(102L);user.setName("點贊1");user.setAge(3);//B 線程 模擬另外一個線程插隊User user1 = userMapper.selectById(102L);user1.setName("收藏加三連");user1.setAge(4);userMapper.updateById(user1);// 自旋鎖來嘗試多次提交userMapper.updateById(user); // 如果沒有樂觀鎖 就會覆蓋插隊的值}

    下面給大家看一下控制臺的輸出

    為了方便觀看 我把測試數據改了 來接著看一下這次的結果

    @Testpublic void updateOptimisticLockerInterceptor(){//A 線程User user = userMapper.selectById(102L);user.setName("關注寧在春");user.setAge(3);//B 線程 模擬另外一個線程插隊User user1 = userMapper.selectById(102L);user1.setName("給寧在春點贊");user1.setAge(4);userMapper.updateById(user1);// 自旋鎖來嘗試多次提交userMapper.updateById(user); // 如果沒有樂觀鎖 就會覆蓋插隊的值}

    這就是加了樂觀鎖的作用 在多線程下 可以保證數據的安全 防止商品超賣等等。

    邏輯刪除

    只對自動注入的sql起效:

    • 插入: 不作限制
    • 查找: 追加where條件過濾掉已刪除數據,且使用 wrapper.entity 生成的where條件會忽略該字段
    • 更新: 追加where條件防止更新到已刪除數據,且使用 wrapper.entity 生成的where條件會忽略該字段
    • 刪除: 轉變為 更新

    例如:

    • 刪除: update user set deleted=1 where id = 1 and deleted=0
    • 查找: select id,name,deleted from user where deleted=0

    使用方法:

    步驟1: 配置

    • 在application.yml 加入下面配置
    mybatis-plus:global-config:db-config:logic-delete-field: flag # 全局邏輯刪除的實體字段名(since 3.3.0,配置后可以忽略不配置步驟2)logic-delete-value: 1 # 邏輯已刪除值(默認為 1)logic-not-delete-value: 0 # 邏輯未刪除值(默認為 0)

    步驟2: 實體類字段上加上@TableLogic注解

    @TableLogic private Integer deleted;

    邏輯刪除 測試

    // TODO tableLogic 邏輯刪除 @Test public void tableLogic(){userMapper.deleteById(103);List<User> userList = userMapper.selectList(null);userList.forEach(System.out::println); }

    測試結果如下 使用查詢全部方法 明顯查不到這行數據拉 我們接下來看看 數據庫里的表 看還有沒有

    數據庫里面還存在 只是deleted 變成1拉

    自動填充

    原理:

    • 實現元對象處理器接口:com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
    • 注解填充字段 @TableField(.. fill = FieldFill.INSERT) 生成器策略部分也可以配置!
    public class User {// 注意!這里需要標記為填充字段@TableField(fill = FieldFill.INSERT)private Date createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime;}
    • 自定義實現類 MyMetaObjectHandler

      @Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("start insert fill ....");this.setFieldValByName("createTime",new Date(),metaObject);this.setFieldValByName("updateTime",new Date(),metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {log.info("start update fill ....");this.setFieldValByName("updateTime",new Date(),metaObject);} }

    測試

    我們來增加一行數據看一看會不會吧 這里把Id 自增也講一起講了吧

    mybatisplus 默認的主鍵自增 是默認使用雪花算法+UUID(不含中劃線)

    具體的 大家可以自行研究。

    //TODO insert 配置了自動填充后的insert @Test public void insert() {User user = new User().setName("自動填充").setAge(99).setEmail("ssss@qq.com");int i = userMapper.insert(user);System.out.println(i);Map<String, Object> map = new HashMap<String,Object>();map.put("name","自動填充");List<User> users = userMapper.selectByMap(map);users.forEach(System.out::println); }

    測試圖:

    搞定

    溜了溜了

    大家看的好 就評論評論 一起學習學習咯

    剛開始 文筆不咋好 爭取之后 我加油寫的好一些 再來點故事。

    總結

    以上是生活随笔為你收集整理的MyBatis-Plus 乐观锁 防止超卖、逻辑删除、自动填充、Id自增的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。