一、项目初始化
1. 添加依赖
- 添加
mybatis-plus-boot-starter
依赖, 该依赖包包含:mybatis-plus
相关依赖mybatis
相关依赖freemarker
、thymeleaf
相关依赖
xml
<!-- START: mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.4.1</version>
</dependency>
<!-- END: mybatis-plus -->
2. 创建 Spring MVC 架构模型
- 新建
entity
模型层 - 新建
dao
数据访问层 - 新建
controller
视图控制层

3. 执行数据库脚本
现有一张 User 表,其表结构如下:
id | name | age | |
---|---|---|---|
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 |
其对应的数据库 Schema 脚本如下:
sql
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`
(
id BIGINT NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
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');
4. 配置
- 在 pom.xml 添加
MYSQL驱动依赖
xml
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
- 在
application.yml
配置文件中添加 MySQL 数据库的相关配置:
yaml
# 数据源配置
spring:
# 配置 MYSQL 连接
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/spring-boot-mybatis-plus?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: xxxxxx
- 在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:
java
package com.calvin.springboot.example.mybatis.plus;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 应用example02
*
* @author calvin
* @date 2024/01/24
*/
@SpringBootApplication
// @MapperScan 注解,扫描 Mapper
@MapperScan("com.calvin.springboot.example.mybatis.plus.dao")
public class AppExample02 {
public static void main(String[] args) {
SpringApplication.run(AppExample02.class, args);
}
}
5.编码
- 实体类
User.java
(此处使用了 Lombok (opens new window)简化代码)
java
package com.calvin.springboot.example.mybatis.plus.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 用户
*
* @author calvin
* @date 2024/01/24
*/
@Data
@TableName("`user`")
public class User {
/**
* id
*/
private Long id;
/**
* 名字。
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 电子邮件
*/
private String email;
}
- 编写
dao
包下的UserMapper
接口
java
/**
* 用户映射器
*
* @author Calvin
* @date 2024/1/24
* @since v1.0.0
*/
public interface UserMapper extends BaseMapper<User> {
}
- 新建
service
和impl
包, 编写IUserService
接口 和UserServiceImpl
实现类
java
/* `IUserService` 接口: 继承 IService<User> */
public interface IUserService extends IService<User> {
}
java
/* `UserServiceImpl` 接口实现类: 继承 ServiceImpl<UserMapper, User>, 实现 IUserService 接口 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}
- 编写
UserController
, 实现 CRUD 接口功能
java
/**
* 用户-控制器
*
* @author Calvin
* @date 2024/1/24
* @since v1.0.0
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
IUserService userService;
/**
* 创建
*
* @param user 用户
* @return {@link Boolean}
*/
@PostMapping("/create")
public Boolean create(@RequestBody User user) {
user.setId(null);
return userService.save(user);
}
/**
* 编辑
*
* @param user 用户
* @return {@link Boolean}
*/
@PutMapping("/edit")
public Boolean edit(@RequestBody User user) {
return userService.updateById(user);
}
/**
* 查询
*
* @param id id
* @return {@link User}
*/
@GetMapping("/find")
public User find(@RequestParam("id") Long id) {
return userService.getById(id);
}
/**
* 删除
*
* @param id id
* @return {@link Boolean}
*/
@DeleteMapping("/delete")
public Boolean delete(@RequestParam("id") Long id) {
return userService.removeById(id);
}
}
6. 视频演示
二、 通用 CRUD
1. 开启控制台日志
yaml
# MyBatis Plus 配置
mybatis-plus:
configuration:
# 控制台日志输出
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 日志配置
logging:
level:
# mybatis 日志级别为 INFO
mybatis: INFO
- 日志输出效果
log
JDBC Connection [HikariProxyConnection@1505454100 wrapping com.mysql.cj.jdbc.ConnectionImpl@2ca7eb54] will not be managed by Spring
==> Preparing: INSERT INTO `user` ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
==> Parameters: 1750042612175224834(Long), Calvin(String), 30(Integer), 1016280226@qq.com(String)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e461abb]
2. 插入操作
java
package com.calvin.spring.boot.example.mybatis.plus.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 用户
*
* @author calvin
* @date 2024/01/24
*/
@Data
@TableName("`user`")
public class User {
/**
* id ID自增
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 名字。
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 电子邮件
*/
private String email;
}
- 源码
IdType
描述
java
/*
* Copyright (c) 2011-2023, baomidou (jobob@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.mybatisplus.annotation;
import lombok.Getter;
/**
* 生成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),
/* 以下2种类型、只有当插入对象ID 为空,才自动填充。 */
/**
* 分配ID (主键类型为number或string),
* 默认实现类 {@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;
}
}
java
package com.calvin.spring.boot.example.mybatis.plus.entity;
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.Data;
/**
* 用户
*
* @author calvin
* @date 2024/01/24
*/
@Data
@TableName("`user`")
public class User {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 名字。
*/
private String name;
/**
* 年龄
*/
@TableField(value = "age") // 表示: 映射该字段名 和数据库表字段名(可以不一致,不一致需要编写数据库表字段名)
private Integer age;
/**
* 电子邮件
*/
@TableField(select = false) // 表示: select 语句不会拼接查询该字段
private String email;
/**
* 其他
*/
@TableField(exist = false) // 表示: 可以不存在数据库列中
private String other;
}
java
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(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);
3. 更新操作
java
// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
使用提示:
在调用 updateById 方法前,需要在 T entity(对应的实体类)中的主键属性上加上
@TableId注解
。 :::
4. 删除操作
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);
5. 查询操作
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);
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);
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);
6. 条件构造器
详细查看官方文档: https://baomidou.com/pages/10c804/#abstractwrapper
三、插件
- 如果不使用分页插件,mybatis plus 无法识别你是使用那种数据库的分页方式
- 新建一个
config
包, 在该包下创建MyBatisPlusConfiguration
。
java
package com.calvin.spring.boot.example.mybatis.plus.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Mybatis-Plus 配置
*
* @author calvin
* @date 2024/01/24
*/
@Configuration
@MapperScan("com.calvin.spring.boot.example.mybatis.plus.dao")
public class MybatisPlusConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 如果配置多个插件, 切记分页最后添加 (如果有多数据源可以不配具体类型 否则都建议配上具体的DbType)
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}