温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Spring Boot + Mybatis-Plus的集成与使用方法

发布时间:2021-10-20 17:32:38 来源:亿速云 阅读:303 作者:柒染 栏目:大数据

这期内容当中小编将会给大家带来有关Spring Boot + Mybatis-Plus的集成与使用方法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

一、自动注入SQL原理 

通过上一章节,我们可以很方便的使用继承了BaseMapper接口的SysLogMapper进行CRUD操作。下面我们先来看下传统MaBatis的特点:

Spring Boot + Mybatis-Plus的集成与使用方法

MyBatis-Plus官方介绍MyBatis-Plus是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变。只为简化开发、提高效率。学习到这里,更直观的使用体验如下:

  • 基于MyBatis

    1. 需要编写XXMapper接口,并手动编写CRUD方法

    2. XXMapper.xml映射文件,并手动编写每个方法对应的SQL语句

  • 基于MyBatis-Plus

    1. 只需要创建XXMapper接口并继承BaseMapper接口,即可完成所有通用CRUD操作

    2. 可以无需创建SQL映射文件

只要继承BaseMapper,就可完成所有通用CRUD操作。那么我们就来了解下BaseMapper接口。查看BaseMapper源码,可以看到接口里定义了各种CRUD操作的17种方法,可以极其方便的实现单一、批量、分页等操作。

Spring Boot + Mybatis-Plus的集成与使用方法

这里看到CRUD方法都在这里定义好了,那么最终执行操作数据库的SQL语句是在哪编写的呢。带着这个疑惑,我先从使用源头SysLogMapper接口开始分析。这接口只继承了BaseMapper接口的定义的所有方法。

那这些方法又是如何实现的呢。

这里我们先要知道动态代理的这个概念。在Spring中动态代理实现有两种:一种基于JDK使用接口代理,另一种是基于cglib的使用类继承方式动态代理。有关动态代理原理这里不作深入讲解,有兴趣的同伴可以查阅资料了解,后续我们也会单独对这块进行讲解学习。

我们选择debug模式,打个断点执行查询操作。

Spring Boot + Mybatis-Plus的集成与使用方法

可以看到sysLogMpper被动态代理后,在对象结构里可以看selSessionFactory对象以及对象里的configuration对象。configuration对象就是MyBatis-Plus全局配置对象,包含所有配置信息。configuration对象中有mappedStatements属性,这里就是sysLogMpper接口方法的SQL语句映射,mappedStatements是一个HashMapkey为方法名,value对应一个个MappedStatement对象。

Spring Boot + Mybatis-Plus的集成与使用方法

我们点开一个键值对看下,在MappedStatement对象里有DynamicSqlSource类对象sqlSource,在对象中就编写了CRUD操作方法的动态SQL语句。

Spring Boot + Mybatis-Plus的集成与使用方法

那么这些动态的SQL是如何放进MappedStatement对象中的呢。在官网文档中提到了SQL注入器,默认为DefaultSqlInjector。我们打开这个类看下

public class DefaultSqlInjector extends AbstractSqlInjector {
    public DefaultSqlInjector() {
    }
 
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        return (List)Stream.of(new Insert(), new Delete(), new DeleteByMap(), new DeleteById(), new DeleteBatchByIds(), new Update(), new UpdateById(), new SelectById(), new SelectBatchByIds(), new SelectByMap(), new SelectOne(), new SelectCount(), new SelectMaps(), new SelectMapsPage(), new SelectObjs(), new SelectList(), new SelectPage()).collect(Collectors.toList());
    }
}

这个类继承AbstractSqlInjector,重写了getMethodList方法,返回一个集合。集合里是实例化后的CRUD执行的方法类对象。我们打开Insert类看下,这个类继承自AbstractMethod类,重写了injectMappedStatement方法。

