MybatisPlus不好用,帅小伙一气之下写了个MybatisPlusPro

简介: 富贵同学在用MybatisPlus作为开发的时候,虽然好用,但是大多数都在对dao层面的增删改查,所以打算自己抽取一套在controller层的功能出来,先介绍一下,“MybatisPlusPro” :只要继承一个BaseController类,就可以拥有增删改查,查询列表,分页查询,排序,带参数查询,统计数量。话不多说,直接开始吧!

富贵同学在用MybatisPlus作为开发的时候,虽然好用,但是大多数都在对dao层面的增删改查,所以打算自己抽取一套在controller层的功能出来,先介绍一下,“MybatisPlusPro” :只要继承一个BaseController类,就可以拥有增删改查,查询列表,分页查询,排序,带参数查询,统计数量。话不多说,直接开始吧!

第一步,引入MybatisPlus的jar包

java复制代码      <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

第二步,编写util类

java复制代码import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * Apprentice系统Util
 *
 * @author MaSiyi
 * @version 1.0.0 2021/11/26
 * @since JDK 1.8.0
 */
public class ApprenticeUtil {
    private static Pattern humpPattern = Pattern.compile("[A-Z]");
    private static Pattern linePattern = Pattern.compile("_(\\w)");
    /**
     * 驼峰转下划线
     *
     * @Param: [str]
     * @return: java.lang.String
     * @Author: MaSiyi
     * @Date: 2021/11/26
     */
    public static String humpToLine(String str) {
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
    /**
     * 下划线转驼峰
     *
     * @Param: [str]
     * @return: java.lang.String
     * @Author: MaSiyi
     * @Date: 2021/11/26
     */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
    /**
     * 获取QueryWrapper
     *
     * @Param: [entity]
     * @return: com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<E>
     * @Author: MaSiyi
     * @Date: 2021/11/26
     */
    public static <E> QueryWrapper<E> getQueryWrapper(E entity) {
        Field[] fields = entity.getClass().getDeclaredFields();
        QueryWrapper<E> eQueryWrapper = new QueryWrapper<>();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            //忽略final字段
            if (Modifier.isFinal(field.getModifiers())) {
                continue;
            }
            field.setAccessible(true);
            try {
                Object obj = field.get(entity);
                if (!ObjectUtils.isEmpty(obj)) {
                    String name = ApprenticeUtil.humpToLine(field.getName());
                    eQueryWrapper.eq(name, obj);
                }
            } catch (IllegalAccessException e) {
                return null;
            }
        }
        return eQueryWrapper;
    }
    /** 反射获取字段值
     * @Param: [entity, value] value 值为 "id" "name" 等
     * @return: java.lang.Object
     * @Author: MaSiyi
     * @Date: 2021/11/26
     */
    public static <E> Object getValueForClass(E entity,String value) {
        Field id = null;
        PropertyDescriptor pd = null;
        try {
            id = entity.getClass().getDeclaredField(value);
            pd = new PropertyDescriptor(id.getName(), entity.getClass());
        } catch (NoSuchFieldException | IntrospectionException e) {
            e.printStackTrace();
        }
        //获取get方法
        Method getMethod = Objects.requireNonNull(pd).getReadMethod();
        return ReflectionUtils.invokeMethod(getMethod, entity);
    }
}

反射获取字段值,这段Java代码演示了如何使用反射获得指定对象的属性值。方法的泛型表示,可以接受任意类型的参数entity。在此代码中,首先通过反射获取参数entity对象所对应类的属性,即value。

接着通过Java内置的Introspector机制获取id属性的JavaBean规范访问器PropertyDescriptor,并从该对象提取出对应的getter方法。最后,利用Spring框架提供的工具类ReflectionUtils得到方法后来调用该getter方法,获取属性值并返回。需要注意,在反射机制下如果要访问私有成员变量或方法时,应先调用其setAccessible(true)方法以获得权限。

第三步,我们编写BaseController类

下面是我们的BaseController类

java复制代码
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wangfugui.apprentice.common.util.ApprenticeUtil;
import com.wangfugui.apprentice.common.util.ResponseUtils;
import com.wangfugui.apprentice.dao.dto.PageParamDto;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/** 核心公共controller类
 * @Param:
 * @return:
 * @Author: MaSiyi
 * @Date: 2021/11/26
 */
