MyBatis-Plus3.x版本使用问题

简介

       个人认为呢,Mybatis-Plus是Mybatis的增强版,他只是在Mybatis的基础上增加了功能,且并未对原有功能进行任何的改动。可谓是非常良心的一款开源产品,今天我就来给大家简单的说一下以下几个功能和踩过的坑。

在最新的3.x版本踩的几个坑

mybatis-plus提供了非常强大的代码生成器,可以一键生成controller、service、mapper、mapping文件,省去了很多重复的动作,这里提供代码生成器的代码

package com.jianghaichao.infantmom;


import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.Scanner;

/**
 * @program: infantmom
 * @classname: CodeGenerator
 * @description: mybatisplus代码生成器 当前为不覆盖
 * @author: zhulin
 * @create: 2019-05-22 16:09
 **/
public class CodeGenerator {

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("zhulin");
        gc.setOpen(false);
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        gc.setServiceName("%sService");
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/infantmom?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.jianghaichao.infantmom")
                .setMapper("mapper")
                .setEntity("entity")
                .setService("service")
                .setController("controller")
                .setXml("mapping");
        mpg.setPackageInfo(pc);

/*        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig() {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                return projectPath + "/src/main/resources/mapping/"
                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);*/


        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        mpg.setStrategy(strategy);
        mpg.execute();
    }

}

这里要注意,如上生成的实体类是开启了lombox注解的,所以你如果用的idea的话,可能还要下载一个lombox插件和在pom.xml文件中导入lombox的包,不然木有效果,闲麻烦也可以关闭strategy.setEntityLombokModel(true);删掉即可,默认为false;

还有不知道为什么自定义配置的xml文件生成路径无效,总是生成在java目录下,本想配置到resource下的。翻阅了网上一些博客也没做出来,先略过了,生成后自己复制一下也行。

至于生成的service和mapper层的方法就不说了,直接看官方文档https://mp.baomidou.com/guide/crud-interface.html会更详细

关于mybtais-plus3.x的分页

我们知道mybtais-plus3.x版本之前是自带一个内存分页(在分页的时候,是把所有的数据都查询出来,然后通过RowBounds进行在内存分页)的,也有分页插件pagination。

但mybatis-plus3.x之前的分页方法是这样的,且返回的是List<T>集合,并且内存分页并不需要配置分页插件

    /**
     * <p>
     * 根据 entity 条件,查询全部记录(并翻页)
     * </p>
     *
     * @param rowBounds 分页查询条件(可以为 RowBounds.DEFAULT)
     * @param wrapper   实体对象封装操作类(可以为 null)
     * @return List<T>
     */
    List<T> selectPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper);

但我使用mybtais-plus3.x之后的分页是这样的

    /**
     * 翻页查询
     *
     * @param page         翻页对象
     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);

可以看到返回的是IPage接口,其实这里返回的IPage跟传进去的第一个参数page是一样的,我们可以自己实现IPage接口也可以直接使用已经提供好的Pagehttps://mp.baomidou.com/guide/page.html

但这里要注意,3.x版本要使用分页,必须配置插件,否则会没有效果,不像2.x没配插件就是内存分页。

package com.jianghaichao.infantmom.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @program: infantmom
 * @classname: MybatisPlusConfig
 * @description: mybatis-plus配置
 * @author: zhulin
 * @create: 2019-05-25 09:58
 **/
//Spring boot方式
@EnableTransactionManagement
@Configuration
@MapperScan("com.jianghaichao.infantmom.mapper")
public class MybatisPlusConfig {

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

上面是springboot的配置形式

2.x的EntityWrapper到3.x也变成了QueryWrapper

还有selectWrapper等就不一一列举了。用到在了解就行

2019/7/31踩坑补充,mybatis-plus代码生成器生成LocalDateTime,查询报错问题

报错如下

org.springframework.dao.InvalidDataAccessApiUsageException: Error attempting to get column 'created' from result set.  Cause: java.sql.SQLFeatureNotSupportedException ; null; nested exception is java.sql.SQLFeatureNotSupportedException

解决方法:

在代码生成器的全局策略中加上一行 gc.setDateType(DateType.ONLY_DATE);

设置生成的时间类型为Date即可解决问题,官网上也有这个问题的介绍

2020/1/6踩坑补充,mp的自动填充

我们都知道,例如阿里开发规范里面要求,每张表都要有create_time和update_time字段,所以我们在插入数据和修改数据的时候往往需要自己set值进去,既然是一样的操作,那么mp提供了自动注入,这里写几点自动填充时需要注意的点。

更多用法见官网https://mp.baomidou.com/guide/auto-fill-metainfo.html

1. 自动注入在每次insert或update时都会触发,所以我们要考虑性能问题,那么就会有如下优化写法

这里需要注意的一点,这里的cretaeTime是实体类属性而不是数据库字段名!

且填充有如下条件:

2020/1/9踩坑补充,Wrapper 自定义SQL

最近使用mybatis-plus3.2.0版本碰到一个问题,从官方文档我们可看到3.0.7以后有了该功能

这里要提醒各位,如果在实例化的时候直接注入entity,你会发现无效,必须得用eq等方法

// 如下类似写法均无效
LambdaQueryWrapper<WxCommentVO> wrapper = Wrappers.lambdaQuery(wxComment);
QueryWrapper<WxCommentVO> wrapper1 = new QueryWrapper<>(wxComment);

// 假如你需要判断某字段值是否为1
wrapper.eq(WxComment::某字段,1);

必须得这样写,直接通过实体类注入是无效的
发布了27 篇原创文章 · 获赞 32 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_39809458/article/details/90667544