Mybatis Plus 详解 IService、BaseMapper、自动填充、分页查询功能

结构直接看目录

前言

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

SpringBoot使用

将以下内容引入pom.xml

XML 复制代码
      <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

以下内容可自选

XML 复制代码
spring:
    #配置数据源信息
    datasource:
    type: com.zaxxer.hikari.HikariDataSource
    #配置数据库连接信息
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost
    username: root
    password: root
 
#mybatisplus添加日志功能
mybatis-plus:
	configuration:
    	log-impl: org.apache.ibatis.logging.stdout.stdOutImpl
global-config:
	db-config:
    	#配置Mybatis-plus操作表的默认前缀
    	table-prefix: t_
    	#配置Mybatis-plus的主键策略
    	id-type: auto

配置文件注意事项

驱动类driver-class-name

spring boot 2.0(内置jdbc5驱动),驱动类使用:driver-class-name: com.mysql.jdbc.Driver

spring boot 2.1及以上(内置jdbc8驱动),驱动类使用:

driver-class-name: com.mysql.cj.jdbc.Driver

否则运行测试用例的时候会有 WARN 信息

连接地址url

MySQL5.7版本的url:

jdbc:mysql://localhost:3306/?characterEncoding=utf-8&useSSL=false

MySQL8.0版本的url:

jdbc:mysql://localhost:3306/?

serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false

注意事项

// 这个属性用于指定 MyBatis Mapper XML 文件的位置,例如:mybatis-plus: mapper-locations: classpath*:/mapper/*Mapper.xml

mybatis-plus.mapper-locations

// 这个属性用于设置是否显示 MyBatis-Plus 的启动 banner。在示例中,该属性被设置为 false,表示禁用启动 banner

mybatis-plus.global-config.banner

// 这个属性用于设置主键 ID 的生成策略。在示例中,auto 表示使用数据库自动生成的主键 ID

mybatis-plus.global-config.db-config.id-type:auto

// 这些属性用于设置全局的 SQL 过滤策略。在示例中,not_empty 表示只在参数值非空时才会生成对应的 SQL 条件

mybatis-plus.global-config.db-config.where-strategy:not_empty

mybatis-plus.global-config.db-config.insert-strategy:not_empty

mybatis-plus.global-config.db-config.update-strategy:not_null

// 这个属性用于设置在 SQL 中处理空值时使用的 JDBC 类型。在示例中,'null' 表示使用 NULL 类型

mybatis-plus.configuration.jdbc-type-for-null:'null'

// 这个属性用于设置是否在设置属性为 NULL 时调用对应的 setter 方法。在示例中,该属性被设置为 true,表示在设置属性为 NULL 时会调用 setter 方法

mybatis-plus.configuration.call-setters-on-nulls:true

引导类中添加 @MapperScan 注解,扫描 Mapper 文件夹

