Spring Boot整合MyBatis-Plus(萌新入门-自用总结-核心功能-热门插件)

MyBatis-Plus之快速启动

MyBatis-Pluis官网
在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:图中blog具体看项目

@MapperScan("com.example.blog.mapper")

在这里插入图片描述

1.核心功能——代码生成器

1.1添加依赖

配置自动生成时的错误:mybatis-plus自动生成的时候报错 java.lang.NoClassDefFoundError
参考 https://blog.csdn.net/wangjinb/article/details/106488308

MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖:

添加 代码生成器 依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.2</version>
</dependency>

添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎。

Velocity(***默认就是说该依赖必须添加,否则会报错 ***):

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.2</version>
</dependency>

Freemarker:

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>

Beetl:

<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>beetl</artifactId>
    <version>3.1.8.RELEASE</version>
</dependency>

注意!如果您选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。

AutoGenerator generator = new AutoGenerator();

// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());

// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());

// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());

// other config
...

1.2编写生成文件:

我的生成文件 CodeCreate.java

package com.example.CodeGenerator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.mysql.cj.xdevapi.Table;

//代码生成器
public class CodeCreate {
    public static  void main(String[] args){
        //DataSourceConfig 数据源配置,通过该配置,指定需要生成代码的具体数据库
        //StrategyConfig 数据库表配置,通过该配置,可指定需要生成哪些表或者排除哪些表
        //PackageConfig 包名配置,通过该配置,指定生成代码的包路径
        //TemplateConfig 模板配置,可自定义代码生成的模板,实现个性化操作
        //GlobalConfig 全局策略配置,具体请查看
        //InjectionConfig 注入配置,通过该配置,可注入自定义参数等操作以实现个性化操作
        AutoGenerator mpg = new AutoGenerator();//构建一个代码自动生成器对象
        String projectPath = System.getProperty("user.dir");
        //1.全局配置 -> GlobalConfig
        GlobalConfig gc = new GlobalConfig();
        gc.setAuthor("lzy");  //开发人员,默认null
        gc.setActiveRecord(false);//开启 ActiveRecord 模式
        gc.setBaseResultMap(false);//开启 BaseResultMap
        gc.setBaseColumnList(false);//开启 baseColumnList
        gc.setDateType(DateType.ONLY_DATE); //时间类型对应策略,默认值:TIME_PACK
        gc.setIdType(IdType.ID_WORKER);//指定生成的主键的ID类型
        gc.setEnableCache(false);//是否在xml中添加二级缓存配置
        gc.setFileOverride(true);//是否覆盖已有文件,默认false
        gc.setKotlin(false);//开启 Kotlin 模式
        gc.setOpen(false); //是否打开输出目录
        gc.setSwagger2(true);//开启 swagger2 模式
        gc.setOutputDir(projectPath+"/src/main/java");//生成文件的输出目录
        gc.setControllerName("%sController");//controller 命名方式
        gc.setEntityName("%sEntity");//实体命名方式
        gc.setMapperName("%sMapper");//mapper 命名方式
        gc.setServiceName("%sService");//service 命名方式,%s填充实体属性,%s为占位符
        gc.setServiceImplName("%sServiceImpl");//service impl 命名方式
        gc.setXmlName("%sXml");//Mapper xml 命名方式
        mpg.setGlobalConfig(gc);
        //2.配置数据源 -> dataSourceConfig
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");  //驱动名称
        dsc.setUsername("root");                        //数据库连接用户名
        dsc.setPassword("123456");                      //数据库连接密码
        dsc.setDbType(DbType.MYSQL);                   //数据库类型,该类内置了常用的数据库类型
        //dsc.setDbQuery()数据库信息查询类,默认由 dbType 类型决定选择对应数据库内置实现,实现 IDbQuery 接口自定义数据库查询 SQL 语句 定制化返回自己需要的内容
        //dsc.setKeyWordsHandler();
        //dsc.setSchemaName(); 数据库 schema name
        //dsc.setTypeConvert();类型转换,默认由 dbType 类型决定选择对应数据库内置实现
        mpg.setDataSource(dsc);
        //4.PackageConfig -> 包的相关配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.example");   //父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名
        pc.setModuleName("blog");   //父包模块名
        pc.setEntity("entity");  //Entity目录名
        pc.setMapper("mapper"); //Mapper目录名
        pc.setController("controller"); //Controller目录名
        pc.setService("service"); //Service目录名
        pc.setServiceImpl("serviceImpl");//Service Impl包名
        pc.setXml("xml"); //  Mapper XML包名
        //pc.setPathInfo()  路径配置信息
        mpg.setPackageInfo(pc);
        //3.数据库表配置 -> StrategyConfig
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("User");  //设置映射表名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
        strategy.setEntityLombokModel(true); //自动lombok
        strategy.setRestControllerStyle(true);//生成 @RestController 控制器
        strategy.setLogicDeleteFieldName("deleted");//逻辑删除名字
        //isCapitalMode是否大写命名,skipView是否跳过视图,

        mpg.setStrategy(strategy);
        //5.模板配置 -> TemplateConfig
//        TemplateConfig tc = new TemplateConfig();
//        tc.setEntity();
//        tc.setEntityKt();
//        tc.setService();
//        tc.setServiceImpl();
//        tc.setMapper();
//        tc.setXml();
//        tc.setController();
//        mpg.setPackageInfo(tc);
        //6.注入配置 -> injectionConfig
      mpg.execute(); //执行
    }
}

1.3我的目录结构:

以one为例运行CodeCreate可以生成如下图的目录结构
在这里插入图片描述
在实际编写中service层和impl、xml层并未实际用处可以删除,编写一下controller层即可返回数据。

package com.example.blog.controller;


import com.example.blog.entity.UserEntity;

import com.example.blog.mapper.UserMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author lzy
 * @since 2020-07-01
 */
@RestController
public class UserController {
    @Autowired

    UserMapper userMapper;

    @RequestMapping(value = "/qurry")
    public UserEntity qurryOne(){

        return userMapper.selectById(4L);
    }

    @RequestMapping(value = "/list")
    public List<UserEntity> queryAllUser(){
        List<UserEntity> users = userMapper.selectList(null);
        return users;
    }

    @RequestMapping(value = "/insert/{name}/{age}/{email}")
    public String insertUser(@PathVariable("name")String name,@PathVariable("age")Integer age,@PathVariable("email")String email){
        UserEntity user = new UserEntity();
        user.setName(name);
        user.setAge(age);
        user.setEmail(email);
        userMapper.insert(user);
        return "insert is running";
    }

    @RequestMapping(value = "/update/{id}/{name}/{age}/{email}")
    public String update(@PathVariable("id")Long id,@PathVariable("name")String name,@PathVariable("age")Integer age,@PathVariable("email")String email){
        UserEntity user = new UserEntity();
        user.setId(id);
        user.setName(name);
        user.setAge(age);
        user.setEmail(email);
        userMapper.updateById(user);
        return "update is running";
    }
    @RequestMapping(value = "/delete/{id}") //删除
    public String DeleteUserById(@PathVariable("id")Long id){
        int r =  userMapper.deleteById(id);
        return "Delete is running";
    }
}

如下图是访问/hello2得到 list里面的数据。
在这里插入图片描述

2 插件扩展——逻辑删除

2.1配置文件

application.properties文件配置如下:

#配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-field= flag  #全局逻辑删除字段值 3.3.0开始支持,详情看下面。
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

application.yml文件配置如下:(如果你的默认值和mp默认的一样,该配置可无)

  global-config:
    db-config:
      logic-delete-field: flag  #全局逻辑删除字段值 3.3.0开始支持,详情看下面。
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

2.2数据库表中添加字段deleted

在数据库中书写deleted字段,默认为0
在这里插入图片描述

2.3 Entity层User/UserEntity文件下添加字段(@TableLogic)

在这里插入图片描述

