入坑mybatis-plus

前言

之前我写过一篇《mybatis分页插件pagehelper的基本使用方法》。当时主要是图简单,引入简单,使用简单,不用想那么多功能。不过最近,我对自己进行了深入的反思。觉得自己太过于纠结代码的细节了。其实,之前查过mybatis plus,但是由于学习成本有些高,封装的功能有点多,就不太像学它。另外,由于我对于实体的建立,增删改查的操作逻辑,各层对象的属性把控都提出了很高的要求,要求研发人员注意思考并实现。于是,就造成了像mybatis plus这种可以快速帮助我们进行增删改查的框架发挥不了多大作用。
但是,后来我进行了自我的深入反思。反观一年来团队的建设内容,说实话,少的可怜。而且,质量也不见得多高。为什么呢?因为,我无法和我自己合作,研发人员和我是两个个体,我无法对他们提出对我自己的要求,因为他们不知道我在想什么,我接下来想到了什么。另外,由于建设思考的多,速度就慢下来了,所以反馈循环走的少,自然质量高不起来,自己再怎么思考也是空想,需要结合实践的反馈才有现实意义。
而且,最近我 突然想通了。其实,大部分的操作就是快速的增删改查。因为,有了基础的数据,才能够进行更高层面的设计和建设。所谓设计能力,不是凭空设计和想象的能力,而是在变化和不确定中带着项目一步一步向前走的能力。所以,现在我要拥抱mybatis plus这种生产力工具啦。(熟悉之后,我还希望能够参与这个开源项目)

引入

这次的引入费了我不小的周折呀。先说正确的引入方法吧,其实很简单:

  1. 引入mybatis-plus-boot-starter,配好DataSource。其实这样就完成了引入,就可以使用了。
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.1</version>
</dependency>
  1. 但是,我是老项目改造,所以还有些后续工作,就是修改SqlSessionFactory的bean,之前这个bean是直接使用Mybatis的Bean,这里要改成Mybatis plus的bean
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
    MybatisSqlSessionFactoryBean fb = new MybatisSqlSessionFactoryBean();
    fb.setDataSource(dataSource);// 指定数据源(这个必须有,否则报错)
    return fb.getObject();
}
  1. 这一步其实可有可无,但是鉴于我费了那么大的劲,还是写上吧,就是调整好依赖。由于我引入的starter的springboot的版本和项目原本的版本并不一致,所以起初我以为是这个原因。但是,后来经过问题的排查和解决,基本可以确定不是这里的原因。但是,调整的过程中,却出现过Application找不到上下文的问题,起原因是2.1.x和2.2.x的差异导致的。这也是我最近发现的,即现在spring里面第二位版本号的差异也可能导致一些兼容性问题了。

使用BaseMapper

其实,这个使用也很简单,但是因为我引入的过程是那它做的第一个例子。所以,这里还是介绍下我验证过的一些事情。

  1. 首先,在官方文档中都是使用MapperScan来划定引入范围的,其实使用Mapper注解是同样生效的。
  2. BaseMapper的生效一是依赖于Mapper的扫描,而是你需要使用mybatis plus的SqlSessionFactory,就是我在引入章节第二点写的。
  3. 能找到Mapper了,我们还需要标志实体对应的是哪张表,主键是谁。这通过在类上的注解TableName和属性上的注解TableId来解决这个问题。
  4. 它对应的操作会自动的把实体中驼峰的命名转换为下划线分隔的命名方式,不一致的可以自己通过注解指明。但是,需要注意的是,java的数据类型要和数据库的对应上。我把我验证过的数据类型列在了下面,由于我使用的是PostgreSQL,所以这里的数据类型是PostgreSQL的
JAVA类型 PostgreSQL类型
Integer int(4)
Long int(8)
Boolean bool
String varchar
  1. 说了这么多都没说怎么用。其实很简单,建立自己的Mapper接口,然后让他继承BaseMapper并指定实体泛型即可

常用注解

TableName

我主要用来标志表名是谁。在使用自定义的TypeHandler的时候,可以打在属性上,然后设置autoResultMap为true。别的功能就没用过了。

TableId

用来标志谁是主键

TableField

这个是打在属性上的。对属性做的事情基本都在这里。我用过的功能有:

  • 设置数据库对应的列名。驼峰和下划线是自动转换的,无法自动转换就得自己写了。
  • 设置自定义的TypeHandler,比如我自己写的JsonTypeHandler
  • 设置更新策略,比如我的updatetime和createtime都是数据库自动更新,就需要设置插入和更新的策略忽略他们。还有一些,具体看官方文档吧。

使用条件构造器进行条件查询

其实,早期的时候我并没有把这个算成吸引我的东西。不过随着写的业务的深入,能够直接使用java的条件构造器自定义where语句,而不是想着怎么兼容各种可能有的没有的条件去写可以参数化的sql语句,这个确实是省了不少心的。这对于编码量和研发时间是非常直接的节约,同时由于不用自己设计了,也会减少很多bug的产生,很实用。
具体的使用其实也很简单,官方的指南中有条件构造器的章节。它整体上都是基于其AbstractWrapper。其下,针对select和Update有特定的实现类,使用对应的接口实现想要的功能就好。并不复杂。具体的使用,我就不赘述了,官网文档讲的很清楚:https://mybatis.plus/guide/wrapper.html#abstractwrapper 我的使用方式一般如下:

//我这个例子里用到了分页参数,需要自行构建。
LambdaQueryWrapper<YourEntity> queryWrapper= Wrappers.lambdaQuery();
//下面根据你的条件构造需要对queryWrapper进行调整,比如下面:
//记录ID
if(condition.getRecordId()!=null){
    queryWrapper=queryWrapper.eq(SensorBatchEntity::getRecordId,condition.getRecordId());
}
//最后,使用构造好的queryWrapper进行查询即可。
IPage<YourEntity> data= this.sensorBatchDao.selectPage(page,queryWrapper);

下面要说的是一些小众的操作。

自定义条件拼接

由于我的表里面有PostgreSQL的jsonb字段,使用jsonb里的值进行查询时,预定好的条件语句就显得不够用了。这个时候,就需要其条件构造器中的apply方法进行支持了。它的声明如下:

apply(String applySql, Object... params)
apply(boolean condition, String applySql, Object... params)

这个方法里,可以放置你自定义的条件语句的sql,比如下面的形式:

apply("((light_source->>'ps')::int2={0} or (light_source->>'led')::int2={0})",queryCondition.getLightSource())

light_source的数据类型是jsonb,根据值中的属性进行查询和筛选在mybatis plus中是不支持的。但是,我有不想自己写一个查询方法,于是就找到了apply方法来解决这个问题。在上述代码中,可以看到我们使用了字符串的{index}来拼接语句。这样是可以防止sql注入的,如果不用这种形式,直接拼接好字符串放进去,也是可以的,但是无法防止sql注入。

分页插件

默认mybatis-plus是没有配置分页插件的。所以,即使你按照官网提供的方法调用了,也会发现,分页并没有生效。我的配置代码如下:

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean fb = new MybatisSqlSessionFactoryBean();
        // 指定数据源(这个必须有,否则报错)
        fb.setDataSource(dataSource);

        //分页插件
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setDbType(DbType.POSTGRE_SQL);
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));


        fb.setPlugins(paginationInterceptor);
        // 开启 数据库字段 下划线 转驼峰
        //fb.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
        return fb.getObject();
    }

总之,就是使用mybatis-plus提供的SqlSessionFactory来创建SqlSession,并把分页插件配置进去,就可以了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341