MybatisPlus

简介

官网 :https://baomidou.com/

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 操作智能分析阻断,也可自定义拦截规则,预防误操作

支持的数据库

MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,

OceanBase,Firebird,Cubrid,Goldilocks,csiidb

快速开始

数据库数据

# 创建 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)
);

# 向表中添加数据
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');

创建项目

创建一个 springboot 项目或 maven-quickstart 项目

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.1.RELEASE</version>
</parent>
<!--web依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--MySQL连接数据库-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.25</version>
</dependency>
<!--MyBatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

配置数据库连接

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=admin

创建实体

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

创建持久层接口(Mapper)

package com.hkp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hkp.entity.User;

//继承 BaseMapper 类 ,参数是实体类 ;里面封装了 CRUD 方法
public interface UserMapper extends BaseMapper<User> {

}

启动类添加注解,扫描持久层包

@MapperScan("com.hkp.mapper")

测试

package com.hkp;

import com.hkp.entity.User;
import com.hkp.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
public class AppTest {

    @Resource
    private UserMapper userMapper;

    @Test
    public void selectAll(){
        //selectList() 方法的参数为 Mybatis-Plus 内置的条件封装器 Wrapper,所以不填写就是无任何条件
        List<User> userList = userMapper.selectList(null);
        //将所有用户循环输出
        userList.forEach(System.out::println);
    }
}

在这里插入图片描述

添加日志

添加日志,可以在控制台看到我们的SQL语句,有助于开发

修改 application.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=admin

#开启日志 ,使用 log4j 等其他的日志 需要导包,这里使用默认的日志; 将日志打印到控制台
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

启动测试方法

在这里插入图片描述

注解

@TableName

描述

表名注解,标识实体类对应的表名

使用位置

实体类

package com.hkp.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@TableName("sys_user")
@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

@TableId

描述

主键注解

使用位置

实体类主键字段

package com.hkp.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@TableName("sys_user")
@Data
public class User {
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

注解的属性

属性类型必须制定默认值描述
valueString“”主键字段名
typeEnumidType.NONE指定主键类型
idType 的值
描述
AUTO数据库 ID 自增
NONE无状态,该类型为未设置主键类型
INPUTinsert 前自行 set 主键值
ASSIGN_ID分配 ID ,主键类型为 :Number ( Long 和 Integer ) 或 String
ASSIGN_UUID分配 UUID ,主键类型为 :String

@TableField

描述

字段注解(非主键)

package com.hkp.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@TableName("sys_user")
@Data
public class User {
    @TableId
    private Long id;
    @TableField("username")
    private String name;
    private Integer age;
    private String email;
}

主要属性

属性类型是否必须默认值描述
valueString“”主要用于 实体中 和 数据表 中名称不一致
fillEnumFieldFill.DEFAULT可以设置字段的自动填充规则,默认是可变的
FieldFill 的值
描述
DEFAULT默认不处理
INSERT插入时填充字段
UPDATE更新时填充字段
INSERT_UPDATE插入和更新时填充字段

@Version

描述

乐观锁注解、标记

作用位置

字段上

@TableLogic

描述

表字段逻辑删除注解

属性

属性类型是否必须默认值描述
valueString“”逻辑未删除值
delvalString“”逻辑删除值

CRUD

新增

1、在测试接口中测试

@Test
public void insertUser(){
    User user=new User();
    user.setName("测试数据");
    user.setAge(12);
    user.setEmail("123456@qq.com");
    int insert = userMapper.insert(user);
    System.out.println(insert);
    System.out.println(user);
}

2、查看控制台日志效果

在这里插入图片描述

注意 :

可以看到,我并没有往实体中设置 id ,但是却自动加上了一个id

如果 主键 id 的类型为 Integer 默认的策略是 NONE

如果 主键id 的类型为 long 默认的策略是 ID_WORKER (雪花算法)

修改

1、在测试类中测试

@Test
public void updateUser(){
    User user=new User();
    user.setId(1310469473752416258L);
    user.setName("测试数据update");
    int i = userMapper.updateById(user);
    System.out.println(i);
}

2、查看效果

在这里插入图片描述

从结果的 SQL 语句中可以看出 这个 修改是动态的修改,也就是需要修改什么属性就传什么属性,不需要修改就不传,保持原来的数据

查询

根据 id 查询

1、测试代码

@Test
public void selectById(){
    User user = userMapper.selectById(1);
    System.out.println(user);
}

2、查看结果

在这里插入图片描述

根据多个 ID 查询

1、测试代码

@Test
public void selectByIds(){
    List<Integer> ids = new ArrayList<>();
    ids.add(1);
    ids.add(2);
    ids.add(3);
    List<User> users = userMapper.selectBatchIds(ids);
    users.forEach(System.out::println);
}

2、查看结果

在这里插入图片描述

多条件查询 Map

1、测试代码

@Test
public void selectByMap(){
    //注意map中的 key 值必须是数据库的字段名
    Map<String,Object> map=new HashMap<String,Object>();
    map.put("name","Tom");
    map.put("age",28);
    List<User> users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}

2、查看结果

在这里插入图片描述

分页查询

1、配置分页插件

// 低版本
@Configuration
public class MybatisConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

// 高版本
@Configuration
public class MybatisConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }
}

2、测试

