枚舉類型用法_Mybatis-plus常見用法總結三

前面已經介紹了Mybatis-plus基本用法,今天為大家分享一些Mybatis-plus高級應用

  1. 邏輯刪除
  2. 自動注入
  3. 枚舉類型處理
  4. Sql注入器
  5. 多租戶

表結構

CREATE TABLE `sys_role` (  `id` varchar(64) NOT NULL COMMENT '主鍵',  `code` varchar(64) NOT NULL DEFAULT '' COMMENT '角色編碼',  `name` varchar(64) NOT NULL DEFAULT '' COMMENT '角色名',  `type` char(2) NOT NULL COMMENT '角色類型,1:管理員,2:普通',  `tenant_code` varchar(64) NOT NULL DEFAULT '' COMMENT '租戶編碼',  `create_user` varchar(64) NOT NULL DEFAULT '' COMMENT '創建用戶',  `create_time` datetime NOT NULL COMMENT '創建時間',  `update_user` varchar(64) NOT NULL DEFAULT '' COMMENT '更新用戶',  `update_time` datetime NOT NULL COMMENT '更新時間',  `is_del` char(1) NOT NULL DEFAULT '0' COMMENT '是否刪除,0:未刪除,1:刪除',  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色';
4dc18fadcbec2857a83d82eb8df8b4de.png

邏輯刪除

全局配置

在配置文件中增加如下配置

mybatis-plus:  global-config: ?  db-config: ? ?  logic-delete-field: isDel#全局邏輯刪除字段值 3.3.0開始支持,詳情看下面。 ? ?  logic-delete-value: 1 # 邏輯已刪除值(默認為 1) ? ?  logic-not-delete-value: 0 # 邏輯未刪除值(默認為 0)

局部配置

在實體類刪除字段上增加@TableLogic注解

/** 是否刪除,0:未刪除,1:刪除 */@TableLogicprivate String isDel;

全局配置和局部配置實現的結果是一樣的,下面針對局部配置做一下測試

@Autowiredprivate RoleMapper roleMapper;@Testpublic void logicDel() { ? ?roleMapper.deleteById("1");}
a307bdf400178e435fd7319222a3bb17.png

從結果可以看出角色id為1數據的is_del被設置為1

使用Mybatis-plus自帶方法刪除、更新和查找都會where條件后面加上刪除字段

以查詢為例看一下效果

@Test void loginDel2() { ? ?roleMapper.selectList(null);}
6f4ce5bd8cd70a883c257256eeba8117.png

從打印的sql中可以看出,在where后面添加了is_del='0'限定,所以要查詢所有數據可以采用自定義sql實現

自動填充

在項目開發中,表中經常會定義一些公共的字段,例如:修改人,創建人。這時候我們可以采用 MyBatis-Plus 中

的字段自動填充功能去實現。

  1. 在實體類屬性上增加@TableField(fill = FieldFill.INSERT_UPDATE)注解,如下所示
@Data@TableName("sys_role")public class Role { ? ?/** 創建人 */ ? ?@TableField(fill = FieldFill.INSERT) ? ?private String createUser; ? ?/** 創建時間 */ ? ?@TableField(fill = FieldFill.INSERT) ? ?private Date createTime; ? ?/** 更新人 */ ? ?@TableField(fill = FieldFill.INSERT_UPDATE) ? ?private String updateUser; ? ?/** 更新時間 */ ? ?@TableField(fill = FieldFill.INSERT_UPDATE) ? ?private Date updateTime; ? ?/** 是否刪除,0:未刪除,1:刪除 */ ? ?@TableLogic ? ?private String isDel;}

TableField默認有四個

  • DEFAULT:默認不處理
  • INSERT:插入時填充字段
  • UPDATE:更新時填充字段
  • INSERT_UPDATE:插入和更新時填充字段
  1. 定義處理器
@Componentpublic class MyMetaObjectHandler implements MetaObjectHandler {? ? public static String CREATEUSER_NAMEINBEAN = "createUser"; ? ?public static String CREATETIME_NAMEINBEAN = "createTime"; ? ?public static String UPDATEUSER_NAMEINBEAN = "updateUser"; ? ?public static String UPDATETIME_NAMEINBEAN = "updateTime"; ? ?@Override ? ?public void insertFill(MetaObject metaObject) { ? ? ? ?boolean createUser = metaObject.hasSetter(CREATEUSER_NAMEINBEAN); ? ? ? ?if (createUser) { ? ? ? ? ? ?this.strictInsertFill(metaObject, CREATEUSER_NAMEINBEAN, String.class, "admin"); ? ? ?  } ? ? ? ?boolean createTime = metaObject.hasSetter(CREATETIME_NAMEINBEAN); ? ? ? ?if (createTime) { ? ? ? ? ? ?this.strictInsertFill(metaObject, CREATETIME_NAMEINBEAN, LocalDateTime.class, LocalDateTime.now()); ? ? ?  } ? ? ? ?boolean updateUser = metaObject.hasSetter(UPDATEUSER_NAMEINBEAN); ? ? ? ?if (updateUser) { ? ? ? ? ? ?this.strictInsertFill(metaObject, UPDATEUSER_NAMEINBEAN, String.class, "admin"); ? ? ?  } ? ? ? ?boolean updateTime = metaObject.hasSetter(UPDATETIME_NAMEINBEAN); ? ? ? ?if (updateTime) { ? ? ? ? ? ?this.strictInsertFill(metaObject, UPDATETIME_NAMEINBEAN, LocalDateTime.class, LocalDateTime.now()); ? ? ?  } ?  }? ? ?@Override ? ?public void updateFill(MetaObject metaObject) { ? ? ? ?boolean updateUser = metaObject.hasSetter(UPDATEUSER_NAMEINBEAN); ? ? ? ?if (updateUser) { ? ? ? ? ? ?this.strictInsertFill(metaObject, UPDATEUSER_NAMEINBEAN, String.class, "amdin"); ? ? ?  } ? ? ? ?boolean updateTime = metaObject.hasSetter(UPDATETIME_NAMEINBEAN); ? ? ? ?if (updateTime) { ? ? ? ? ? ?this.strictInsertFill(metaObject, UPDATETIME_NAMEINBEAN, LocalDateTime.class, LocalDateTime.now()); ? ? ?  } ?  }}?
  1. 測試
@Testvoid update() {    // 更新id為2角色的名字為測試2    Role role = new Role();    role.setName("測試2");    role.setId("2");    roleMapper.updateById(role);}
7e35c222404686dea8355b7b319eb3fa.png

在執行更新操作時自動加上更新人和更新時間

枚舉類型處理器

自mybatis3.1.0開始,如果你無需使用原生枚舉,可配置默認枚舉來省略掃描通用枚舉配置 默認枚舉配置

  1. 定義枚舉類,主要有兩種方式

方法一:采用繼承IEnum實現

@Getter@AllArgsConstructorpublic enum RoleType implements IEnum {    ADMIN("1"),    COMMON("2");    private String type;    @Override    public Serializable getValue() {        return type;    }}

方法二:注解方式,在枚舉類需要解析的屬性上增加@EnumValue注解

@Getter@AllArgsConstructorpublic enum RoleType {    ADMIN("1"),    COMMON("2"); @EnumValue//標記數據庫存的值是type    private String type;}
  1. 定義實體類
@Data@TableName("sys_role")public class Role { /** 角色類型 */    private RoleType type;}
  1. 配置掃描的枚舉包路徑
mybatis-plus:  typeEnumsPackage: com.yanyu.spring.mybatisplus.enums
c66f01806047679d4f804758a35679da.png

從結果可以看出查詢出的角色類型自動轉換成了枚舉ADMIN

Sql注入

當Mybatis-plus自帶的原生方法不能滿足我們的需求,我們可以利用sql注入器自定義sql

實現步驟:

  1. 創建自定義的類
public class DeleteByCodeMethod extends AbstractMethod {    @Override    public MappedStatement injectMappedStatement(Class> mapperClass, Class> modelClass, TableInfo tableInfo) {        // 執行的slq        String sql = "delete from "+ tableInfo.getTableName() +" where code = #{code}";        // Mapper接口方法名        String method = "deleteByCode";        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);        return addDeleteMappedStatement(mapperClass, method, sqlSource);    }}
  1. 創建注入器
@Componentpublic class MySqlInject extends DefaultSqlInjector {    @Override    public List getMethodList(Class> mapperClass) {        List methodList = super.getMethodList(mapperClass);        methodList.add(new DeleteByCodeMethod());        return methodList;    }}
  1. 在Mapper中加入自定義方法
public interface RoleMapper extends BaseMapper {    int deleteByCode(@Param("code") String code);}
  1. 測試
@Testvoid deleteByCode() {    // 刪除編碼為code的角色    roleMapper.deleteByCode("test");}
2b49cb1d205096eb3ba17445dcd0287f.png

從結果看,我們自定義的根據編碼刪除數據執行成功

Mybatis-plus官方為我們提供了三種自定義類

  • InsertBatchSomeColumn:批量新增數據,自選字段insert
  • AlwaysUpdateSomeColumnById:根據id更新固定字段
  • LogicDeleteByIdWithFill:根據id邏輯刪除,并帶字段填充功能

以InsertBatchSomeColumn為例,簡單的演示一下怎么使用

  1. 在注入器中加入InsertBatchSomeColumn自定義類
@Componentpublic class MySqlInject extends DefaultSqlInjector {    @Override    public List getMethodList(Class> mapperClass) {        List methodList = super.getMethodList(mapperClass);        methodList.add(new DeleteByCodeMethod());        /**         * 不是邏輯刪除的字段包括在內         */        methodList.add(new InsertBatchSomeColumn(t -> !t.isLogicDelete()));        return methodList;    }}
  1. 在Mapper中加入自定義方法
public interface RoleMapper extends BaseMapper {    int insertBatchSomeColumn(List list);}
  1. 測試
@Testvoid insertBatchSomeColumn() {    // 測試批量插入角色1和角色2    Role role1 = new Role();    role1.setCode("ROLE_1");    role1.setName("角色1");    role1.setType(RoleType.ADMIN);    Role role2 = new Role();    role2.setCode("ROLE_2");    role2.setName("角色2");    role2.setType(RoleType.ADMIN);    List roles = new ArrayList<>(Arrays.asList(role1,role2));    roleMapper.insertBatchSomeColumn(roles);}
6264a8f9a750365358fc48ff19c5c28a.png

多租戶

租戶實現

Mybatis-plus多租戶依賴于分頁插件,下面我們將簡單介紹如何實現租戶解析

  1. 定義租戶解析器
@Beanpublic PaginationInterceptor paginationInterceptor() throws IOException {    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();    TenantSqlParser tenantSqlParser = new TenantSqlParser();    tenantSqlParser.setTenantHandler(new TenantHandler() {        @Override        public Expression getTenantId(boolean select) {            return new StringValue("00000");        }        @Override        public String getTenantIdColumn() {            return "tenant_code";        }        @Override        public boolean doTableFilter(String tableName) {            /**             * 是否加租戶信息,false->加,true->不加             */            return false;        }    });    paginationInterceptor.setSqlParserList(Arrays.asList(tenantSqlParser));    return paginationInterceptor;}
  1. 測試
@Testpublic void tenant() {    // 查詢id為1的角色    roleMapper.selectById("1");}
fce7cb6c2d6e5ae4b1219c5ab53c1697.png

從結果看,sql執行時在查詢條件中自動為我們加上了租戶判斷

特定sql過濾

在開發中有的方法不需要限定租戶標識,實現方式有兩種

  1. 方式一:通過在分頁插件中自定義過濾器,具體實現如下所示
@Beanpublic PaginationInterceptor paginationInterceptor() throws IOException {    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();    TenantSqlParser tenantSqlParser = new TenantSqlParser();    tenantSqlParser.setTenantHandler(new TenantHandler() {        @Override        public Expression getTenantId(boolean select) {            return new StringValue("00000");        }        @Override        public String getTenantIdColumn() {            return "tenant_code";        }        @Override        public boolean doTableFilter(String tableName) {            /**             * 是否加租戶信息,false->加,true->不加             */            return false;        }    });    paginationInterceptor.setSqlParserList(Arrays.asList(tenantSqlParser));    paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {        /**         * true 不增加,false 增加         * @param metaObject         * @return         */        @Override        public boolean doFilter(MetaObject metaObject) {            MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);            if("具體方法".equals(ms.getId())) {                return true;            }            return false;        }    });    return paginationInterceptor;}
  1. 方式二:在不需要限定租戶的方法上加入
public interface RoleMapper extends BaseMapper {    @SqlParser(filter = true)    int getByCode(String code);}

如果有哪里寫得不對的,還請各位小友指正,只有不斷試錯,才能慢慢提高。如果你覺得對你有幫助,請點贊+關注,謝謝!!!!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453050.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453050.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453050.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

NOIP 2011 Day2

tags: 貪心模擬NOIP categories:信息學競賽總結計算系數 Solution 根據二項式定理,\[ \begin{align} (ab)^n\sum_{k0}^nC_{n}^{k}a^kb^{n-k} \end{align} \] 那么\[ \begin{align}(axby)^k&\sum_{p0}^kC_{k}^p(ax)^p(by)^{k-p}\\ &\sum_{p0}^k(C_{k}^pa^pb^{k-p})x^py^…

VS Code的golang開發配置 之 代碼提示

之前用VS Code的時候&#xff0c;發現自己的代碼的提示一直不好&#xff0c;換用JetBrain的Goland的代碼提示是好了&#xff0c;但是比較占用資源。在網上找了一些資料&#xff0c;發現很多人也是遇到第三方或者自己的代碼無法提示的情況&#xff0c;但是都沒有下文了。后來發現…

使用oprofile分析性能瓶頸

使用oprofile分析性能瓶頸 1. 概述oprofile 是 Linux 平臺上&#xff0c;類似 INTEL VTune 的一個功能強大的性能分析工具。其支持兩種采樣(sampling)方式&#xff1a;基于事件的采樣(event based)和基于時間的采樣(time based)。基于事件的采樣是oprofile只記錄特定事件&#…

什么是死鎖

死鎖是多個進程在運行過程中因競爭資源時產生的一種僵局。 各并發資源彼此等待對方擁有的資源&#xff0c;且在得到對方資源前不釋放自己的資源。

python數據工程師 面試題_阿里P7工程師耗時兩天整理的292道python大廠面試題,內含解析!...

前言相對于python大家應該都不會陌生吧&#xff01;現在java跟python可以算的是勢均力敵了&#xff0c;所以現在學習python 的小伙伴也是越來越多了&#xff0c;可是學完之后就能找到稱心如意的工作了嗎&#xff1f;很多小伙伴學習Python的時候感覺很簡單&#xff0c;但是到了去…

數組復制

在Java里面,可以用復制語句”AB”給基本類型的數據傳遞值,但是如果A,B是兩個同類型的數組&#xff0c;復制就相當于將一個數組變量的引用傳遞給另一個數組&#xff1b;如果一個數組發生改變&#xff0c;那么引用同一數組的變量也要發生改變。 1.使用FOR循環,將數組的每個元素復…

IntelliJ IDEA 對于generated source的處理

IntelliJ IDEA 對于generated source的處理 學習了&#xff1a;https://stackoverflow.com/questions/5170620/unable-to-use-intellij-with-a-generated-sources-folder 如果有generated source &#xff0c;例如使用gRPC過程中生成的&#xff0c;可以使用鼠標右鍵點擊使之成為…

產生死鎖的原因

一 競爭資源&#xff0c;但是資源的數目不能滿足進程的需要。 二 進程間推進順序非法&#xff0c;進程在運行過程中請求和釋放資源的順序不當。

fabric shim安裝合約_hyperledger fabric 開發第一個智能合約

一、編寫智能合約代碼HelloWorld.go&#xff0c;go語言實現&#xff0c;代碼很簡單&#xff0c;每個合約包含兩個方法&#xff0c;Init、Invoke。package mainimport ("fmt""github.com/hyperledger/fabric/core/chaincode/shim""github.com/hyperled…

不能干一輩子開發???

程序員的職業生涯之我見 總是聽到下面的論調 程序員干不了一輩子&#xff01; 程序員怎么也不能干一輩子吧&#xff01; 在中國程序員還能干一輩子&#xff1f; 過了&#xff08;30&#xff09;40我就干不動程序員了&#xff01; 每每聽…

分布式緩存的25個優秀實踐與線上案例 done

楊彪&#xff0c;螞蟻金服技術專家&#xff0c;《分布式服務架構&#xff1a;原理、設計與實戰》和《可伸縮服務架構&#xff1a;框架與中間件》作者。近10年互聯網和游戲行業工作經驗。本文節選自即將出版的《可伸縮服務架構&#xff1a;框架與中間件》一書&#xff0c;作者&a…

服務器性能估算參考(硬件-應用服務器)

2019獨角獸企業重金招聘Python工程師標準>>> Environment(2013-05-24) two identical machines via a GB-Ethernet link a client machine generating HTTP requests with wrk as the load generator a server machine running the respective “benchmarkee”all …

產生死鎖的四個必要條件

&#xff08;1&#xff09;互斥條件&#xff1a;進程對所分配到的資源不允許其他進程進行訪問&#xff0c;若其他進程訪問該資源&#xff0c;只能等待&#xff0c;直至占有該資源的進程使用完成后釋放該資源 &#xff08;2&#xff09;請求和保持條件&#xff1a;進程獲得一定的…

下拉選擇_在管理Excel中實現聯動下拉選擇

在系統中常常出現這樣的情況&#xff1a;由于下拉選擇的數量太多了&#xff0c;難以高效選擇。為此管理Excel通過通過引入多級聯動選擇的方式來減少下拉選擇的困難度。先看下使用效果&#xff1a;聯動下拉選擇這個功能&#xff0c;在管理Excel中可以通過比較簡單的配置方法實現…

圖片預覽

// 預覽圖片yulanFn: function (e) {var arr [];var that this;//獲取當前圖片的下表var indexw e.currentTarget.dataset.indexw;var index e.currentTarget.dataset.index;//數據源var pictures this.data.banner[indexw].shoppingCarouselList;var picture "http…

風雨20年:我所積累的20條編程經驗

原文作者喬納森丹尼可&#xff08;Jonathan Danylko&#xff09;是一位自由職業的web架構師和程序員&#xff0c;編程經驗已超過20年&#xff0c;涉足領域有電子商務、生物技術、房地產、醫療、保險和公用事業。正如喬納 森在文中所言&#xff0c;本文適合剛畢業的大學生和剛入…

JS跨域(ajax跨域、iframe跨域)解決方法及原理詳解(jsonp)

這里說的js跨域是指通過js在不同的域之間進行數據傳輸或通信&#xff0c;比如用ajax向一個不同的域請求數據&#xff0c;或者通過js獲取頁面中不同域的框架中(iframe)的數據。只要協議、域名、端口有任何一個不同&#xff0c;都被當作是不同的域。 下表給出了相對 http://store…

xenserver 安裝新硬盤_給Xenserver添加新硬盤

首先我們進入到xenserver的Console界面.然后按下enter進入命令模式,接下來.咱們先看看硬盤有沒有存在輸入fdisk -l出現如下提示:Disk /dev/sda: 500.1 GB, 500107862016 bytes255 heads, 63 sectors/track, 60801 cylindersUnits cylinders of 16065 * 512 8225280 bytesDevi…

go-study

package (包) 一個目錄下面所有的.go文件的包名必須相同. 包名一般和目錄名相同(是約定, 不是強制), 包名都小寫main包是一個特殊的包名, 在main包中, 必須包含func main()函數導入包(import)的時候, 使用的是包所在目錄的路徑, 路徑中不用包含包的名字, 在使用包的時候,直接用…