字段支持所有数据类型(推荐使用 Integer,Boolean,LocalDateTime)
如果使用LocalDateTime,建议逻辑未删除值设置为字符串null,逻辑删除值只支持数据库函数例如now() 效果:
使用mp自带方法删除和查找都会附带逻辑删除功能 (自己写的xml不会)
设置逻辑删除后,执行删除操作实际上是更新操作,更新deleted为1,从而数据库可见,用户不可见
说明:

example
删除 update user set deleted=1 where id =1 and deleted=0
查找 select * from user where deleted=0

全局逻辑删除: begin 3.3.0

如果公司代码比较规范,比如统一了全局都是flag为逻辑删除字段。

使用此配置则不需要在实体类上添加 @TableLogic。

但如果实体类上有 @TableLogic 则以实体上的为准,忽略全局。 即先查找注解再查找全局,都没有则此表没有逻辑删除。

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag  #全局逻辑删除字段值

附件说明

逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。 如果你需要再查出来就不应使用逻辑删除,而是以一个状态去表示。
如: 员工离职,账号被锁定等都应该是一个状态字段,此种场景不应使用逻辑删除。

若确需查找删除数据,如老板需要查看历史所有数据的统计汇总信息,请单独手写sql。

3.条件构造器——查询

3.1编写测试类 WrapperTest

package com.example;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.blog.mapper.UserMapper;
import com.example.blog.entity.UserEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Map;

@SpringBootTest
public class WrapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void test1(){
        //查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper
                .isNotNull("name")
                .isNotNull("email")
                .ge("age",12);
        userMapper.selectList(wrapper).forEach(System.out::println);
    }

    @Test
    void test2(){
        //查询名字风花雪月
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("name","风花雪月");
        UserEntity user =  userMapper.selectOne(wrapper);
        System.out.println(user);
    }

    @Test
    void test3(){
        //查询年龄在18-30
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.between("age",18,30);
        Integer count =  userMapper.selectCount(wrapper);
        System.out.println(count);
    }

    @Test
    void test4(){
        //查询名字没有e并且右边以t开头
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper
                .notLike("name","e")
                .likeRight("email","t");

        List<Map<String, Object>> maps =  userMapper.selectMaps(wrapper);
        maps.forEach(System.out::println);
    }

    @Test
    void test5(){
        //id在子查询中查询出来
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.inSql("id","select id from user where id>3");

        List<Object> objects =  userMapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
    }

    @Test
    void test6(){
        //通过id排序
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("id");

        List<UserEntity> users =  userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }
}

4.核心功能——分页插件

4.1编写配置类MyBatisPlusConfig (取自官网拿来即用

package com.example.config;

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

@EnableTransactionManagement
@Configuration
@MapperScan("com.example.blog.mapper")  //扫描文件夹
public class MyBatisPlusConfig {
    //分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

4.2测试函数以及效果图

在这里插入图片描述

5.插件扩展——自动填充功能

5.1步骤一:数据库添加字段

在这里插入图片描述

5.2步骤二:在UserEntity中添加字段,也可以在自动生成中配置

在这里插入图片描述

5.3步骤三:自定义实现类 MyMetaObjectHandler

package com.example.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;

@Slf4j
@Component //
public class MyMetaObjectHandler implements MetaObjectHandler {

   //插入时的更新策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill...");
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
    //更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill...");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

5.4注意事项:

字段必须声明TableField注解,属性fill选择对应策略,该声明告知Mybatis-Plus需要预留注入SQL字段
填充处理器MyMetaObjectHandler在 Spring Boot 中需要声明@Component或@Bean注入
要想根据注解FieldFill.xxx和字段名以及字段类型来区分必须使用父类的strictInsertFill或者strictUpdateFill方法
不需要根据任何来区分可以使用父类的fillStrategy方法**

5.5 FieIdFill策略在5.2中的应用

public enum FieldFill {
    /**
     * 默认不处理
     */
    DEFAULT,
    /**
     * 插入填充字段
     */
    INSERT,
    /**
     * 更新填充字段
     */
    UPDATE,
    /**
     * 插入和更新填充字段
     */
    INSERT_UPDATE
}

6:自用小插件——SQL配置日志输出

在这里插入图片描述

6.1:效果图展示

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章