前面已經介紹了Mybatis-plus基本用法,今天為大家分享一些Mybatis-plus高級應用
邏輯刪除 自動注入 枚舉類型處理 Sql注入器 多租戶 表結構
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='角色';
邏輯刪除 全局配置 在配置文件中增加如下配置
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");}
從結果可以看出角色id為1數據的is_del被設置為1
使用Mybatis-plus自帶方法刪除、更新和查找都會where條件后面加上刪除字段
以查詢為例看一下效果
@Test void loginDel2() { ? ?roleMapper.selectList(null);}
從打印的sql中可以看出,在where后面添加了is_del='0'限定,所以要查詢所有數據可以采用自定義sql實現
自動填充 在項目開發中,表中經常會定義一些公共的字段,例如:修改人,創建人。這時候我們可以采用 MyBatis-Plus 中
的字段自動填充功能去實現。
在實體類屬性上增加@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:插入和更新時填充字段 定義處理器 @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()); ? ? ? } ? }}?
測試 @Testvoid update() { // 更新id為2角色的名字為測試2 Role role = new Role(); role.setName("測試2"); role.setId("2"); roleMapper.updateById(role);}
在執行更新操作時自動加上更新人和更新時間
枚舉類型處理器 自mybatis3.1.0開始,如果你無需使用原生枚舉,可配置默認枚舉來省略掃描通用枚舉配置 默認枚舉配置
定義枚舉類,主要有兩種方式 方法一:采用繼承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;}
定義實體類 @Data@TableName("sys_role")public class Role { /** 角色類型 */ private RoleType type;}
配置掃描的枚舉包路徑 mybatis-plus: typeEnumsPackage: com.yanyu.spring.mybatisplus.enums
從結果可以看出查詢出的角色類型自動轉換成了枚舉ADMIN
Sql注入 當Mybatis-plus自帶的原生方法不能滿足我們的需求,我們可以利用sql注入器自定義sql
實現步驟:
創建自定義的類 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); }}
創建注入器 @Componentpublic class MySqlInject extends DefaultSqlInjector { @Override public List getMethodList(Class> mapperClass) { List methodList = super.getMethodList(mapperClass); methodList.add(new DeleteByCodeMethod()); return methodList; }}
在Mapper中加入自定義方法 public interface RoleMapper extends BaseMapper { int deleteByCode(@Param("code") String code);}
測試 @Testvoid deleteByCode() { // 刪除編碼為code的角色 roleMapper.deleteByCode("test");}
從結果看,我們自定義的根據編碼刪除數據執行成功
Mybatis-plus官方為我們提供了三種自定義類
InsertBatchSomeColumn:批量新增數據,自選字段insert AlwaysUpdateSomeColumnById:根據id更新固定字段 LogicDeleteByIdWithFill:根據id邏輯刪除,并帶字段填充功能 以InsertBatchSomeColumn為例,簡單的演示一下怎么使用
在注入器中加入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; }}
在Mapper中加入自定義方法 public interface RoleMapper extends BaseMapper { int insertBatchSomeColumn(List list);}
測試 @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);}
多租戶 租戶實現 Mybatis-plus多租戶依賴于分頁插件,下面我們將簡單介紹如何實現租戶解析
定義租戶解析器 @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;}
測試 @Testpublic void tenant() { // 查詢id為1的角色 roleMapper.selectById("1");}
從結果看,sql執行時在查詢條件中自動為我們加上了租戶判斷
特定sql過濾 在開發中有的方法不需要限定租戶標識,實現方式有兩種
方式一:通過在分頁插件中自定義過濾器,具體實現如下所示 @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;}
方式二:在不需要限定租戶的方法上加入 public interface RoleMapper extends BaseMapper { @SqlParser(filter = true) int getByCode(String code);}
如果有哪里寫得不對的,還請各位小友指正,只有不斷試錯,才能慢慢提高。如果你覺得對你有幫助,請點贊+關注,謝謝!!!!!!
總結
以上是生活随笔 為你收集整理的枚举类型用法_Mybatis-plus常见用法总结三 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。