本文最后更新于 2023-08-16,文章内容可能已经过时,请注意内容的辨别。

Mybatis-plus

简介

MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

作者:苞米豆组织 因为项目是在码云上的,看成员很多都是中文名字所以我默认是中国的

特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

准备工作

创建springboot工程

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>kj08</groupId>
    <artifactId>mybatisplusdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatisplusdemo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--mybatisPlus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3.4</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.18</version>
        </dependency>
        <dependency>
            <groupId>p6spy</groupId>
            <artifactId>p6spy</artifactId>
            <version>3.9.1</version>
        </dependency>
        <!-- 模板引擎 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

配置文件

spring:
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url:  jdbc:p6spy:mysql://localhost:3306/kj08?useAffectedRows=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 9320
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      #配置获取连接等待超时的时间
      max-wait: 60000
      #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 30000

mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1  #逻辑删除的值是1
      logic-not-delete-value: 0 #不逻辑删除的值是0
  configuration:
    #我们在数据库的字段名也是 userCode
    #但是如果我们不设置mybstis plus 默认的驼峰式编码在mybatis plus 则会默认把驼峰式编码写成 user_code, 这种下划线格式的字段,
    #这时你会发现你的代码会出错,它会提示你user_code字段不存在
    map-underscore-to-camel-case: false
  # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


创建实体类

普通查询

创建mapper只要继承了baseMapper就能省略基础的CURD操作了

@Mapper
@Repository
public interface BlogMapper extends BaseMapper<Blog> {

}

test测试

package kj08.mybatisplusdemo;

import kj08.mybatisplusdemo.mapper.BlogMapper;
import kj08.mybatisplusdemo.pojo.Blog;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class MybatisplusdemoApplicationTests {

@Autowired
private BlogMapper blogMapper;

@Test
public void testSelect() {
    System.out.println(("----- selectAll method test ------"));
    List<Blog> userList = blogMapper.selectList(null);
    for (Blog blog : userList) {
        System.out.println(blog);
    }
}
}

插入操作

在谈到插入操作的时候,我们要先来看一下关于主键的策略,已知我们有默认的之间策略即我们的mysql自增的策略,但是在分布式的项目当中如果说用mysql自带的主键生成策略就会出现重复,所以又有了其他的主键生成策略一般来说有uuid和雪花算法(记得是推特的)在mybatis中也有相关的操作能让我们不用自己写主键值靠mp自动填充

简单的插入操作

@Test
public void testInsert() {
    System.out.println(("----- selectInsert method test ------"));
    int insert = blogMapper.insert(new Blog());
    System.out.println(insert);
}

加入生成主键策略(在实体类加注解)

@TableId
属性类型必须指定默认值描述
valueString""主键字段名
typeEnumIdType.NONE主键类型

idtype是枚举型

描述
AUTO数据库ID自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert前自行set主键值
ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)

一般我们用ASSIGN_ID,但是有个问题他生成的值是19位的,我们数据库就要有相应的改变,首先数据库字段要是bigint的并且我们的实体类的一定要是Long的这样才能成功,数据库设置自增不自增已经不影响了

package kj08.mybatisplusdemo.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Blog {
    @TableId(type = IdType.ASSIGN_ID)
   private Long blogId;
   private String title;
   private String comment;
   private String picPath;

}

普通修改操作

//普通的修改
@Test
public void testUpdate() {
    Blog blog = blogMapper.selectById(1L);
    blog.setComment("ss");
    int i = blogMapper.updateById(blog);
    System.out.println("有"+i+"条数据被修改");
}

普通删除操作

//普通删除操作
@Test
public void testDelete() {
    int i = blogMapper.deleteById(1L);
    System.out.println("有"+i+"条数据被删除");
}

逻辑删除操作

首先逻辑删除并不是删除,因为我说了,删除这个操作我们一般是不用的,所以逻辑删除很有必要,其实所谓的逻辑删除也就是修改,那下面我们来学习怎么去逻辑删除

1.加表字段logicDel 设置默认值是0 加实体类属性logicDel

2.配置逻辑删除

mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1  #逻辑删除的值是1
      logic-not-delete-value: 0 #不逻辑删除的值是0

3.加注解

