目录

一、什么是MybatisPlus

二、快速入门

2.1、创建数据库mybatis_plus

2.2、创建user表

2.3、插入数据

2.4、初始化项目

2.5、添加依赖

2.6、配置(连接数据库)

2.7、编码

2.8、开始使用

2.9、小结

三、配置日志

四、CRUD

4.1、插入测试

4.2、自定义ID生成器

4.2.1、UUID

4.2.2、SnowFlake(雪花算法)

4.3、更新操作

五、自动填充

5.1、什么是自动填充

5.2、自动填充方式

六、乐观锁和悲观锁

6.1、什么是乐观锁

6.2、什么是悲观锁

6.3、配置乐观锁

6.3.1、数据库中添加version字段

6.3.2、同步实体类

6.3.3、配置插件

6.3.4、测试乐观锁

七、增删改查

7.1、查询操作

7.2、分页查询

7.3、删除操作

7.4、逻辑删除

八、执行SQL分析打印

8.1、p6spy依赖引入

8.2、application.yml配置

8.3、spy.properties配置

8.4、测试

九、条件构造器

9.1、代码演示

十、代码自动生成器

10.1、EasyCode

10.2、功能

10.3、操作


一、什么是MybatisPlus

为什么要学MybatisPlus?

MybatisPlus可以节省大量时间,所有的CRUD代码可以自动化完成

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

特性

二、快速入门

2.1、创建数据库mybatis_plus

2.2、创建user

DROP TABLE IF EXISTS user;
​
CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);

2.3、插入数据

DELETE FROM user;
​
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

2.4、初始化项目

快速初始化一个空的spring boot 项目

2.5、添加依赖

引用spring boot starter工程

<parent&gt;
    <groupId&gt;org.springframework.boot</groupId&gt;
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.5</version>
    <relativePath/>
</parent>

引入springboot-starterspring-boot-starter-test、mybatis-plus-boot-starterh2依赖

<dependencies>
    <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>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>

注意:尽量不要同时导入mybatis和mybatis_plus,版本差异

2.6、配置(连接数据库)

application.yml配置文件添加MySQL数据库相关配置:

# DataSource Config
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql:///mybatis_plus?userUnicode=true&amp;characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver

在spring boot启动类中添加@MapperScan注解扫描Mapper文件夹

@SpringBootApplication
@MapperScan("com.wen.mybatis_plus.mapper")  //扫描mapper
public class MybatisPlusApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);
    }
​
}

2.7、编码