public class Insert extends AbstractMethod {
    public Insert() {
    }
 
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        KeyGenerator keyGenerator = new NoKeyGenerator();
        SqlMethod sqlMethod = SqlMethod.INSERT_ONE;
        String columnScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlColumnMaybeIf(), "(", ")", (String)null, ",");
        String valuesScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlPropertyMaybeIf((String)null), "(", ")", (String)null, ",");
        String keyProperty = null;
        String keyColumn = null;
        if (StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
            if (tableInfo.getIdType() == IdType.AUTO) {
                keyGenerator = new Jdbc3KeyGenerator();
                keyProperty = tableInfo.getKeyProperty();
                keyColumn = tableInfo.getKeyColumn();
            } else if (null != tableInfo.getKeySequence()) {
                keyGenerator = TableInfoHelper.genKeyGenerator(tableInfo, this.builderAssistant, sqlMethod.getMethod(), this.languageDriver);
                keyProperty = tableInfo.getKeyProperty();
                keyColumn = tableInfo.getKeyColumn();
            }
        }
        //格式SQL语句
        String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);
        SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
        return this.addInsertMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource, (KeyGenerator)keyGenerator, keyProperty, keyColumn);
    }
}

injectMappedStatement方法里,可以看传了三个参数mapperClass、 modelClass、 tableInfo,分别为要操作的mapper接口对象、实体类对象、以及实体映射的表信息对象。在方法里将这里信息按insert操作格式化出sql字符串,最后一行调用继承的addInsertMappedStatement方法将以上这对象信息进行封装,最终返回MappedStatement对象。

以上就是我们对MyBatis-Plus自动注入SQL原理进行简单的分析,有兴趣的同学可以再深入研究,欢迎留言与我们一起探讨。

二、 条件构造器

在前面介绍BaseMapper接口中定义的方法中,我们发现有方法参数中传了Wrapper对象。这就是我们接下来要讲解的条件构造器。在开始讲解如何使用条件构造器前,先了解下什么是条件构造器,磨刀不误砍柴工!

Spring Boot + Mybatis-Plus的集成与使用方法

从上面图解中可以清楚看到各接口、抽象类与实现类间的实现与继承关系。之所以给出上面图解,是因为接下来将要重点讲解使用QueryWrapperLambdaQueryWrapperUpdateWrapperLambdaUpdateWrapper四个查询与更新包装器,主要用于处理 sql 拼接,排序,实体参数进行分页查询与更新,简单便捷,没有额外的负担,能够有效的提高开发效率。

可以看到对象查询,这里字义了两个类,QueryWrapperLambdaQueryWrapper。两个类的区别是QueryWrapper中条件参数使用的是数据库字段,不是Java属性。LambdaQueryWrapper看类名就知道是支持使用JDK8新特性,使用方法引用来进行查询

通用的条件参数有以下这些:

查询方式说明
setSqlSelect设置 SELECT 查询字段
whereWHERE 语句,拼接 + WHERE 条件
andAND 语句,拼接 + AND 字段=值
andNewAND 语句,拼接 + AND (字段=值)
orOR 语句,拼接 + OR 字段=值
orNewOR 语句,拼接 + OR (字段=值)
eq等于=
allEq基于 map 内容等于=
ne不等于<>
gt大于>
ge大于等于>=
lt小于<
le小于等于<=
like模糊查询 LIKE
notLike模糊查询 NOT LIKE
inIN 查询
notInNOT IN 查询
isNullNULL 值查询
isNotNullIS NOT NULL
groupBy分组 GROUP BY
havingHAVING 关键词
orderBy排序 ORDER BY
orderAscASC 排序 ORDER BY
orderDescDESC 排序 ORDER BY
existsEXISTS 条件语句
notExistsNOT EXISTS 条件语句
betweenBETWEEN 条件语句
notBetweenNOT BETWEEN 条件语句
addFilter自由拼接 SQL
last拼接在最后,例如:last("LIMIT 1")

三 、小结

MyBatis-Plus自动注入SQL原理以及简单了解什么是条件构造器。一起学习的同伴们应该对MyBatis-Plus的条件构造器使用已经跃跃欲试了。

上述就是小编为大家分享的Spring Boot + Mybatis-Plus的集成与使用方法了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI