mybatis-plus
(简化代码神器)
地址:https://mp.baomidou.com/
目录
简介
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
支持数据库
- mysql 、 mariaDB 、 oracle 、 db2 、 h2 、 hsql 、 DuckDB、 Derby、 Phoenix
- 神州通用、虚谷、优炫
提示
任何能使用 MyBatis 进行增删改查,并且支持标准 SQL 的数据库应该都在 MyBatis-Plus 的支持范围内,具体支持情况如上。
如果您想要的数据库类型不在上面的列表,欢迎给我们 PR 您的数据库方言。
参与贡献
欢迎各路好汉一起来参与完善 MyBatis-Plus,我们期待你的 PR!
- 贡献代码:代码地址 MyBatis-Plus ,欢迎提交 Issue 或者 Pull Requests
- 维护文档:文档地址 MyBatis-Plus-Doc ,欢迎参与翻译和修订
- 授权说明:MyBatis-Plus LOGO 官方授权沟通邮件
快速指南
我们将通过一个简单的项目来阐述 MyBatis-Plus的强大功能,在此之前,您需要先了解以下几点:
- 拥有 Java 开发环境以及相应 IDE
- 熟悉 Spring Boot
- 熟悉 Maven
使用第三方组件:
1、导入对应的依赖
2、代码如何编写
步骤
1、创建数据库 mybatis_plus
现有一张 User
表,其表结构如下:
id | name | age | |
1 | 小李 | 18 | admin1@baomidou.com |
2 | 小陈 | 20 | admin2@baomidou.com |
3 | 小徐 | 28 | admin3@baomidou.com |
4 | 小贾 | 21 | admin4@baomidou.com |
5 | 小张 | 24 | admin5@baomidou.com |
其对应的数据库 sql 脚本如下:
CREATE DATABASE IF NOT EXISTS `mybatis_plus`
USE `mybatis_plus`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` BIGINT NOT NULL COMMENT '主键ID',
`name` VARCHAR(30) DEFAULT NULL COMMENT '姓名',
`age` INT DEFAULT NULL COMMENT '年龄',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
INSERT INTO `user`(`id`,`name`,`age`,`email`) VALUES
(1,'小李',18,'admin1@baomidou.com'),
(2,'小陈',20,'admin2@baomidou.com'),
(3,'小徐',28,'admin3@baomidou.com'),
(4,'小贾',21,'admin4@baomidou.com'),
(5,'小张',24,'admin5@baomidou.com');
2、导入相关的依赖
完整的pom文件,复制粘贴即可
<?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.7.17</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>8.0.26</version>
</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>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.1</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>
说明:我们使用mybatis-plus可以节省我们大量的代码,尽量不要同时导入mybatis和mybatis-plus!
3、创建对应的文件夹
pojo->mapper->service->controller
4、编写配置文件
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_plus?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=root
#连接数据库
mybatis-plus.type-aliases-package=com.example.demo.pojo
mybatis-plus.configuration.map-underscore-to-camel-case=false
mybatis-plus.mapper-locations=classpath:mapper/*.xml
mybatis-plus.configuration.auto-mapping-behavior=full
#mybatis相关的配置
5、编写代码
5.1、User实体类
package com.example.demo.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author author
* @since 2024-12-15
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 邮箱
*/
private String email;
}
5.2、mapper层
package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.pojo.User;
/**
* <p>
* Mapper 接口
* </p>
*
* @author author
* @since 2024-12-15
*/
//在对应的Mapper上继承基本的类baseMapper
public interface UserMapper extends BaseMapper<User> {
//所有的CRUD已经编写完成
//不需要像以前的配置一些xml
}
此时编写完这两个之后就可以开始进行测试了,至于之前的mapper.xml文件现在无需进行编写
5.3、测试类扫描mapper层
package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.example.demo.mapper")
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
6、测试
package com.example.demo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.pojo.User;
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 DemoApplicationTests {
@Autowired
UserMapper userMapper;
@Test
void contextLoads() {
List<User> users = userMapper.selectList(null);
for (User user : users) {
System.out.println(user.toString());
}
}
}
直接在测试类中编写以上代码,selectList中为null原因是需要传入一个QueryWrapper条件管理的对象
而传入一个null值表示不需要任何条件,所以是全查
此时控制台就会将所有的数据都输出
完整的代码示例请移步:Spring Boot 快速启动示例 [Spring MVC 快速启动示例]
7、总结
通过以上几个简单的步骤,我们就实现了 User 表的查找功能,甚至连 XML 文件都不用编写!
从以上步骤中,我们可以看到集成MyBatis-Plus非常的简单,只需要引入 starter 工程,并配置 mapper 扫描路径即可。但 MyBatis-Plus 的强大远不止这些功能,想要详细了解 MyBatis-Plus 的强大功能?那就继续往下看吧!
配置日志
在application.xml文件中写入这句代码
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
常用注解
@TableName("表名")
当表名与实体类名不一致时,可以在实体类上加入@TableName()声明
@TableId
声明属性为表中的主键(若属性名称不为默认id)
@TableFieId("字段")
当实体类属性与表字段不一致时,可以用来声明
@TableName("表名")
public class User{
@TableId
private Long userId;
@TableFieId("name")
private String realName
}
新增数据
我们需要配置主键自增
1、实体类字段上 @TableId(type =IdType.AUTO)
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
编写一个Test测试类
@Test
public void insert(){
User user = new User();
user.setName("小明");
user.setAge(18);
user.setEmail("admin1@baomidou.com");
userMapper.insert(user);
}
这边也是同样直接调用自带的insert方法,插入完后执行selectList方法查看是否成功
此时可以看到,确实多了一条数据,并且就是刚刚插入的数据
修改数据
@Test
public void update(){
User user = new User();
user.setName("小明");
user.setAge(18);
user.setEmail("admin6@baomidou.com");
user.setId(6L);
userMapper.updateById(user);
}
修改数据时需要传入一个id,而调用的方法也需要使用updateById的方法,并且是根据在实体类中设置的主键来判断的,所以说实体类的注解很关键(如果我们设置了其他的位主键,那么就会根据其他的来进行修改)
执行完毕后,使用selectList再次查询,查看是否成功修改,
数据已成功修改!!!!
删除数据
这边为我们提供了很多的删除方法,而我们用的最多的也就是第二种deleteById(单个删除)
也是非常简单,只需要添加一条代码就可以了
@Test
public void delete(){
userMapper.deleteById(6);
}
里面的值也就是我们需要删除的数的id,我们现在把刚刚添加的删除
执行方法后,再次使用selectList方法查询
可以看到,已经成功删除
条件操作
上面的增删查改操作都仅仅是很普通的操作,那么现在我们对操作进行优化,可以有更加高级的操作
1、QueryWrapper
在查询中,上方展示的是全查,现在展示带条件的查询
并且以下的方法可以使用多个,表示同时带多个条件
1.1、eq
表示等于查询,在数据库中表示 “=”
@Test
void contextLoads() {
QueryWrapper<User> qw=new QueryWrapper<>();
qw.eq("name","小李");
List<User> users = userMapper.selectList(qw);
for (User user : users) {
System.out.println(user.toString());
}
}
这段代码就可以实现查询为name的列,name列里面是小李的
这样查询结果就是name为小李的一行
1.2、like
在数据库中表示 “like”,也就是模糊查询
@Test
void contextLoads() {
QueryWrapper<User> qw=new QueryWrapper<>();
qw.like("name","小");
List<User> users = userMapper.selectList(qw);
for (User user : users) {
System.out.println(user.toString());
}
}
这样就可以将name中包含 “小” 的每一行都输出
执行方法后,可以看到确实将每一条name中包含了 “小” 的都输出了
1.3、ge
与gt相似,此代码表示在数据库中,age列大于等于19的都会输出
此时只输出了四条,因为有一条的age是小于19的,所以不会输出
1.4、lt
表示小于,在age这个列中小于19的都会输出
@Test
void contextLoads() {
QueryWrapper<User> qw=new QueryWrapper<>();
qw.lt("age","19");
List<User> users = userMapper.selectList(qw);
for (User user : users) {
System.out.println(user.toString());
}
}
此时只输出了age小于19的数据
1.5、gt
表示大于,在age这个列中大于19的都会输出
@Test
void contextLoads() {
QueryWrapper<User> qw=new QueryWrapper<>();
qw.gt("age","19");
List<User> users = userMapper.selectList(qw);
for (User user : users) {
System.out.println(user.toString());
}
}
此时只输出了age大于19的数据
方法太多这里表示不完,详细的请看官网
2、查询
selectList():根据qw类来当做参数,根据条件查询
selectBatchIds():可以有多个id,将多个id全查出来
selectById():单查,只能有一个id,查询一条数据
selectCount():查数量,将qw类的条件当做参数,根据条件查询,将数量查出来
selectByMap():传递一个Map集合,集合中的key是列名,value是值
selectMaps():传递一个qw类,再传递一个Map集合,将两个的条件一起结合
selectObjs():即使在查询中指定了多个字段,selectObjs
方法也只会返回查询结果中每个记录的第一个字段的值,结果以 List<Object>
的形式返回
selectOne():如果查询结果有多条数据,那么会抛出异常;如果没有数据,则返回 null
selectPage():分页查询使用,传递一个Ipage类,以及一个qw类
3、删除
delete():传递一个qw类,如果qw中没有任何条件,那么就会全部删除
deleteById():传递一个id,可以是字符串,也可以是数字等,根据在实体类中的主键来进行删除
deleteBatchIds():传递多个id,同样可以是字符串或数字等,表示同时删除多条数据
deleteByMap():传递一个Map集合,key表示列,value表示值,可以同时删除多个
4、修改
update中只有两个方法,也非常的简单
update():根据qw条件进行修改
updateById():传入一个实体类,直接根据实体类的信息进行修改,修改主键所在的列
5、新增
insert只有一个方法,也是无需多说
insert():传入一个实体类,直接增加实体中的信息
service层条件操作
刚刚所有的操作都是在mapper层实现的,所以说大多部分只有一些方法,而service层有更多的方法供我们使用
1、查询
在service层中,方法也与mapper层有所不同,这里的查询方法变成了list()
但是与之前的都基本相似,这里就不多介绍了,因为都差不多
2、删除
删除方法也有所不同,从delete变成了remove,并且都与mapper层相似,所以也不过多介绍了
3、新增
新增方法从insert变成了save,并且也比之前多了很多
saveBatch():一次性增加多条数据,批量新增
saveOrUpdate():这个在项目中使用最频繁,因为他只需要一个方法,就可以实现新增或修改,实现原理也很简单,传入一个实体类,如果有id,那么就是修改,如果没有id,那么就是新增
saveOrUpdateBatch():同样,有id则修改,无id则新增,可以批量操作
4、修改
修改的方法也很多,不过大多方法一看就知道什么意思,所以只介绍部分方法
updateBatchByid():批量修改,可以传入一个集合,里面都是实体类的信息
lambdaUpdate():使用 Lambda 表达式来描述要更新的实体类对象的字段和条件,从而实现更加简洁和类型安全的更新操作
总结
那么,mybatis-plus的使用就都介绍完了,是不是非常简便呢,这也就是mybatis-plus为什么要推出的原因,就是因为sql代码太难写了,所以使用了mybatis-plus就可以极大的简化我们的开发
如果想更深入的了解mybatis-plus可以前往官网查看:MyBatis-Plus 🚀 为简化开发而生 (baomidou.com)
制作不易,有问题可联系作者,或者直接在评论声明,作者看到会第一时间解决