编写实体类User.java(此处使用Lombok简化代码

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

编写Mapper包下的UserMapper接口

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wen.mybatis_plus.pojo.User;
import org.apache.ibatis.annotations.Mapper;
​
//再对应mapper上面实现基本接口 BaseMapper
@Mapper
public interface UserMapper extends BaseMapper<User> {
    //所有的CRUD都已经完成
    //不需要像以前一样配置一大堆文件:pojo-dao(连接mybatis,配置mapper.xml文件)==>service-controller
}

注意:

要在主启动类上去扫描mapper包下的所有接口:@MapperScan(“com.wen.mybatis_plus.mapper“)

2.8、开始使用

添加测试类,进行功能测试

@SpringBootTest
class MybatisPlusApplicationTests {
​
    //继承了BaseMapper所有的方法可以编写自己扩展方法
    @Autowired
    private UserMapper userMapper;
​
    @Test
    public void testSelect(){
        System.out.println("--------selectAll method test-------");
        //查询全部用户参数一个Wrapper,条件构造器,先不使用null
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
    }

提示

UserMapper中的selectList()方法的参数为MP内置的条件封装器Wrapper,所以不填写就是无任何条件

控制台输出

User(id=1, name=Jone, age=18, email=test1@baomidou.com) User(id=2, name=Jack, age=20, email=test2@baomidou.com) User(id=3, name=Tom, age=28, email=test3@baomidou.com) User(id=4, name=Sandy, age=21, email=test4@baomidou.com) User(id=5, name=Billie, age=24, email=test5@baomidou.com)

2.9、小结

以上几个步骤就已经实现User表的CRUD功能,甚至连XML文件都不用编写,以上步骤可以看出集成MyBatis-Plus非常的简单,只需要引入starter工程,并配置mapper扫描路径即可。方法都是MyBatis-Plus写好的,直接引用即可

三、配置日志

所有的SQL都是不可见的,所以在后台是希望看到SQL是怎么执行的,就必须要配置日志

在.yml配置文件中配置日志:

#配置日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

四、CRUD

4.1、插入测试

//测试插入
@Test
public void testInsert(){
    User user = new User();
    user.setName("小文");
    user.setAge(21);
    user.setEmail("2312103645@qq.com");
​
    int insert = userMapper.insert(user);//如果没有设置id,那么会自动生成id
    System.out.println(insert);//受影响行数
    System.out.println(user);//id会自动回填
}

 

数据库插入ID默认值全局唯一ID

4.2、自定义ID生成器

复杂分布式系统中,往往需要大量的数据消息进行唯一标识比如支付宝一个账号数据库分表后都需要一个唯一ID做标识。此时一个能够生成全局唯一ID的系统是非常必要的。

所以,生成的ID需要具备一下特点:

  1. 全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求。

  2. 趋势递增:在MySQL InnoDB引擎使用的是聚集索引,由于多数RDBMS使用B-tree数据结构存储索引数据,在主键选择上面我们应该尽量使用有序主键保证写入性能

  3. 单调递增:保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息排序特殊需求

  4. 信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要ID无规则、不规则

上述123对应三类不同的场景,3和4需求还是互斥的,无法使用同一个方案满足。

这里只讲两种自动生成ID的方案UUID和SnowFlake

可以查看哪些方法,查看源码

用户ID上添加@TableId注解里面的值便是使用主键自动生成的方法

自 3.3.0 开始,默认使用雪花算法+UUID(不含中划线)

@Data
public class User {
    //对应数据库中的主键(UUID、自增id、雪花算法rediszookeeper)
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

点击 IdType查看源码看有哪些自动生成方法

/**
 * 生成ID类型枚举类
 *
 * @author hubin
 * @since 2015-11-10
 */
@Getter
public enum IdType {
    /**
     * 数据库ID自增
     * <p>该类型请确保数据库设置了 ID自增 否则无效</p>
     */
    AUTO(0),
    /**
     * 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
     */
    NONE(1),
    /**
     * 用户输入ID
     * <p>该类型可以通过自己注册自动填充插件进行填充</p>
     */
    INPUT(2),
​
    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    /**
     * 分配ID (主键类型为numberstring),
     * 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花算法)
     *
     * @since 3.3.0
     */
    ASSIGN_ID(3),
    /**
     * 分配UUID (主键类型为 string)
     * 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-",""))
     */
    ASSIGN_UUID(4);
​
    private final int key;
​
    IdType(int key) {
        this.key = key;
    }
}   

4.2.1、UUID

UUID(Universally Unique Identifier)的标准型包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符示例550e8400-e29b-41d4-a716-446655440000,到目前为止业界一共有5种方式生成UUID,详情见IETF发布的UUID规范 A Universally Unique IDentifier (UUID) URN Namespace

优点:

缺点:

4.2.2、SnowFlake(雪花算法

这种方案大致来说是一种以划分命名空间(UUID也算,由于比较常见,所以单独分析)来生成ID的一种算法,这种方案把64-bit分别划分成多段,分开来标示机器时间等,比如在snowflake中的64-bit分别表示下图图片来自网络所示

41-bit时间可以表示(1L<<41)/(1000L360024*365)=69年的时间,10-bit机器可以分别表示1024台机器。如果我们对IDC划分需求,还可以将10-bit分5-bit给IDC,分5-bit给工作机器。这样就可以表示32个IDC,每个IDC下可以有32台机器,可以根据自身需求定义。12个自增序列号可以表示2^12个ID,理论上snowflake方案的QPS约为409.6w/s,这种分配方式可以保证在任何一个IDC的任何一台机器任意毫秒内生成的ID都是不同的。

核心思想:

使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096个ID),最后还有一个符号位,永远是0,。

优点:

缺点:

4.3、更新操作

所有的SQL都是自动配置的

//测试更新
@Test
public void testUpdate(){
    User user = new User();
    //可以通过条件自动拼接动态SQL
    user.setId(5L);
    user.setName("id:5,修改过后");
    //updateById 参数是一个对象!
    int i = userMapper.updateById(user);
    System.out.println(i);
}

注意:updateById 参数是一个对象!而不是ID

 

五、自动填充

5.1、什么是自动填充

在常用业务中有些属性需要配置一些默认值,MyBatis-Plus提供了实现此功能的插件,也就是自动填充功能。比如创建时间修改时间这些操作一般都是自动化完成的,是不用去手动更新的。

5.2、自动填充方式

方式一:数据级别(不建议使用)

1、在表中新增字段create_time,update_time

注意:在create_time里除了没有勾选根据当前时间更新外其他步骤都一样!

2、在此测试插入方法,需要实体同步!!

private Data createTime;
private Data updateTime;

3、在此更新查看

//测试更新
@Test
public void testUpdate(){
    User user = new User();
    //可以通过条件自动拼接动态SQL
    user.setId(5l);
    user.setName("id:5,修改过后");
    user.setAge(25);
    //updateById 参数是一个对象!
    int i = userMapper.updateById(user);
    System.out.println(i);
}

4、查看时间是否更新

方式二:代码级别 

1、删除数据库的默认值更新操作

2、注解填充字段 @TableField(.. fill = FieldFill.INSERT) 生成器策略部分也可以配置!

//注解填充字段 @TableField(.. fill = FieldFill.INSERT) 生成器策略部分也可以配置!
@TableField(fill = FieldFill.INSERT)
private Data createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Data updateTime;

3、自定义实现类 MyMetaObjectHandler 处理这个注解

@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start intsert fill ....");
        //strictInsertFill(MetaObject metaObject, String fieldName, Class<T> fieldType, E fieldVal)
        this.strictInsertFill(metaObject,"createTime", LocalDateTime.class,LocalDateTime.now());// 起始版本 3.3.0(推荐使用)
    }
​
    //更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
    }
}

