springboot中使用MyBatisPlus Mybatis-Plus简介 Springboot整合Mybatis-Plus Mybatis-Plus逆向工程

Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。虽然mybatis可以直接在xml中通过SQL语句操作数据库,很是灵活。但正其操作都要通过SQL语句进行,就必须写大量的xml文件,很是麻烦。Mybatis-Plus出现前市面上已经有了一些mybatis逆向工程工具(mybatis-generate,idea中的easyCode插件等),这些工具可以帮助我们快速生成一些基础的xml、mapper和model文件等,然后都是一些基础的方法,实际场景中作用不大。Mybatis-Plus官网地址:https://mybatis.plus/guide/

Springboot整合Mybatis-Plus

依赖和配置

 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
  </dependency>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
  </dependency>
  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
  </dependency>
  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
  </dependency>
  <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.4.1</version>
  </dependency>
server:
  port: 8888
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:mysql://localhost:3306/mbg?useSSL=false&useUnicode=yes&characterEncoding=utf8
    username: root
    password: 123456
mybatis-plus:
  global-config:
    db-config:
      id-type: auto
      table-prefix: t_
logging:
  level:
    root: info
    com.example: debug

基础编码

我们需要自己创建实体类和mapper类,在实体类中可能需要使用一些注解(表名、字段名与实体类名称不符的时候),例如@TableName、@TableId、@TableField等

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

BaseMapper中已经涵盖了常用的curd方法,类似于jpa的使用

public interface UserMapper  extends BaseMapper<User> {

    Page<User> selectPageByAge(Page page, @Param("age") Integer age);
}

测试方法

举例几个curd方法,具体用法参考官方文档

 @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelect(){
        List<User> users = userMapper.selectList(null);
        Assert.assertEquals(5,users.size());
        users.forEach(System.out::println);
    }

    @Test
    public void testSelectByCondition(){
        Map<String,Object> columnMap = new HashMap<>();
        //map中key写表中的列名
        columnMap.put("name","zhangsan");
        List<User> users = userMapper.selectByMap(columnMap);
        users.forEach(System.out::println);
    }


    @Test
    public void testInsert(){
        User user = new User();
        user.setName("zhangsan");
        user.setAge(12);
        user.setEmail("123@123");
        userMapper.insert(user);
        System.out.println(user.getId());
    }

    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(1l);
        user.setName("asd");
        //根据id进行更新,没有传值的属性就不会更新
        userMapper.updateById(user);
    }

全局配置

配置结构如下,我在demo中通过db-config为表中id统一设置了自增id以及表明前缀,其它配置还是参考官网

mybatis-plus:
  ......
  configuration:
    ......
  global-config:
    ......
    db-config:
      ......  

条件构造器

不用编写 SQL 语句,MP 提供了功能强大的条件构造器:AbstractWrapper

 @Test
    public void testQueryWrapper(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().between(User::getAge, 21, 26).eq(User::getName, "Sandy");
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }

    @Test
    public void testUpdateWrapper(){

        User user = new User();
        user.setEmail("sdfdsf@123.com");
        user.setName("asd");
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().between(User::getAge, 21, 26).eq(User::getName, "Sandy");
        int update = userMapper.update(user, updateWrapper);
    }

分页插件

配置时请注意依赖版本,不同版本api变化挺大,并且官网更新不及时,因此需要看源码,这里给出新版本添加拦截器的两种方式

@Configuration
@MapperScan("com.example.mbp.mapper")
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        Properties properties = new Properties();
        properties.setProperty("@page", "com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor");
        properties.setProperty("page:maxLimit", "5");
        mybatisPlusInterceptor.setProperties(properties);
//        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
//        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
//        paginationInnerInterceptor.setOverflow(false);
//        // 设置最大单页限制数量,默认 500 条,-1 不受限制
//        paginationInnerInterceptor.setMaxLimit(500L);
//        paginationInnerInterceptor.setProperties();
//        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
        return mybatisPlusInterceptor;
    }
}

