1.背景
mybatis-plus除了常規的一些CRUD還有其他的的功能如下
2.邏輯刪除
2.1.實現配置
步驟一、數據庫准備一個邏輯刪除字段,一般是deleted
步驟二、配置文件中添加入下配置
步驟三、java實體上加標簽如下:
2.2.實際案例演示

package com.ldp.demo01; import com.ldp.entity.SysUser; import com.ldp.mapper.SysUserMapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * @author 姿勢帝-博客園 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 12/14 7:13 * @description <p> * 邏輯刪除測試 * </p> */ @RunWith(SpringRunner.class) @SpringBootTest public class Test11LogicDeleted { @Autowired private SysUserMapper sysUserMapper; /** * 邏輯刪除測試 * <p> * ==> Preparing: UPDATE sys_user SET deleted=1 WHERE id=? AND deleted=0 * ==> Parameters: 26(Integer) * <== Updates: 1 * <p> * 注意觀察:雖然我執行的是刪除,但是因為配置了邏輯刪除,使用最后執行的本質sql是更新, * 而且在更新的sql語句中還加入了deleted=0這個條件 * 那么試想一想,如果是查詢、修改會加入deleted=0這個條件么? */ @Test public void test01() { int row = sysUserMapper.deleteById(25); System.out.println("受影響行數:" + row); } /** * 測試邏輯刪除下的查詢 * <p> * ==> Preparing: SELECT id,version,age,gender,name,parent_id,position,account,we_chat,password,status,type,create_time,update_time,deleted * FROM sys_user WHERE id=? AND deleted=0 * ==> Parameters: 25(Integer) * <p> * 注意邏輯刪除下的查詢是加了 AND deleted=0 作為查條件的 */ @Test public void test02() { SysUser sysUser = sysUserMapper.selectById(25); System.out.println("sysUser=" + sysUser); } /** * 邏輯刪除下的更新 * <p> * ==> Preparing: UPDATE sys_user SET name=? WHERE id=? AND deleted=0 * ==> Parameters: 邏輯刪除測試(String), 25(Integer) * <p> * 注意從sql語句上看也是添加了deleted=0的 */ @Test public void test03() { int row = sysUserMapper.updateById(new SysUser().setId(25).setName("邏輯刪除測試")); System.out.println("受影響行數=" + row); } /** * 邏輯刪除下的新增 * ==> Preparing: INSERT INTO sys_user ( age, name ) VALUES ( ?, ? ) * ==> Parameters: 18(Integer), 新增測試(String) * <== Updates: 1 * 注意從sql語句來看,在添加的時候並沒有幫我們自動添加deleted=0字段的值, * 所有在實際生產中最佳的作法是在數據庫設置默認值為0 */ @Test public void test04() { int row = sysUserMapper.insert(new SysUser().setName("新增測試").setAge(18)); System.out.println("受影響行數=" + row); } }
3.自動填充
第一步:注解填充字段 @TableField(.. fill = FieldFill.INSERT)
生成器策略部分也可以配置!
/** * 表示創建時自動填充 */ @TableField(value = "create_time",fill = FieldFill.INSERT) private Date createTime; /** * 表示更新時自動填充 */ @TableField(fill = FieldFill.UPDATE) private Date updateTime;
第二步:自定義實現類 MyMetaObjectHandler

package com.ldp.config; 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; /** * @author 姿勢帝-博客園 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 12/14 8:03 * @description */ @Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill ...."); this.strictInsertFill(metaObject, "createTime", () -> new Date(), Date.class); // 起始版本 3.3.3(推薦) } @Override public void updateFill(MetaObject metaObject) { log.info("start update fill ...."); this.strictUpdateFill(metaObject, "updateTime", () -> new Date(), Date.class); // 起始版本 3.3.3(推薦) } }
第三步:測試

package com.ldp.demo01; import com.ldp.entity.SysUser; import com.ldp.mapper.SysUserMapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * @author 姿勢帝-博客園 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 12/14 8:10 * @description <p> * 自動填充 * </p> */ @RunWith(SpringRunner.class) @SpringBootTest public class Test12FieldFill { @Autowired private SysUserMapper sysUserMapper; /** * 新增時自動填充 * <p> * ==> Preparing: INSERT INTO sys_user ( age, name, create_time ) VALUES ( ?, ?, ? ) * ==> Parameters: 18(Integer), 自動填充(String), 2020-12-14 19:55:36.065(Timestamp) * <== Updates: 1 */ @Test public void test01() { int row = sysUserMapper.insert(new SysUser().setName("自動填充").setAge(18)); System.out.println("受影響行數=" + row); } /** * 更新時自動填充 * <p> * ==> Preparing: UPDATE sys_user SET name=?, update_time=? WHERE id=? AND deleted=0 * ==> Parameters: 更新自動填充(String), 2020-12-14 19:56:16.539(Timestamp), 25(Integer) * <== Updates: 1 */ @Test public void test02() { int row = sysUserMapper.updateById(new SysUser().setId(25).setName("更新自動填充")); System.out.println("受影響行數=" + row); } }
4.樂觀鎖
實現原理:
取出記錄時,獲取當前version 更新時,帶上這個version 執行更新時, set version = newVersion where version = oldVersion 如果version不對,就更新失敗
具體實現
第一步:數據庫和java實體添加字段version,並在實體上添加注解@Version
/** * 樂觀鎖 */ @Version private Integer version;
第二步:注冊樂觀鎖插件

package com.ldp.config; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @author 姿勢帝-博客園 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 12/06 4:45 * @description */ @Configuration public class MybatisPlusConfig { /** * 樂觀鎖配置 * * @return */ @Bean public MybatisPlusInterceptor optimisticLockerInnerInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); // 設置請求的頁面大於最大頁后操作, true調回到首頁,false 繼續請求 默認false // paginationInterceptor.setOverflow(false); // 設置最大單頁限制數量,默認 500 條,-1 不受限制 // paginationInterceptor.setLimit(500); // 開啟 count 的 join 優化,只針對部分 left join paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); return paginationInterceptor; } }
第三步:測試

package com.ldp.demo01; import com.ldp.entity.SysUser; import com.ldp.mapper.SysUserMapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * @author 姿勢帝-博客園 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 12/14 9:40 * @description */ @RunWith(SpringRunner.class) @SpringBootTest public class Test13Version { @Autowired private SysUserMapper sysUserMapper; /** * 樂觀鎖測試 * ==> Preparing: UPDATE sys_user SET version=?, name=?, update_time=? WHERE id=? AND version=? AND deleted=0 * ==> Parameters: 8(Integer), 樂觀鎖測試(String), 2020-12-14 22:04:15.04(Timestamp), 12(Integer), 7(Integer) * <== Updates: 1 * 注意觀察sql,查詢出來的version=7,在更新的時候將session版本設置為8 */ @Test public void test01() { SysUser sysUser = sysUserMapper.selectById(12); int row = sysUserMapper.updateById( new SysUser() .setId(sysUser.getId()) .setName("樂觀鎖測試") .setVersion(sysUser.getVersion()) ); System.out.println("受影響行數=" + row); } }