六、乐观锁和悲观

6.1、什么乐观

乐观锁:十分乐观,认为不会出现问题,无论干什么都不会去上锁,如果出现问题,就再次更新测试值

乐观锁是对于数据冲突保持一种乐观态度,操作数据时不会对操作的数据进行加锁(这使得多个任务可以并行的对数据进行操作),只有到数据提交的时候才通过一种机制来验证数据是否存在冲突(一般实现方式是通过加版本号然后进行版本号的对比方式实现);

特点:乐观锁是一种并发类型的锁,其本身不对数据进行加锁而是通过业务实现锁的功能,不对数据进行加锁就意味着允许多个请求同时访问数据,同时也省掉了对数据加锁解锁过程,这种方式因为节省悲观加锁的操作,所以可以一定程度的的提高操作的性能,不过在并发非常高的情况下,会导致大量的请求冲突冲突导致大部分操作无功而返而浪费资源,所以在高并发的场景下,乐观锁的性能却反而不如悲观锁。

6.2、什么是悲观锁

悲观锁:十分悲观,认为总是出现问题,无论干什么都会上锁,再去操作

悲观锁是基于一种悲观的态度类来防止一切数据冲突,它是以一种预防的姿态在修改数据之前把数据锁住然后再对数据进行读写,在它释放锁之前任何人都不能对其数据进行操作,直到前面个人把锁释放后下一个人数据加锁才可对数据进行加锁,然后才可以对数据进行操作,一般数据库本身锁的机制都是基于悲观锁的机制实现的;

特点:可以完全保证数据的独占性和正确性,因为每次请求都会先对数据进行加锁, 然后行数据操作,最后解锁,而加锁释放锁的过程会造成消耗,所以性能不高;

6.3、配置乐观锁

本文主要讲解乐观锁机制

乐观锁实现方式:

当要更新一条记录时,是希望这条记录没有被更新的

-- 乐观锁:1、先查询,获取版本号 version=1
-- A线程
update user name = "tian" ,version = version +1
where id = 2 and version = 1
-- 如果B线程抢先完成,这个时候version=2,就会导致A线程修改失败
-- B线程
update user name = "tian" ,version = version +1
where id = 2 and version = 1

