浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除
生活随笔
收集整理的這篇文章主要介紹了
浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
淺談:MyBatis-Plus的CRUD與樂觀鎖,分頁插件,邏輯刪除
MyBatis-Plus官方文檔連接
什么是MyBatis-Plus
請點擊上面官方文檔查看
代碼演示:代碼注釋為功能詳細解釋
數據庫
創建maven項目,基于springboot,mvc請參考官網
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fs</groupId><artifactId>MyBatisPlus-HelloWorld</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.1.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><java.version>1.8</java.version></properties><dependencies><!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.2</version></dependency><!-- 由于引入了MyBatisPlus ,就不需要引入這個了,因為MyBatis-puls底層就是對MyBatis封裝 spring MyBatis--> <!-- <dependency>--> <!-- <groupId>org.mybatis.spring.boot</groupId>--> <!-- <artifactId>mybatis-spring-boot-starter</artifactId>--> <!-- <version>2.1.3</version>--> <!-- </dependency>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.20</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>application.yml
spring:datasource:username: rootpassword: rooturl: jdbc:mysql://192.168.93.132:3306/testdriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource #自定義數據源# 配置開發環境profiles:active: dev # 配置日志 mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #配置邏輯刪除global-config:db-config:logic-delete-field: flag # 全局邏輯刪除的實體字段名(since 3.3.0,配置后可以忽略不配置步驟2)logic-delete-value: 1 # 邏輯已刪除值(默認為 1)logic-not-delete-value: 0 # 邏輯未刪除值(默認為 0)主啟動 MybatispulsHelloWorld
package com.fs;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class MybatispulsHelloWorld {public static void main(String[] args) {SpringApplication.run(MybatispulsHelloWorld.class,args);} }MyBatis-Plus配置類
package com.fs.config;import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration//配置類 //開啟事務管理 @EnableTransactionManagement //使用MyBatis-puls要使用@MapperScan掃描dao的包 @MapperScan("com.fs.dao") public class MybatisPlusConfig {//注冊樂觀鎖插件@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();}//配置分頁插件@Beanpublic PaginationInterceptor paginationInterceptor() {PaginationInterceptor paginationInterceptor = new PaginationInterceptor();// 設置請求的頁面大于最大頁后操作, true調回到首頁,false 繼續請求 默認false// paginationInterceptor.setOverflow(false);// 設置最大單頁限制數量,默認 500 條,-1 不受限制// paginationInterceptor.setLimit(500);// 開啟 count 的 join 優化,只針對部分 left joinpaginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));return paginationInterceptor;}//邏輯刪除 新版在yml配置了,這里不用配置 // @Bean // public ISqlInjector sqlInjector(){ // return new DefaultSqlInjector(); // }// /** // * SQL執行效率插件 在3.2上已被移除 // * // * @return // */ // @Bean // @Profile({"dev"}) // 指定環境為dev生效 // public PerformanceInterceptor performanceInterceptor() { // PerformanceInterceptor interceptor = new PerformanceInterceptor(); // // sql美化打印 // interceptor.setFormat(true); // // 設置SQL超時時間 // interceptor.setMaxTime(5000L); // return interceptor; // }}自動填充功能類 MyMetaObjectHandler
package com.fs.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component;import java.util.Date;@Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler {//插入的時候充填策略@Overridepublic void insertFill(MetaObject metaObject) {log.info("start insert fill ....");this.setFieldValByName("creatTime",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);} }pojo實體類User 屬性對應數據庫表的字段
package com.fs.pojo;import com.baomidou.mybatisplus.annotation.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import org.apache.ibatis.annotations.Delete;import java.util.Date;@Data @ToString @AllArgsConstructor @NoArgsConstructor public class User {//對應數據庫中的主鍵,通過雪花算法@TableId(type = IdType.ID_WORKER)private Long id;private String name;private Integer age;private String email;// //在insert的時候插入 // @TableField(fill = FieldFill.INSERT) // private Date creatTime; // @TableField(fill = FieldFill.INSERT_UPDATE) // private Date updateTime;// //版本 // @Version//代表這是一個樂觀鎖的注解 // @TableField(value = "`version`")//處理數據庫關鍵字 // private Integer version;// //邏輯刪除 // @TableLogic//這個注解就代表這個表中的字段存在邏輯 // @TableField(value = "`delete`")//處理數據庫關鍵字 // private Integer delete; }mapper或者Dao接口 UserDao
這個接口要繼承 BaseMapper<T>接口
package com.fs.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.fs.pojo.User;//使用MyBatis-puls,只需要在UserDao接口上實現BaseMapper<實體類> //這樣,所有的CRUD都已經寫完了,不需要在配置一大堆文件 public interface UserDao extends BaseMapper<User> { }測試類
package com.fs;import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fs.dao.UserDao; import com.fs.pojo.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;import java.util.Arrays; import java.util.HashMap; import java.util.List;@SpringBootTest public class MybatispulsHelloWorldTest {//userDao繼承了BaseMapper.所有的方法都來自父類//我們也可以自己編寫自己的擴展方法@Autowiredprivate UserDao userDao;//測試查詢所有@Testpublic void testUser(){//selectList的參數是一個Wrapper 條件構造器,不傳就填null//查詢全部用戶List<User> users = userDao.selectList(null);for (User user : users) {System.out.println(user);}}//測試添加@Testpublic void testUserInsert(){//會自動根據你傳遞的對象的屬性值不為null的來動態sql 就是xml 中的if/*private Long id;private String name;private Integer age;private String email;*///添加一個用戶 // userDao.insert(new User(null,"小付",18,"934226217@qq.com"));User user = new User();user.setName("測試2"); // user.setAge(12);userDao.insert(user);}//測試更新@Testpublic void testUserupdateById(){/*private Long id;private String name;private Integer age;private String email;*/User user = new User();user.setName("小強");user.setId(1293148203881086977L);//添加一個用戶userDao.updateById(user);}//測試樂觀鎖成功@Testpublic void optimisticLocker(){User user = userDao.selectById(1L);user.setName("大大");user.setAge(1);user.setEmail("1213@qq.com");userDao.updateById(user);}//測試樂觀失敗,多線程下@Testpublic void optimisticLocker02(){//線程一User user = userDao.selectById(1L);user.setName("大大111");user.setAge(1);user.setEmail("1213@qq.com");//模擬另一個線程執行插隊抄作User user1 = userDao.selectById(1L);user1.setName("大大22");user1.setAge(1);user1.setEmail("1213@qq.com");//插隊,如果沒有沒有樂觀鎖就會被下面的覆蓋userDao.updateById(user1);//由于上面更新操作后version+1,這里還是version.所以對比version值不一致,就不會對表中數據進行更新,這就是樂觀鎖userDao.updateById(user);}//測試查詢@Testpublic void selectUser(){//selectList的參數是一個Wrapper 條件構造器,不傳就填null//查詢全部用戶List<User> users = userDao.selectList(null);for (User user : users) {System.out.println(user);}}//根據ids查詢@Testpublic void selectUserByIds(){//selectList的參數是一個Wrapper 條件構造器,不傳就填null//查詢ids用戶List<User> users = userDao.selectBatchIds(Arrays.asList(1, 2, 3));for (User user : users) {System.out.println(user);}}//條件查詢使用map操作@Testpublic void selectUserByMap(){HashMap<String, Object> map = new HashMap<>();map.put("name","小強");userDao.selectByMap(map).forEach(System.out::println);}//分頁查詢//配置攔截器@Testpublic void findPage(){//分頁查詢需要這個類,我們就new出來,傳遞當前頁與每頁條數Page<User> userPage = new Page<>(2,5);//Wrapper 沒有就給nullPage<User> users = userDao.selectPage(userPage, null);List<User> records = users.getRecords();records.forEach(System.out::println);long total = users.getTotal();System.out.println("總數:"+total);}//刪除@Testpublic void deleteUser(){int i = userDao.deleteById(1);System.out.println(i); // userDao.deleteBatchIds(Arrays.asList(2,3,4));//批量id刪除 // userDao.deleteByMap(new HashMap<>());//根據條件刪除}//邏輯刪除@Testpublic void deleteUser02(){/*物理刪除:從數據庫中直接刪除,持久化邏輯刪除:在數據庫中沒有被移除,而是通過一個變量來讓他失效!delete = 1//使用場景:管理員查詢被刪除的記錄!,防止數據的丟失,類似于回收站//在數據表中增加delete字段*///配置邏輯刪除后,執行的sql語句是更新操作,將delete的字段值為1,就實現了邏輯刪除,查詢的時候會自動拼接delete = 0//查詢語句自動添加delete SELECT id,name,age,email,creat_time,update_time,`version`,`delete` FROM user WHERE `delete`=0userDao.deleteById(2);} }以查詢所有為列子
說明我們不需要寫任何sql.crud的sql,MyBatis-puls都幫我們自動生成,而且執行.
總結
以上是生活随笔為你收集整理的浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Freemarker来页面静态化,与
- 下一篇: Dockerfile文件创建centos