MyBatisPlus学习笔记

Posted 康小庄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatisPlus学习笔记相关的知识,希望对你有一定的参考价值。

MyBatisPlus学习笔记

简介

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

愿景

我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

官网:MyBatis-Plus (baomidou.com)

文档:简介 | MyBatis-Plus (baomidou.com)

源码:baomidou/mybatis-plus

框架结构

快速使用

创建项目步骤不再赘述,此文章是快速上手MP,其余步骤自行搜索!!

开发环境

JDK:jdk1.8

IDE:IntelliJ IDEA 2020.2.3 x64

Maven:apache-maven-3.6.3

MYSQL:mysql5.5

引入mybatis-plus相关maven依赖

		<!--mybatis-plus依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.4.2</version>
        </dependency>

引入mybatis-plus在spring boot中的场景启动器

		<!--SpringBoot启动器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>

ps:切记不可再在pom.xml文件中引入mybatis与mybatis-spring的maven依赖,这一点,mybatis-plus的官方文档中已经
说明的很清楚了

项目中其他需要导入依赖

		<!--mysql数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
		 <!--Druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.3</version>
        </dependency>

创建表SQL语句

CREATE DATABASE mp;

USE mp;

CREATE TABLE tbl_employee(
   id INT(11) PRIMARY KEY AUTO_INCREMENT,
   last_name VARCHAR(50),
   email VARCHAR(50),
   gender CHAR(1),
   age INT
);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom','tom@atguigu.com',1,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Jerry','jerry@atguigu.com',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','black@atguigu.com',1,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','white@atguigu.com',0,35);

SELECT  * FROM tbl_employee;

项目结构一览

项目配置

配置MapperScan注解

application.properties配置

#mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#mybatis-plus查看SQL语句
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

创建Entity(Pojo)实体

src/main/java/com/zhuang/pojo

使用lombok插件简化代码

package com.zhuang.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.stereotype.Component;

/**
 * @Classname Employee
 * @Description 实体类
 * @Date 2021/10/23 8:49
 * @Author by zhuang
 */
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@TableName("tbl_employee")
public class Employee {
    /**
     * TableId 注解对应数据库字段,防止识别失败
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @TableField(value = "last_name")
    private String lastName;
    @TableField(value = "email")
    private String email;
    @TableField(value = "gender")
    private Integer gender;
    @TableField(value = "age")
    private Integer age;
}

创建接口

注意注解要加!

package com.zhuang.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhuang.pojo.Employee;
import org.springframework.stereotype.Repository;

/**
 * @Classname EmployeeMapper
 * @Description Mapper接口
 * @Date 2021/10/23 8:51
 * @Author by dell
 */
@Repository
public interface EmployeeMapper extends BaseMapper<Employee> {

}

普通的CRUD操作

直接看代码!

package com.zhuang.mybatisplus;

import com.zhuang.mapper.EmployeeMapper;
import com.zhuang.pojo.Employee;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

@SpringBootTest
class MybatisPlusApplicationTests {

    @Autowired
    private EmployeeMapper employeeMapper;


    /**
     * 插入一条数据的测试
     */
    @Test
    public void insert() {
        int result = employeeMapper.insert(new Employee(null, "zhuangkang", "123@qq.com", 0, 18));
        System.out.println(result);
    }

    /**
     * 通过Id修改数据
     */
    @Test
    public void updateById() {
        // 先查询
        Employee employee = employeeMapper.selectById(1);
        employee.setLastName("123zk");
        // 再执行修改
        int result = employeeMapper.updateById(employee);
        System.out.println(result);
    }

    /**
     * 查询id为1的员工信息
     */
    @Test
    public void queryById() {
        Employee employee = employeeMapper.selectById(1);
        System.out.println(employee);
    }

    /**
     * 查询性别为男性(0)且年龄在25岁的员工信息
     */
    @Test
    public void selectByIdMap() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("gender", 0);
        map.put("age", 25);
        List<Employee> employees = employeeMapper.selectByMap(map);
        employees.forEach(System.out::println);
    }

    /**
     * 查询id分别为1、2、3的员工的信息
     */
    @Test
    public void queryBatch() {
        List<Employee> employees = employeeMapper.selectBatchIds(Arrays.asList(1, 2, 3));
        employees.forEach(System.out::println);
    }


    /**
     * 删除id为1的员工信息
     */
    @Test
    public void deleteById() {
        int result = employeeMapper.deleteById(1);
        System.out.println(result);
    }

    /**
     * 删除性别为男性(0)且年龄在25岁的员工信息
     */
    @Test
    public void deleteByMap() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("gender", 0);
        map.put("age", 25);
        int result = employeeMapper.deleteByMap(map);
        System.out.println(result);
    }

    /**
     * 删除id分别为3、8、9的员工的信息
     */
    @Test
    public void deleteBatch() {
        int result = employeeMapper.deleteBatchIds(Arrays.asList(3, 8, 9));
        System.out.println(result);
    }
}

注意

有时候IDEA会抽风,识别不到Mapper,出现下列情况可以忽略

注解

这里只介绍常用的,具体可去官方文档查询 注解 | MyBatis-Plus (baomidou.com)

👉 mybatis-plus-annotation