@Test
public void SlectPage(){
    //page 中第一个参数表示第几页,第二个参数表示一页中有多少条数据
    Page<User> page=new Page<>(2,5);
    userMapper.selectPage(page,null);
    // 所有的结果都在 page 中 :查询出来的数据,总页数
    List<User> userList = page.getRecords();
    userList.forEach(System.out::println);
    // 每页共有多少条数据
    System.out.println(page.getSize());
    //数据总条数
    System.out.println(page.getTotal());
    //共有多少页
    System.out.println(page.getPages());
    //是否还有下一页
    System.out.println(page.hasNext());
    //是否有上一页
    System.out.println(page.hasPrevious());
}

3、查看效果

在这里插入图片描述

删除

根据 ID 删除

1、测试代码

@Test
public void deleteById(){
    int num = userMapper.deleteById(2);
    System.out.println(num);
}

2、查看效果

在这里插入图片描述

根据多个 ID 删除

1、测试代码

@Test
public void deleteByIds(){
    List<Integer> ids = new ArrayList<>();
    ids.add(4);
    ids.add(5);
    int num = userMapper.deleteBatchIds(ids);
    System.out.println(num);
}

2、查看效果

在这里插入图片描述

多条件删除 Map

1、测试代码

@Test
public void deleteByMap(){
    Map<String,Object> map = new HashMap<>();
    //注意map中的 key 值必须是数据库的字段名
    map.put("name","测试数据update");
    int num = userMapper.deleteByMap(map);
    System.out.println(num);
}

2、查看效果

在这里插入图片描述

逻辑删除

物理删除 :直接从数据库中删除了,数据永远没有了。

逻辑删除 :没有从数据库中删除,通过一个变量让他失效了。实际上执行的是一个 update 语句。

# 例如:
# 删除: 
update user set deleted=1 where id = 1 and deleted=0
# 查找: 
select id,name,deleted from user where deleted=0
实现步骤

1、在数据库中添加 变量 用来标记是否是逻辑删除 ,并给默认值为0

0 :逻辑未删除,1:逻辑已删除

在这里插入图片描述

2、在实体类中添加属性,并添加注解 @TableLogic

package com.hkp.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;

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

3、配置逻辑删除插件 ( 3.1.1 版本之后就不需要这个步骤了 )

@Configuration
public class MybatisConfig {
    @Bean
    public ISqlInjector sqlInjector(){
        return new LogicSqlInjector();
    }
}

4、配置 application.properties 文件

# 全局逻辑删除的实体字段名
mybatis-plus.global-config.db-config.logic-delete-field=deleted
# 逻辑已删除值(默认为1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# 逻辑未删除值(默认为0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0

执行 根据 id 删除语句,结果如下 :

在这里插入图片描述

执行根据 多个id 删除语句,结果如下 :

在这里插入图片描述

执行查询语句,结果如下 :

在这里插入图片描述

此时发现,查询的SQL 语句中加入了一个条件 where deleted=0

条件构造器 wrapper

更多知识去文档里学习 :

https://baomidou.com/pages/10c804/#abstractwrapper

like

语法 :

like(R column,Object val)

根据 姓名模糊查询

@Test
public void like(){
    //根据姓名模糊查询
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.like("name","j");
    List<User> users = userMapper.selectList(wrapper);
    //将所有用户循环输出
    users.forEach(System.out::println);
}

运行结果

在这里插入图片描述

根据姓名左边模糊查询 和 右边模糊查询

@Test
public void like2(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.likeLeft("name","a")
        .likeRight("name","j");
    List<User> users = userMapper.selectList(wrapper);
    //将所有用户循环输出
    users.forEach(System.out::println);
}

运行结果

在这里插入图片描述

between

between and 左右均包含

语法 :

between(R column, Object val1, Object val2)

查询年龄在 20-30 岁之间

@Test
public void between(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.between("age","12","28");
    List<User> users = userMapper.selectList(wrapper);
    //将所有用户循环输出
    users.forEach(System.out::println);
}

运行结果

在这里插入图片描述

isNotNull

语法 :

isNotNull(R column)

查询姓名不为空的用户

@Test
public void isNotNull(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.isNotNull("name");
    List<User> users = userMapper.selectList(wrapper);
    //将所有用户循环输出
    users.forEach(System.out::println);
}

运行结果 :

在这里插入图片描述

eq

语法 :

eq(R column, Object val)

查询姓名等于 tom 的用户

@Test
public void eq(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("name","tom");
    User user = userMapper.selectOne(wrapper);
    //将所有用户循环输出
    System.out.println(user);
}

运行结果 :

在这里插入图片描述

扩展

eq :等于

ne :不等于

ge

语法 :

ge(R column, Object val)

查询年龄大于等于28岁的用户

@Test
public void ge(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.ge("age",28);
    List<User> users = userMapper.selectList(wrapper);
    //将所有用户循环输出
    users.forEach(System.out::println);
}

运行结果

在这里插入图片描述

扩展

gt :大于

ge :大于等于

lt :小于

le :小于等于

orderByDesc

语法 :

orderByDesc(R... columns) // 多个字段用逗号隔开
orderByDesc("id", "name")--->order by id DESC,name DES

根据 id 降序排序

@Test
public void desc(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.orderByDesc("id");
    List<User> users = userMapper.selectList(wrapper);
    //将所有用户循环输出
    users.forEach(System.out::println);
}

运行结果

在这里插入图片描述

扩展

orderByAsc :升序

orderByDesc :降序

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值