package kj08.mybatisplusdemo.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.*;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
public class Blog {
    @TableId(type = IdType.ASSIGN_ID)
   private Long blogId;
   private String title;
   private String comment;
   private String picPath;
   @TableLogic //逻辑删除注解
   private String logicDel;


}

4.删除(修改)

//逻辑删除
@Test
public void testLogicDel() {
    int i = blogMapper.deleteById(2L);
    System.out.println(i);
}

你看他的日志,其实是修改。总结,方法都是一样的但是注意只要有了配置logic-delete-value和注解 @TableLogic他就不删了生成的sql是很标准严谨的sql

 UPDATE blog SET logicDel='1' WHERE blogId=? AND logicDel='0'

乐观锁操作

1.加表字段version 设置默认值是1 加实体类属性version 并加注解@Version 默认int

2.加配置类

package kj08.mybatisplusdemo.conf;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor optimisticLockerInnerInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

原代码

//乐观锁
@Test
public void testlgUpdate() {
    Blog blog = blogMapper.selectById(3L);
    blog.setComment("sss");
    int i = blogMapper.updateById(blog);
    System.out.println("有"+i+"条数据被修改");
}

注意sql语句

SELECT blogId,title,comment,picPath,logicDel,version FROM blog WHERE blogId=? AND logicDel='0'

UPDATE blog SET title=?, comment=?, picPath=?, version=? WHERE blogId=? AND logicDel='0'

当我们的实体类加了@version之后

SELECT blogId,title,comment,picPath,logicDel,version FROM blog WHERE blogId=? AND logicDel='0'

UPDATE blog SET title=?, comment=?, picPath=?, version=? WHERE blogId=? AND version=? AND logicDel='0'

注意看version也变了变成了2

总结:节约了我们的乐观锁的操作

自动填充

在我们日常的数据库操作当中,肯定会遇到添加创建时间修改时间的事情,这些事情也是固定化的操作而这种操作,我们一般用代码方式,而我们的mybatisplus就帮助我们实现了

1.表创建字段createtime,updatetime date类型 实体类也创建

2.在confi下创建处理器

package kj08.mybatisplusdemo.conf;
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.strictInsertFill(metaObject, "createtime", Date.class,new Date());

}

@Override
public void updateFill(MetaObject metaObject) {
    log.info("start update fill ....");
    this.strictUpdateFill(metaObject, "updatetime", Date.class, new Date());

}
}

3.在实体类加注解

@TableField(fill=FieldFill.INSERT)
    private Date createtime;
@TableField(fill=FieldFill.UPDATE)
    private Date updatetime;
    //实体类数据类型和处理器数据类型要保证一致 

3.运行新增修改代码试试,注意自动填充策略是如果属性有值则不覆盖,如果没值就填充,改变这一现象需要加一下代码,但是可能以后会有变动。mp个版本差异性很大,使用的时候需要明确版本。

@TableField(fill=FieldFill.INSERT_UPDATE,update = "now()")
    private Date updatetime;

BaseMapper

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.baomidou.mybatisplus.core.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;

public interface BaseMapper<T> extends Mapper<T> {
    int insert(T entity);

    int deleteById(Serializable id);

    int deleteById(T entity);

    int deleteByMap(@Param("cm") Map<String, Object> columnMap);
	//map里面放字段名和值 string是字段名 object是值

    int delete(@Param("ew") Wrapper<T> queryWrapper);

    int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    int updateById(@Param("et") T entity);

    int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

    T selectById(Serializable id);

    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);

    default T selectOne(@Param("ew") Wrapper<T> queryWrapper) {
        List<T> ts = this.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(ts)) {
            if (ts.size() != 1) {
                throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records", new Object[0]);
            } else {
                return ts.get(0);
            }
        } else {
            return null;
        }
    }

    Long selectCount(@Param("ew") Wrapper<T> queryWrapper);

    List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);

    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);

    List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);

    <P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper);

    <P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper);
}

关于map参数举例

@Test
public void testSelectByMap() {
    System.out.println(("----- selectAll method test ------"));
    HashMap<String, Object> map = new HashMap<>();
    map.put("title","aa");
    List<Blog> userList = blogMapper.selectByMap(map);
    for (Blog blog : userList) {
        System.out.println(blog);
    }
}