public class BaseController<S extends IService<E>, E> {
    @Autowired
    protected S baseService;
    @ApiOperation("增")
    @PostMapping("/insert")
    public ResponseUtils insert(@RequestBody E entity) {
        baseService.save(entity);
        return ResponseUtils.success("添加成功");
    }
    @ApiOperation("删")
    @PostMapping("/deleteById")
    public ResponseUtils delete(@RequestBody List<Integer> ids) {
        baseService.removeByIds(ids);
        return ResponseUtils.success("添加成功");
    }
    @ApiOperation("改")
    @PostMapping("/updateById")
    public ResponseUtils updateById(@RequestBody E entity) {
        baseService.updateById(entity);
        return ResponseUtils.success("添加成功");
    }
    @ApiOperation("查")
    @GetMapping("/getById")
    public ResponseUtils getById(@RequestParam Integer id) {
        return ResponseUtils.success(baseService.getById(id));
    }
    @ApiOperation("存")
    @PostMapping("/save")
    public ResponseUtils save(@RequestBody E entity) {
        baseService.saveOrUpdate(entity);
        return ResponseUtils.success("添加成功");
    }
    @ApiOperation("list查")
    @PostMapping("/list")
    public ResponseUtils list(@RequestBody E entity) {
        QueryWrapper<E> queryWrapper = ApprenticeUtil.getQueryWrapper(entity);
        List<E> list = baseService.list(queryWrapper);
        return ResponseUtils.success(list);
    }
    @ApiOperation("page查")
    @PostMapping("/page")
    public ResponseUtils page(@RequestBody PageParamDto<E> pageParamDto) {
        //限制条件
        if (pageParamDto.getPage() < 1) {
            pageParamDto.setPage(1);
        }
        if (pageParamDto.getSize() > 100) {
            pageParamDto.setSize(100);
        }
        Page<E> page = new Page<>(pageParamDto.getPage(), pageParamDto.getSize());
        QueryWrapper<E> queryWrapper = new QueryWrapper<>();
        //升序
        String asc = pageParamDto.getAsc();
        if (!StrUtil.isEmpty(asc) && !"null".equals(asc)) {
            String[] split = asc.split(",");
            queryWrapper.orderByAsc(split);
        }
        //降序
        String desc = pageParamDto.getDesc();
        if (!StrUtil.isEmpty(desc) && !"null".equals(desc)) {
            String[] split = desc.split(",");
            queryWrapper.orderByDesc(split);
        }
        Page<E> ePage = baseService.page(page, queryWrapper);
        return ResponseUtils.success(ePage);
    }
    @ApiOperation("获取数量")
    @PostMapping("/count")
    public ResponseUtils count(@RequestBody E entity) {
        QueryWrapper<E> queryWrapper = ApprenticeUtil.getQueryWrapper(entity);
        long count = baseService.count(queryWrapper);
        return ResponseUtils.success(count);
    }
}

这段Java代码展示了一个基本的基于Spring Boot框架开发的RESTful API接口实现。BaseController是一个较为通用的Controller基类,通过泛型使其可以处理各种实体类型对应的请求(比如增、删、改、查等)。

具体来说,该类中包含了五个基本HTTP操作(POST, GET),通过不同参数和请求方式对实体对象进行CRUD操作,即添加(insert)、删除(delete)、修改(update)、查询(getById)、存储(save)、列表查询(list)、分页查询(page)、统计数量(count)。同时,通过Spring Boot自带的Web开发框架中的注解,将每个方法暴露为一个Restful API。

需要注意的是,该控制器只是一个模板,实际使用时需要继承该控制器并传入相应的Service类作为泛型S的参数,并实现具体的CRUD方法。

第四步,由于mybatisplus默认是不支持分页的,我们需要配置一下使他支持

java复制代码import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
    /** 设置分页插件
     * @Param: []
     * @return: com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
     * @Author: MaSiyi
     * @Date: 2021/11/26
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

第五步,我们在自己的controller类中继承BaseController类

java复制代码import com.wangfugui.apprentice.dao.domain.Dynamic;
import com.wangfugui.apprentice.service.IDynamicService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 动态表 前端控制器
 * </p>
 *
 * @author MrFugui
 * @since 2021-11-23
 */
@RestController
@RequestMapping("/apprentice/dynamic")
@Api("动态管理")
public class DynamicController extends BaseController<IDynamicService, Dynamic>{
}