测试MP的乐观锁插件

6.3.1、数据库中添加version字段

添加完成后查看是否更改完成

6.3.2、同步实体

记得在实体类上加上@Version注解

@Version    //乐观锁version注解
private Integer version;

6.3.3、配置插件

spring xml 方式:

<bean class="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor" id="optimisticLockerInnerInterceptor"/>
​
<bean id="mybatisPlusInterceptor" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
    <property name="interceptors">
        <list>
            <ref bean="optimisticLockerInnerInterceptor"/>
        </list>
    </property>
</bean>

这里讲解的是springboot的注解方式

spring boot 的注解方式

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}

首先创建配置类文件config,在该文件创建配置类MyBatisPlusConfig,该类需要添加三个注解:

@Configuration  //配置类
@MapperScan("com.wen.mybatis_plus.mapper")  //扫描mapper
@EnableTransactionManagement    //自动管理事务默认开启

@MapperScan()是将原先MybatisPlusApplication中的扫描换到这里的,所以MybatisPlusApplication中就不需要@MapperScan(),在该配置类里添加@MapperScan()即可

创建完MyBatisPlusConfig类并添加完注解后,就可以将上面的组件的注解方式填入进来

@Configuration  //配置类
@MapperScan("com.wen.mybatis_plus.mapper")  //扫描mapper
@EnableTransactionManagement
public class MyBatisPlusConfig {
    //注册乐观锁插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

此时乐观锁就已经配置完成了!

6.3.4、测试乐观锁

在测试类中分别对成功与失败进行测试

测试成功:

//测试成功的乐观锁
@Test
void testOptimisticLocker_success() {
    //1.查询用户信息
    User user = userMapper.selectById(1l);
    //2.修改用户信息
    user.setName("tian");
    user.setAge(21);
    //3.执行更新操作
    userMapper.updateById(user);
}

结果如下

测试失败

模拟多线程的方式执行插队操作

@Test
void testOptimisticLocker_failure() {
    //模拟多线程实现插队效果
    //线程1
    User user = userMapper.selectById(1l);
    user.setName("tian");
    user.setAge(21);
    //线程2
    User user2 = userMapper.selectById(1l);
    user2.setName("xiaotian");
    user2.setAge(19);
    userMapper.updateById(user2);   //在这里插队
​
    userMapper.updateById(user);    //如果没有乐观锁就会覆盖插队线程的值
}

查看控制台输出

从数据库看结果

七、增删改查

7.1、查询操作

1.通过Id查询用户

//测试查询
@Test
public void testSelectById(){
    User user = userMapper.selectById(1L);
    System.out.println(user);
}

结果

2.批量查询

//批量查询
@Test
public void selectBatchIds(){
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
    users.forEach(System.out::println);
}

批量查询通过selectBatchIds方法,方法内放入的是集合,可以通过源码

selectBatchIds方法源码:

/**
 * 查询(根据ID 批量查询)
 *
 * @param idList 主键ID列表(不能为 null 以及 empty)
 */
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

可以看到参数是Collection也就是集合这里使用的是Arrays集合

结果

3.条件查询

通过自定义条件查询

//条件查询
@Test
public void selectByMap(){
    HashMap<String,Object> map = new HashMap<>();
    //自定义查询
    map.put("name","小文");
    map.put("age",20);
    List<User> users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}

可以看出,map类的参数字段名参数)会被MySQLPlus自动组合成查询条件

 

7.2、分页查询

支持数据库:

属性介绍

属性 类型 默认值 描述
overflow boolean false 溢出总页数后是否进行处理(默认处理)
maxLimit Long 单页分页条数限制(默认限制)
dbType DbType 数据库类型(根据类型获取应使用的分页方言)
dialect IDialect 方言实现类

建议单一数据库类型的均设置 dbType

如何使用MyBatisPlus内页插件?

1、配置拦截器组件即可