Mybatis-Plus逆向工程

Mybatis-Plus的代码生成器基于Java配置进行生成,可生成: 实体类、Mapper 接口、Mapper 映射文件、 Service 层、Controller 层。只生成基本的框架类,没有具体实现方法。

public class MyBatisPlusGenerator {

    public static void main(String[] args) {
        String projectPath = System.getProperty("user.dir");
        // 代码生成器
        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setGlobalConfig(initGlobalConfig(projectPath));
        autoGenerator.setDataSource(initDataSourceConfig());
        autoGenerator.setPackageInfo(initPackageConfig("order"));
        autoGenerator.setCfg(initInjectionConfig(projectPath, "order"));
        autoGenerator.setTemplate(initTemplateConfig());
        autoGenerator.setStrategy(initStrategyConfig(new String[]{"t_order"}));
        autoGenerator.setTemplateEngine(new VelocityTemplateEngine());
        autoGenerator.execute();
    }


    /**
     * 初始化全局配置
     */
    private static GlobalConfig initGlobalConfig(String projectPath) {
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(projectPath + "/src/main/java");
        globalConfig.setAuthor("hehang");
        globalConfig.setOpen(false);
        globalConfig.setSwagger2(false);
        globalConfig.setIdType(IdType.AUTO);
        globalConfig.setBaseResultMap(true);
        globalConfig.setFileOverride(true);
        globalConfig.setDateType(DateType.ONLY_DATE);
        globalConfig.setEntityName("%s");
        globalConfig.setMapperName("%sMapper");
        globalConfig.setXmlName("%sMapper");
        globalConfig.setServiceName("%sService");
        globalConfig.setServiceImplName("%sServiceImpl");
        globalConfig.setControllerName("%sController");
        return globalConfig;
    }

    /**
     * 初始化数据源配置
     */
    private static DataSourceConfig initDataSourceConfig() {
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mbg?useSSL=false&useUnicode=yes&characterEncoding=utf8");
        dataSourceConfig.setDriverName("com.mysql.jdbc.Driver");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("123456");
        return dataSourceConfig;
    }

    /**
     * 初始化包配置
     */
    private static PackageConfig initPackageConfig(String moduleName) {
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setModuleName(moduleName);
        packageConfig.setParent("com.example.modules");
        packageConfig.setEntity("model");
        return packageConfig;
    }

    /**
     * 初始化模板配置
     */
    private static TemplateConfig initTemplateConfig() {
        TemplateConfig templateConfig = new TemplateConfig();
        //可以对controller、service、entity模板进行配置
        //mapper.xml模板需单独配置
        templateConfig.setXml(null);
        return templateConfig;
    }

    /**
     * 初始化策略配置
     */
    private static StrategyConfig initStrategyConfig(String[] tableNames) {
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setEntityLombokModel(true);
        strategyConfig.setRestControllerStyle(true);
        //当表名中带*号时可以启用通配符模式
        if (tableNames.length == 1 && tableNames[0].contains("*")) {
            String[] likeStr = tableNames[0].split("_");
            String likePrefix = likeStr[0] + "_";
            strategyConfig.setLikeTable(new LikeTable(likePrefix));
        } else {
            strategyConfig.setInclude(tableNames);
        }
        return strategyConfig;
    }

    /**
     * 初始化自定义配置
     */
    private static InjectionConfig initInjectionConfig(String projectPath, String moduleName) {
        // 自定义配置
        InjectionConfig injectionConfig = new InjectionConfig() {
            @Override
            public void initMap() {
                // 可用于自定义属性
            }
        };
        // 模板引擎是Velocity
        String templatePath = "/templates/mapper.xml.vm";
        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                return projectPath + "/src/main/resources/mapper/" + moduleName
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        injectionConfig.setFileOutConfigList(focList);
        return injectionConfig;
    }

}