这样就可以有默认的增删改查了

java复制代码
import com.wangfugui.apprentice.dao.domain.Blog;
import com.wangfugui.apprentice.service.IBlogService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 博客表 前端控制器
 * </p>
 *
 * @author MrFugui
 * @since 2021-11-25
 */
@RestController
@RequestMapping("/apprentice/blog")
@Api(tags = "博客管理")
public class BlogController extends BaseController<IBlogService, Blog>{
}

这样就能使用啦!

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

相关文章
|
移动开发 前端开发 JavaScript
童年回忆——开心消消乐(内含源码inscode一键运行)
童年回忆——开心消消乐(内含源码inscode一键运行)
|
Java Nacos 数据库
Nacos常见问题之页面删除失败如何解决
Nacos是一款易于使用的动态服务发现、配置管理和服务管理平台,针对不同版本可能出现的兼容性和功能问题,本汇总贴心整理了用户在使用Nacos时可能遇到的版本相关问题及答案,以便用户能够更顺畅地进行服务治理和配置管理。
330 0
|
7月前
|
运维 监控 数据可视化
斩获6.1 star,再见Crontab!这款开源定时任务管理系统让运维更高效
Gocron是一款基于Go语言的轻量级定时任务调度系统,替代传统Linux Crontab。它提供可视化Web界面管理,支持秒级调度、任务依赖配置与多节点执行。核心功能包括:1) 可视化管理;2) 精确调度规则;3) 全链路任务控制;4) 多类型任务支持;5) 完善监控通知。适用于自动化运维、系统监控、数据处理及业务自动化等场景。通过三步快速上手:一键部署、添加任务节点、创建定时任务。相比Crontab和Celery,Gocron更直观高效,适合个人与企业使用。项目地址:https://github.com/ouqiang/gocron。
1227 8
|
SQL Java Kotlin
MybatisPlus怎么拓展自定义BaseMapper
通过扩展Mybatis-Plus的`BaseMapper`,可以自定义SQL模板以满足特定业务需求。例如,当遇到唯一键冲突而不希望抛出异常时,可使用`INSERT IGNORE`语法。首先,创建`InsertIgnore`类继承`AbstractMethod`并定义`insertIgnore`方法及其SQL模板。接着,在自定义的`UltraBaseMapper`接口中声明`insertIgnore`方法,并让业务Mapper继承此接口。最后,通过`UltraSqlInjector`类将`InsertIgnore`方法注册到Mybatis-Plus插件中。
674 1
|
9月前
|
Java API 微服务
微服务——SpringBoot使用归纳——Spring Boot中的切面AOP处理——Spring Boot 中的 AOP 处理
本文详细讲解了Spring Boot中的AOP(面向切面编程)处理方法。首先介绍如何引入AOP依赖,通过添加`spring-boot-starter-aop`实现。接着阐述了如何定义和实现AOP切面,包括常用注解如`@Aspect`、`@Pointcut`、`@Before`、`@After`、`@AfterReturning`和`@AfterThrowing`的使用场景与示例代码。通过这些注解,可以分别在方法执行前、后、返回时或抛出异常时插入自定义逻辑,从而实现功能增强或日志记录等操作。最后总结了AOP在实际项目中的重要作用,并提供了课程源码下载链接供进一步学习。
1145 0
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
1551 1
SpringBoot入门(7)- 配置热部署devtools工具
|
Java API 数据安全/隐私保护
在Spring Boot中,过滤器(Filter)是一种非常有用的组件
在Spring Boot中,过滤器(Filter)是一种非常有用的组件
552 6
|
消息中间件 监控 Kafka
实时计算 Flink版产品使用问题之处理Kafka数据顺序时,怎么确保事件的顺序性
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
Python
图文并茂:Python Tkinter从入门到高级实战全解析
图文并茂:Python Tkinter从入门到高级实战全解析
820 0
图文并茂:Python Tkinter从入门到高级实战全解析
|
JSON Java 数据格式
SpringBoot 实战:在 RequestBody 中优雅的使用枚举参数(原理篇)
在优雅的使用枚举参数(原理篇)中我们聊过,Spring对于不同的参数形式,会采用不同的处理类处理参数,这种形式,有些类似于策略模式。
978 0
SpringBoot 实战:在 RequestBody 中优雅的使用枚举参数(原理篇)