关于Wrapper参数举例

Wrapper是条件构造器的抽象类

一般两个继承类是QueryWrapper和UpdateWrapper

QueryWrapper方法
方法名说明使用
eq=eq(“real_name”,“王昭君”)
ne<>ne(“nick_name”,“空想 4”)
gt>gt(“age”,21)
ge>=ge(“age”,22)
lt<lt(“age”,22)
le<=le(“age”,21")
betweencloum between ? and ?between(“age”,21)
notBetweencloum between ? and ?notBetween(“age”,21)
likecloum like ‘% 王 %’like(“real_name”,“王”)
notLikenot like ‘% 王 %’notLike(“real_name”,“王”)
likeLeftlike ‘% 王’likeLeft(“real_name”,“昭”)
likeRightlike ‘王 %’likeRight(“real_name”,“昭”)
isNullis nullisNull(“gender”)
isNotNullis not nullisNotNull(“gender”)
inin (1,2,3)in(“nick_name”,lists)
notInage not in (1,3)notIn(“nick_name”,lists)
insqlage in (1,3,4,5,6)insql(“nick_name”,"‘空想 4’,‘空想 5’,‘空想 6’")
notInsqlage not in (1,6)notInsql(“nick_name”,‘空想 6’")
groupBygroup by id,namegroupBy(“nick_name”,“age”)
orderByAscorder by id ASC,name ASCorderByAsc(“nick_name”,“age”)
orderByDescorder by id DESC,name DESCorderByDesc(“age”)
orderByorder by id ASC,name ASCorderBy(true,true,“age”)
havinghaving sum(age) > 10having(“sum(age) > 10”)
orid = 1 or name = ‘老王’eq(“nick_name”,“空想 4”).or(i->i.eq(“age”,21) eq(“nick_name”,“空想 4”).or().eq(“nick_name”,“空想 5”)
andand (name = ‘李白’ and status <> ‘活着’)and(i->i.eq(“age”,21))
nested(name = ‘李白’ and status <> ‘活着’)nested(i->i.eq(“age”,21).eq(“nick_name”,“空想 4”))
applyid = 1apply(“nick_name = ‘空想 4’”)
last最后添加多个以最后的为准,有 sql 注入风险last(“limit 1”)
exists拼接 EXISTS (sql 语句)exists(“select id from table where age = 1”)
notExists拼接 NOT EXISTS (sql 语句)notExists(“select id from table where age = 1”)
//wrapper查询
@Test
public void testWrapperSelectByMap() {
    System.out.println(("----- selectAll method test ------"));
    QueryWrapper wrapper=new QueryWrapper();
    wrapper.eq("title","aa");
    List<Blog> list = blogMapper.selectList(wrapper);

    for (Blog blog : list) {
        System.out.println(blog);
    }
}
//wrapper修改一般不用
@Test
public void testWrapperUpdate() {
    UpdateWrapper<Blog> blogUpdateWrapper = new UpdateWrapper<>();
    blogUpdateWrapper.eq("title","aa");
    Blog blog = blogMapper.selectById(1447419394744479746L);
    blogMapper.update(blog,blogUpdateWrapper);

}

分页查询

我们之前学了原始的limit个mybatis常用的pagehelper在mp中也是有分页的插件的

他就是Page

在使用这个page之前要做一个配置操作,死代码

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 注册乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        // 分页查询插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }

配置完成之后测试

   // 测试分页查询
@Test
public void testPage(){
    // 参数一:当前页,参数二:页面大小
    Page<Blog> page = new Page<>(2,3);
    // 不进行 count sql 优化,解决 MP 无法自动优化 SQL 问题,这时候你需要自己查询 count 部分
    // page.setOptimizeCountSql(false);
   /*有时使用分页功能的时候发现统计到的total和预期不符,于是在控制台查看分页count sql,
    发现mybatis自动优化了sql,把select 后面要查询的内容全部省略,直接count。这是mysql自动优化的策略。
    正常情况下这样做并没有什么问题,但是当我select 后面需要聚合,比如使用sum函数的时候,自动优化得到的total就会比预期多。
    当日解决办法也是有的,就是禁用自动优化*/

    // 当 total 为小于 0 或者设置 setSearchCount(false) 分页插件不会进行 count 查询
    // 要点!! 分页返回的对象与传入的对象是同一个
    IPage<Blog> bolgPage = blogMapper.selectPage(page, null);
    List<Blog> records = bolgPage.getRecords();
    for (Blog record : records) {
        System.out.println(record);
    }
    System.out.println(page.getTotal());
}

排序查询

两种方式

加注解

@OrderBy(优先级低于wrapper)

属性类型必须指定默认值描述
isDescboolean是否倒序查询
sortshortShort.MAX_VALUE数字越小越靠前

条件构造器

wrapper.orderByAsc(R... columns)

wrapper.orderByDesc(R... columns)

执行 SQL 分析打印

spring:
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url:  jdbc:p6spy:mysql://localhost:3306/kj08?useAffectedRows=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 9320
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      #配置获取连接等待超时的时间
      max-wait: 60000
      #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 30000

mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1  #逻辑删除的值是1
      logic-not-delete-value: 0 #不逻辑删除的值是0
  configuration:
    #我们在数据库的字段名也是 userCode
    #但是如果我们不设置mybstis plus 默认的驼峰式编码在mybatis plus 则会默认把驼峰式编码写成 user_code, 这种下划线格式的字段,
    #这时你会发现你的代码会出错,它会提示你user_code字段不存在
    map-underscore-to-camel-case: false
  # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

主要改 driver-class-name: com.p6spy.engine.spy.P6SpyDriver url: jdbc:p6spy:mysql://localhost:3306/kj08?useAffectedRows=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8

加spy.properties

#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2

日志输出:

Consume Time:13 ms 2021-10-12 16:39:02 Execute SQL:SELECT blogId,title,comment,picPath,logicDel,version,createtime,updatetime FROM blog WHERE title = 'aa' AND logicDel='0'

代码生成器

步骤

1.加依赖

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!-- 模板引擎 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

运行这个类

package kj08.mybatisplusdemo;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

@SpringBootTest
public class Generator {

@Test
    public void GeneratorCode(){
    AutoGenerator mpg = new AutoGenerator();

    // 全局配置
    GlobalConfig gc = new GlobalConfig();
    String projectPath = System.getProperty("user.dir");
    gc.setOutputDir(projectPath + "/src/main/java");
    gc.setAuthor("afeng");//設置作者
    gc.setOpen(false);//是否打開資源管理器(不管他)
    gc.setSwagger2(true); //实体属性 Swagger2 注解
    gc.setFileOverride(false);//是否覆蓋原來的
    gc.setServiceImplName("%sService");//去service的I前綴
    mpg.setGlobalConfig(gc);

    // 数据源配置
    DataSourceConfig dsc = new DataSourceConfig();
    dsc.setUrl("jdbc:mysql://localhost:3306/kj08?useUnicode=true&useSSL=false&characterEncoding=utf8");
    // dsc.setSchemaName("public");
    dsc.setDriverName("com.mysql.cj.jdbc.Driver");
    dsc.setUsername("root");
    dsc.setPassword("9320");
    mpg.setDataSource(dsc);

    // 包配置
    PackageConfig pc = new PackageConfig();
    pc.setModuleName("login");
    pc.setParent("kj08.mybatisplusdemo");
    pc.setController("controller");
    pc.setEntity("pojo");
    pc.setMapper("mapper");
    pc.setService("service");

    mpg.setPackageInfo(pc);
    StrategyConfig stConfig = new StrategyConfig();
    stConfig.setInclude("blog","class");//主要是用這個要生成几个表的
    stConfig.setEntityLombokModel(true);//要不要用lombok
    mpg.setStrategy(stConfig);
    mpg.execute();
    }

}


MybatisX 快速开发插件

作用:响应文件 生成mapper.xml 里的基本标签

步骤

1.打开 IDEA,进入 File -> Settings ->搜索 plugins 输入 mybatisx 搜索并安装。重启idea

你能在mapper上能看到小鸟

然后你写个接口

alt加enter

generate statement 选择 就自定在mapper。xml中生成标签了