#@TableName(opens new window)

  • 描述:表名注解
属性类型必须指定默认值描述
valueString“”表名
schemaString“”schema
keepGlobalPrefixbooleanfalse是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值)
resultMapString“”xml 中 resultMap 的 id
autoResultMapbooleanfalse是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)
excludePropertyString[]{}需要排除的属性名(@since 3.3.1)

@TableId(opens new window)

  • 描述:主键注解
属性类型必须指定默认值描述
valueString“”主键字段名
typeEnumIdType.NONE主键类型

#IdType(opens new window)

描述
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方法)
ID_WORKER分布式全局唯一ID 长整型类型(please use ASSIGN_ID)
UUID32位UUID字符串(please use ASSIGN_UUID)
ID_WORKER_STR分布式全局唯一ID 字符串类型(please use ASSIGN_ID)

#@TableField(opens new window)

  • 描述:字段注解(非主键)
属性类型必须指定默认值描述
valueString“”数据库字段名
elString“”映射为原生 #{ ... } 逻辑,相当于写在 xml 里的 #{ ... } 部分
existbooleantrue是否为数据库表字段
conditionString“”字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s},参考(opens new window)
updateString“”字段 update set 部分注入, 例如:update="%s+1":表示更新时会set version=version+1(该属性优先级高于 el 属性)
insertStrategyEnumNDEFAULT举例:NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)
updateStrategyEnumNDEFAULT举例:IGNORED: update table_a set column=#{columnProperty}
whereStrategyEnumNDEFAULT举例:NOT_EMPTY: where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
fillEnumFieldFill.DEFAULT字段自动填充策略
selectbooleantrue是否进行 select 查询
keepGlobalFormatbooleanfalse是否保持使用全局的 format 进行处理
jdbcTypeJdbcTypeJdbcType.UNDEFINEDJDBC类型 (该默认值不代表会按照该值生效)
typeHandlerClass<? extends TypeHandler>UnknownTypeHandler.class类型处理器 (该默认值不代表会按照该值生效)
numericScaleString“”指定小数点后保留的位数

@TableLogic(opens new window)

  • 描述:表字段逻辑处理注解(逻辑删除)
属性类型必须指定默认值描述
valueString“”逻辑未删除值
delvalString“”逻辑删除值

@OrderBy(opens new window)

  • 描述:内置 SQL 默认指定排序,优先级低于 wrapper 条件查询
属性类型必须指定默认值描述
isDescboolean是否倒序查询
sortshortShort.MAX_VALUE数字越小越靠前

MyBatisPlus的条件构造器

构造器是个很强大的东西,简化开发很多,通过 EntityWrapper(简称 EW,MP 封装的一个查询条件构造器)或者 Condition(与 EW 类似) 来让用户自由的构建查询条件,简单便捷,没有额外的负担, 能够有效提高开发效率,它主要用于处理 sql 拼接,排序,实体参数查询。

注意:使用的是数据库字段,不是 Java 属性!

警告:MyBatis-Plus不支持以及不赞成在 RPC 调用中把 Wrapper 进行传输,Wrapper 很重,传输 Wrapper 可以类比为你的 controller 用 map 接收值(开发一时爽,维护火葬场),正确的 RPC 调用姿势是写一个 DTO 进行传输,被调用方再根据 DTO 执行相应的操作

说明:

  • 以下出现的第一个入参boolean condition表示该条件是否加入最后生成的sql中,例如:query.like(StringUtils.isNotBlank(name), Entity::getName, name) .eq(age!=null && age >= 0, Entity::getAge, age)
  • 以下代码块内的多个方法均为从上往下补全个别boolean类型的入参,默认为true
  • 以下出现的泛型Param均为Wrapper的子类实例(均具有AbstractWrapper的所有方法)
  • 以下方法在入参中出现的R为泛型,在普通wrapper中是String,在LambdaWrapper中是函数(例:Entity::getId,Entity为实体类,getId为字段idgetMethod)
  • 以下方法入参中的R column均表示数据库字段,当R具体类型为String时则为数据库字段名(字段名是数据库关键字的自己用转义符包裹!)!而不是实体类数据字段名!!!,另当R具体类型为SFunction时项目runtime不支持eclipse自家的编译器!!!
  • 以下举例均为使用普通wrapper,入参为MapList的均以json形式表现!
  • 使用中如果入参的Map或者List,则不会加入最后生成的sql中!!!

Warrper结构

常用方法

只介绍常用的,具体请跳转👉条件构造器 | MyBatis-Plus (baomidou.com)

	/**
     * 查询员工年龄小于30
     */
    @Test
    public void queryForList() {
        QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("age", 30);
        List<Employee> employees = employeeMapper.selectList(queryWrapper);
        employees.forEach(System.out::println);
    }

    /**
     * 查询所有员工信息
     */
    @Test
    public void queryAll() {
        QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
        List<Employee> employees = empl

以上是关于MyBatisPlus学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记:python3,代码片段(2017)

MyBatis­Plus快速入门源码笔记共享,拿走吧你

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段

MyBatis Plus学习笔记

基于Springboot+MybatisPlus的外卖项目瑞吉外卖Day3

mybaits-plus学习笔记整合