/**
 * 注册插件
 */
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
​
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    // 添加分页插件
    PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor();
    // 设置请求的页面大于最大页后操作,true调回到首页false继续请求。默认false
    pageInterceptor.setOverflow(false);
    // 单页分页条数限制,默认无限制
    pageInterceptor.setMaxLimit(500L);
    // 设置数据库类型
    pageInterceptor.setDbType(DbType.MYSQL);
​
    interceptor.addInnerInterceptor(pageInterceptor);
    return interceptor;
}

2、分页组件测试

//测试MybatisPlus分页插件
@Test
public void testMybatisPlus_Page(){
    // 两个参数:current的值默认是1,从1开始,不是0。size是每一页条数。
    Page<User> page = new Page<>(1, 4);
    userMapper.selectPage(page,null);
    page.getRecords().forEach(System.out::println);
}

结果分析

查询第二页试试看

除此之外,Page 的方法还有很多比如:

//page的其他方法
System.out.println("当前页:" + page.getCurrent());
System.out.println("总页数:" + page.getPages());
System.out.println("记录数:" + page.getTotal());
System.out.println("是否有上一页:" + page.hasPrevious());
System.out.println("是否有下一页:" + page.hasNext());

结果

 

7.3、删除操作

跟查询操作相似,就不详细讲解,直接上代码

//测试删除
@Test
public void testDeleteById(){
    userMapper.deleteById(4L);
}
​
//批量删除
@Test
public void testDeleteBatchId(){
    userMapper.deleteBatchIds(Arrays.asList(1L,2L));
}
​
//通过map删除
@Test
public void testdeleteByMap(){
    Map<String, Object> map = new HashMap<>();
    map.put("name","xiaotian");
    userMapper.deleteByMap(map);
}

7.4、逻辑删除

物理删除:从数据库中直接删除

逻辑删除:在数据库中没有被删除,而是通过一个变量来让它失效deleted=0 ==》deleted=1

管理员可以查看被删除的记录,防止数据丢失,相当于回收站

测试:

1、在数据表中增加一deleted字段

2、同步实体类,在实体类上加上@TableLogic 注解

@TableLogic //逻辑删除
private Integer deleted;

3、配置application.yml文件

#配置日志
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

4、测试

这里直接使用之前的delete测试

//测试删除
@Test
public void testDeleteById(){
    userMapper.deleteById(4L);
}

查看日志输出可以看到,delete的语句以经发生了更改

实质上就是update(修改)语句,将deleted字段从1修改为0

  

5、对Id为4的用户进行查询

//测试查询
@Test
public void testSelectById(){
    User user = userMapper.selectById(4L);
    System.out.println(user);
}

查看日志输出可以看到,seletc的语句以经发生了更改

增加了deleted的判断语句,判断deleted是否为1,为1则能搜索,0则不能

 

6、小结

只对自动注入的SQL有效:

比如:

删除语句转化为:update user set deleted=1 where id = 1 and deleted=0

查找语句转化为:select id,name,deleted from user where deleted=0

注意事项

  • 逻辑删除是为了方便数据恢复保护数据本身价值等等的一种方案,但实际就是删除。

  • 如果你需要频繁查出来看就不应使用逻辑删除,而是以一个状态去表示。

八、执行SQL分析打印

输出 SQL 语句以及其执⾏时间建议开发测试时启⽤该功能,能快速揪出慢查询

注意:PerformanceInterceptor在3.2.0被移除了,如果想进⾏性能分析,⽤第三⽅的,官⽅这样写的“该插件 3.2.0 以上版本移除 推荐使⽤第三扩展 执⾏SQL分析打印 功能”。也就是p6spy

使用步骤

8.1、p6spy依赖引入

Maven:

<dependency>
  <groupId>p6spy</groupId>
  <artifactId>p6spy</artifactId>
  <version>最新版本</version> <!--这里用的是>3.9.1版本-->
</dependency>

8.2、application.yml配置

spring:
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:h2:mem:test
    ...

注意: driver-class-name 为 p6spy 提供的驱动类 url 前缀为 jdbc:p6spy 跟着冒号为对应数据库连接地址

实际配置为:

spring:
  datasource:
    username: root
    password: 123456
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql:///mybatis_plus?userUnicode=true&amp;characterEncoding=utf-8

 