java 复制代码
@SpringBootApplication
@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
public class MPApplication {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

建立实体类

自行建立一个实体,可以是最简单的 学生,姓名,班级,学号

建立Mapper层

继承BaseMapper,后面的实体写自己的实体

java 复制代码
@Mapper
public interface UserMapper extends BaseMapper<UserEntity>{

}

建立Service层

建立Service接口
java 复制代码
public interface UserService extends IService<UserEntity> {}
建立Service接口实现类ServiceImpl
java 复制代码
	@Slf4j
	@Service
	public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements  
	UserService {}

Service Interface接口内容说明

插入功能save

java 复制代码
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

功能描述: 插入记录,根据实体对象的字段进行策略性插入。
返回值: boolean,表示插入操作是否成功。
参数说明:

类型 参数名 描述
T entity 实体对象
Collection<T> entityList 实体对象集合
int batchSize 插入批次数量
示例
java 复制代码
// 假设有一个 User 实体对象
User user = new User();
user.setName("John Doe");
user.setEmail("john.doe@example.com");
boolean result = userService.save(user); // 调用 save 方法
if (result) {
    System.out.println("User saved successfully.");
} else {
    System.out.println("Failed to save user.");
}
生成的 SQL:
sql 复制代码
INSERT INTO user (name, email) VALUES ('John Doe', 'john.doe@example.com')

如果存在就更新不存在就新增 saveOrUpdate

功能描述: 根据实体对象的主键 ID 进行判断,存在则更新记录,否则插入记录。
返回值: boolean,表示插入或更新操作是否成功。
参数说明:

类型 参数名 描述
T entity 实体对象
Wrapper<T> updateWrapper 实体对象封装操作类 UpdateWrapper
Collection<T> entityList 实体对象集合
int batchSize 插入批次数量
java 复制代码
// TableId 注解属性值存在则更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
示例
java 复制代码
// 假设有一个 User 实体对象,其中 id 是 TableId 注解的属性
User user = new User();
user.setId(1);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
boolean result = userService.saveOrUpdate(user); // 调用 saveOrUpdate 方法
if (result) {
    System.out.println("User updated or saved successfully.");
} else {
    System.out.println("Failed to update or save user.");
}
生成的 SQL(假设 id 为 1 的记录已存在):
sql 复制代码
UPDATE user SET name = 'John Doe', email = 'john.doe@example.com' WHERE id = 1
生成的 SQL(假设 id 为 1 的记录不存在):
sql 复制代码
INSERT INTO user (id, name, email) VALUES (1, 'John Doe', 'john.doe@example.com')

删除功能remove

java 复制代码
// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);

功能描述: 通过指定条件删除符合条件的记录。
返回值: boolean,表示删除操作是否成功。
参数说明:

类型 参数名 描述
Wrapper<T> queryWrapper 实体包装类 QueryWrapper
Serializable id 主键 ID
Map<String, Object> columnMap 表字段 map 对象
Collection<? extends Serializable> idList 主键 ID 列表
示例:
删除
java 复制代码
// 假设有一个 QueryWrapper 对象,设置删除条件为 name = 'John Doe'
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "John Doe");
boolean result = userService.remove(queryWrapper); // 调用 remove 方法
if (result) {
    System.out.println("Record deleted successfully.");
} else {
    System.out.println("Failed to delete record.");
}
生成的 SQL:
sql 复制代码
DELETE FROM user WHERE name = 'John Doe'
根据ID删除
java 复制代码
// 假设要删除 ID 为 1 的用户
boolean result = userService.removeById(1); // 调用 removeById 方法
if (result) {
    System.out.println("User deleted successfully.");
} else {
    System.out.println("Failed to delete user.");
}
生成的 SQL:
sql 复制代码
DELETE FROM user WHERE id = 1
批量删除
java 复制代码
// 假设有一组 ID 列表,批量删除用户
List<Integer> ids = Arrays.asList(1, 2, 3);
boolean result = userService.removeByIds(ids); // 调用 removeByIds 方法
if (result) {
    System.out.println("Users deleted successfully.");
} else {
    System.out.println("Failed to delete users.");
}
生成的 SQL:
sql 复制代码
DELETE FROM user WHERE id IN (1, 2, 3)

更新功能update

java 复制代码
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

功能描述: 通过指定条件更新符合条件的记录。
返回值: boolean,表示更新操作是否成功。
参数说明:

类型 参数名 描述
Wrapper<T> updateWrapper 实体对象封装操作类 UpdateWrapper
T entity 实体对象
Collection<T> entityList 实体对象集合
int batchSize 更新批次数量
根据元素进行更新
java 复制代码
// 假设有一个 UpdateWrapper 对象,设置更新条件为 name = 'John Doe',更新字段为 email
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "John Doe").set("email", "john.doe@newdomain.com");
boolean result = userService.update(updateWrapper); // 调用 update 方法
if (result) {
    System.out.println("Record updated successfully.");
} else {
    System.out.println("Failed to update record.");
}
生成的 SQL:
sql 复制代码
UPDATE user SET email = 'john.doe@newdomain.com' WHERE name = 'John Doe'
根据ID进行更新
java 复制代码
// 假设有一个 User 实体对象,设置更新字段为 email,根据 ID 更新
User updateEntity = new User();
updateEntity.setId(1);
updateEntity.setEmail("updated.email@example.com");
boolean result = userService.updateById(updateEntity); // 调用 updateById 方法
if (result) {
    System.out.println("Record updated successfully.");
} else {
    System.out.println("Failed to update record.");
}

生成的 SQL:

sql 复制代码
UPDATE user SET email = 'updated.email@example.com' WHERE id = 1

查询功能get

java 复制代码
// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

功能描述: 根据指定条件查询符合条件的记录。
返回值: 查询结果,可能是实体对象、Map 对象或其他类型。
参数说明:

类型 参数名 描述
Serializable id 主键 ID
Wrapper<T> queryWrapper 实体对象封装操作类 QueryWrapper
boolean throwEx 有多个 result 是否抛出异常
T entity 实体对象
Function<? super Object, V> mapper 转换函数
根据id进行查询
java 复制代码
// 假设要查询 ID 为 1 的用户
User user = userService.getById(1); // 调用 getById 方法
if (user != null) {
    System.out.println("User found: " + user);
} else {
    System.out.println("User not found.");
}
生成的 SQL:
sql 复制代码
SELECT * FROM user WHERE id = 1
根据对象进行查询
java 复制代码
// 假设有一个 QueryWrapper 对象,设置查询条件为 name = 'John Doe'
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "John Doe");
User user = userService.getOne(queryWrapper); // 调用 getOne 方法
if (user != null) {
    System.out.println("User found: " + user);
} else {
    System.out.println("User not found.");
}
生成的SQL:
sql 复制代码
SELECT * FROM user WHERE name = 'John Doe' LIMIT 1

查询记录功能list

java 复制代码
// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

功能描述: 查询符合条件的记录。
返回值: 查询结果,可能是实体对象、Map 对象或其他类型。
参数说明:

类型 参数名 描述
Wrapper<T> queryWrapper 实体对象封装操作类 QueryWrapper
Collection<? extends Serializable> idList 主键 ID 列表
Map<String, Object> columnMap 表字段 map 对象
Function<? super Object, V> mapper 转换函数
示例:
查询全部
java 复制代码
// 查询所有用户
List<User> users = userService.list(); // 调用 list 方法
for (User user : users) {
    System.out.println("User: " + user);
}
生成的SQL:
sql 复制代码
SELECT * FROM user
根据实体进行查询
java 复制代码
// 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
List<User> users = userService.list(queryWrapper); // 调用 list 方法
for (User user : users) {
    System.out.println("User: " + user);
}
生成的SQL:
sql 复制代码
SELECT * FROM user WHERE age > 25
批量查询用户
java 复制代码
// 假设有一组 ID 列表,批量查询用户
List<Integer> ids = Arrays.asList(1, 2, 3);
Collection<User> users = userService.listByIds(ids); // 调用 listByIds 方法
for (User user : users) {
    System.out.println("User: " + user);
}

生成的SQL:

sql 复制代码
SELECT * FROM user WHERE id IN (1, 2, 3)
分页查询
java 复制代码
// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

功能描述: 分页查询符合条件的记录。
返回值: 分页查询结果,包含记录列表和总记录数。
参数说明:

类型 参数名 描述
IPage<T> page 翻页对象
Wrapper<T> queryWrapper 实体对象封装操作类 QueryWrapper
示例
分页查询
java 复制代码
// 假设要进行无条件的分页查询,每页显示10条记录,查询第1页
IPage<User> page = new Page<>(1, 10);
IPage<User> userPage = userService.page(page); // 调用 page 方法
List<User> userList = userPage.getRecords();
long total = userPage.getTotal();
System.out.println("Total users: " + total);
for (User user : userList) {
    System.out.println("User: " + user);
}
生成的SQL:
sql 复制代码
SELECT * FROM user LIMIT 10 OFFSET 0
相关推荐
小江的记录本9 小时前
【Spring Boot】Spring Boot 全体系知识结构化拆解(附 Spring Boot 高频面试八股文精简版)
java·spring boot·后端·spring·面试·tomcat·mybatis
Thomas.Sir10 小时前
从底层源码深入剖析 MyBatis 工作原理
java·架构·mybatis
eggwyw10 小时前
Spring 中使用Mybatis,超详细
spring·tomcat·mybatis
guestsun13 小时前
SpringBoot七大事务失效场景分析
java·spring boot·mybatis
计算机学姐1 天前
基于SpringBoot的校园二手书籍交易系统【个性化推荐+数据可视化统计+我买到的+我卖出的】
vue.js·spring boot·后端·mysql·信息可视化·intellij-idea·mybatis
zjneymar1 天前
Mybatis的动态sql
java·sql·mybatis
稻草猫.1 天前
MyBatis-Plus高效开发全攻略
java·数据库·后端·spring·java-ee·mybatis·mybatis-plus
计算机学姐1 天前
基于SpringBoot的网吧管理系统
java·spring boot·后端·spring·tomcat·intellij-idea·mybatis
弹简特1 天前
【JavaEE20-后端部分】 MyBatis 入门第四篇:多表查询、#{}与${}详解、数据库连接池
数据库·mybatis
哆啦A梦15882 天前
Springboot整合MyBatis实现数据库操作
数据库·spring boot·mybatis