枚举类型用法_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.mzph.cn/news/453050.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VS Code的golang开发配置 之 代码提示

之前用VS Code的时候&#xff0c;发现自己的代码的提示一直不好&#xff0c;换用JetBrain的Goland的代码提示是好了&#xff0c;但是比较占用资源。在网上找了一些资料&#xff0c;发现很多人也是遇到第三方或者自己的代码无法提示的情况&#xff0c;但是都没有下文了。后来发现…

数组复制

在Java里面,可以用复制语句”AB”给基本类型的数据传递值,但是如果A,B是两个同类型的数组&#xff0c;复制就相当于将一个数组变量的引用传递给另一个数组&#xff1b;如果一个数组发生改变&#xff0c;那么引用同一数组的变量也要发生改变。 1.使用FOR循环,将数组的每个元素复…

服务器性能估算参考(硬件-应用服务器)

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 …

下拉选择_在管理Excel中实现联动下拉选择

在系统中常常出现这样的情况&#xff1a;由于下拉选择的数量太多了&#xff0c;难以高效选择。为此管理Excel通过通过引入多级联动选择的方式来减少下拉选择的困难度。先看下使用效果&#xff1a;联动下拉选择这个功能&#xff0c;在管理Excel中可以通过比较简单的配置方法实现…

JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

这里说的js跨域是指通过js在不同的域之间进行数据传输或通信&#xff0c;比如用ajax向一个不同的域请求数据&#xff0c;或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同&#xff0c;都被当作是不同的域。 下表给出了相对 http://store…

HelloWorld新手常见问题

1.显示错误&#xff1a; HelloWorld.java:1: 错误: 写入HelloWorld时出错: C:\HelloWorld.class public class HelloWorld { ^ 1 个错误 解决方法&#xff1a; 将文件转移至D盘&#xff0c;然后编译即可。不要放在C盘&#xff01; 2.显示错误&#xff1a; 错误: 找不…

浅谈HTTPS以及Fiddler抓取HTTPS协议

原文 浅谈HTTPS以及Fiddler抓取HTTPS协议 最近想尝试基于Fiddler的录制功能做一些接口的获取和处理工作&#xff0c;碰到的一个问题就是简单连接Fiddler只能抓取HTTP协议&#xff0c;关键的登录请求等HTTPS协议都没有捕捉到&#xff0c;所以想让Fiddler能够同时抓取到HTTPS和HT…

关于.c和.h 和定义变量的问题

最初调试的时候是因为有个错误在wavplay.h文件中 于是我跳到了recorderl.h中:从图中看到引用了main.h 出现这个问题的具体原因还是不太清楚: 不过我任务是因为: wavplay.h中定义了 __WaveHeader 变量 在main.h文件中引用了wavplay.h 而在wavplay.h中试图引用main.h里的 __Wa…

《软件调试分析技术》学习笔记

《软件调试分析技术》学习笔记&#xff08;一&#xff09; 今天开始写写一些心得体验。 《软件调试分析技术》是好友Monster的处女作品。作为一直以的好伙伴&#xff0c;他是我看着长大的&#xff0c;(*^__^*) 嘻嘻……之所以有今天这样的成绩&#xff0c;是与他的努力和天赋…

解决ubuntu首次安装Mysql之后,首次登录出现ERROR 1698 (28000): Access denied for user 'root'@'localhost'的方法

解决步骤&#xff1a; 1.打开终端&#xff0c;输入sudo vi /etc/mysql/debian.cnf 打开/etc/mysql/debian.cnf文件&#xff0c;显示如下&#xff1a; 2.mysql -udebian-sys-maint -p 打开mysql 输入密码为上图中password字段 3.修改root密码 ALTER USER rootlocalhost IDEN…

python获取window共享目录列表_利用Python获取DICOM RTstructure勾画列表

在《利用Python打开DICOM CT文件》一文中&#xff0c;我们利用pydicom.dcmread()读取了CT图像。本文中我们将修改load_scan()函数来读取RTstructure文件并获取勾画列表1. 打开Jupyter notebook&#xff0c;导入需要的科学包import numpy as npimport mathimport pydicomimport …

Ubuntu中安装、生成、导入、导出、Python3虚拟环境

1.安装Ubuntu虚拟环境、以及可以支持虚拟环境的模块 sudo apt install virtualenv sudo apt install virtualenvwrapper 安装完成之后&#xff0c;进入home目录&#xff0c;输入命令ls -al查看是否出现.virtualenvs目录&#xff0c;如果没有则手动创建.virtualenvs目录 重要…

如何拷贝工程_如何将premiere的工程及素材文件打包?

我们在剪辑视频的时候经常会遇到素材丢失的情况&#xff0c;或者说需要换地方或换电脑继续剪辑。特别是以前做的视频现在需要修改一些地方&#xff0c;然后打开工程文件会发现素材丢失&#xff0c;如图&#xff1a;这种情况要不就是素材已经删除&#xff0c;要不就是素材改变了…

c语言编写一个菜单系统_一招教你,轻松解决C语言编写一个正整数的所有因子!...

这个实例是一个能提高分析能力的实例&#xff0c;这个实例主要用到for语句&#xff0c;关键是如何确定其中变量的范围。求一个正整数的所有因子先来看看编程结果演示&#xff1a;编程演示输出结果编程如下:#include/*引用预处理命令&#xff0c;预处理包含stdio.h的头文件*/mai…

第四次Scrum编码冲刺!!!!

第四次Scrum编码冲刺&#xff01;&#xff01;&#xff01;&#xff01; 一、总体任务&#xff1a; 本次冲刺是完成对图书馆管理系统的最后三个功能的实现------管理员对用户授权、用户注销和用户查询 二、个人任务及完成情况&#xff1a; 本人本次的任务是实现对删除用户功能以…

Spring Cloud Edgware新特性之八:Zuul回退的改进

为什么80%的码农都做不了架构师&#xff1f;>>> Spring Cloud Edgware对Hystrix回退的逻辑进行了一些改进。本文将信息探讨新旧版本的回退操作&#xff0c;并分析的原因及改进后的优势。 Dalston及更低版本 对于Dalston及更低版本&#xff0c;要想为Zuul提供回退&a…

idea插件导出_Intellij IDEA 中我一直在用的几个插件

提前声明一下&#xff0c;今天这篇文章是在我家的那台 Mac 机子上写的&#xff0c;但是文中使用的快捷键还是主要针对于 Windows 平台「由于我的大多数读者在使用该系统&#xff0c;我是有多么爱你们&#xff5e;&#xff5e;&#xff5e;」。接上一篇《谈谈我与 Intellij IDEA…

Python基础学习五 内置模块

time 模块 1 >>> import time2 >>> time.time()3 1491064723.8086694 >>> # time.time()返回当前时间的时间戳timestamp(定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数)的方法,无参数5 >>> time.asctime()6 Sun Apr 2…