8.3、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

8.4、测试

这里使用之前的分页查询来测试一下

//测试MybatisPlus分页插件
@Test
public void testMybatisPlus_Page(){
    // 两个参数:current的值默认是1,从1开始,不是0。size是每一页的条数。
    Page<User> page = new Page<>(2, 4);
    userMapper.selectPage(page,null);
    page.getRecords().forEach(System.out::println);
    //page的其他方法
    System.out.println("当前页:" + page.getCurrent());
    System.out.println("总页数:" + page.getPages());
    System.out.println("记录数:" + page.getTotal());
    System.out.println("是否有上一页:" + page.hasPrevious());
    System.out.println("是否有下一页:" + page.hasNext());
}

查看日志输出

 

因为在配置文件中设置了慢SQL的检查,为2s,所以这里的查询可以通过

但是只要超过了时长就会抛出异常

九、条件构造器

Wrapper,可以通过其构造复杂的SQL

注意:

1、耦合性高

2、传输wrapper相当于conroller用map接收值,后期维护极为困难

所以这里只是采取少量代码进行演示

9.1、代码演示

1、查询name、邮箱为空年龄大于等于20的用户

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

2、查询姓名为小文的用户

@Test
void WrapperTest2(){
    //查询姓名为小文的用户
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("name","小文");    //equals
    User user = userMapper.selectOne(wrapper); 
    System.out.println(user);
}

注意:

查询一个数据出现多个结果就使用List或map

3、查询年龄在19-23之间的用户

@Test
void WrapperTest3(){
    //查询年龄在19-23之间的用户
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.between("age", 19, 23);
    Long count = userMapper.selectCount(wrapper);//查询结果数
    System.out.println(count);
}

4、查询年龄在19-23之间的用户

@Test
void WrapperTest3(){
    //查询年龄在19-23之间的用户
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.between("age", 19, 23);
    Long count = userMapper.selectCount(wrapper);//查询结果数
    System.out.println(count);
}

 

这里的方法取值范围是左开右闭!

5、模糊查询

@Test
void WrapperTest4(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper
            .notLike("name","a")    //查询姓名中不包含a的用户
            .likeRight("email","t");   //左和右是代表%的位置 两边都要匹配则为%e%,这里是email以t开头的 t%
    List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
    maps.forEach(System.out::println);
}

 

6、联表查询

//联表查询
@Test
void WrapperTest5(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.inSql("id","select id from user where id < 4");
    List<Object> objects = userMapper.selectObjs(wrapper);
    objects.forEach(System.out::println);
}

 

7、通过ID进行排序

@Test
void WrapperTest6(){
    //通过ID进行排序
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.orderByAsc("id");   //通过id升序
    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

十、代码自动生成器

MybatisPlus看官方文档即可,这里讲一个Idea插件Easy Code代码生成

10.1、EasyCode

EasyCode是基于IntelliJ IDEA Ultimate版开发的一个代码生成插件,主要通过自定义模板基于velocity)来生成各种你想要的代码。通常用于生成Entity、Dao、Service、Controller。如果你动手能力强还可以用于生成HTML、JS、PHP等代码。理论上来说只要是与数据有关的代码都是可以生成的。

支持的数据库类型:

  1. MySQL

  2. SQL Server

  3. Oracle

  4. PostgreSQL

  5. Sqlite

  6. Sybase

  7. Derby

  8. DB2

  9. HSQLDB

  10. H2

当然支持的数据库类型也会随着Database Tool插件的更新同步更新。

10.2、功能

10.3、操作

1、安装EasyCode

2、建立数据库

这里就不再多说了,就用之前的数据库即可

3、在IDEA配置连接数据库

这里也不多说了,就是idea连接自己的数据库

4、使用EasyCode

对应字段右键,就可以看到多出一个EasyCode,点击然后选择生成

5、开始生成代码

勾选需要生成的代码,点击OK即可

6、效果图

这些就是自动生成的代码了,代码你成熟了,应该自己生成了<狗头>

原文地址:https://blog.csdn.net/m0_46313726/article/details/124187527

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_21670.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注