这里写自定义目录标题
- MyBatis-Plus 概述
- 快速入门
- 入门案例
- 常用注解
- 常见配置
MyBatis-Plus 概述
MyBatis-Plus 简介:
MyBatis-Plus 是在 MyBatis 基础上开发的一个 增强工具包,它简化了 MyBatis 的开发,减少了大量重复代码。它保持了 MyBatis 原有的特性(如灵活的 SQL),同时提供了很多开箱即用的功能。
官网定位是:
👉 只做增强,不做改变。
MyBatis-Plus 的优势:
- 无侵入:只需少量配置,几乎不改变原有项目结构。
- CRUD 自动化:内置了大量单表操作方法,几乎不用写 Mapper XML。
- 条件构造器:通过链式调用快速构造 SQL 条件。
- 分页插件:提供强大的分页功能。
- 代码生成器:自动生成 Entity、Mapper、Service、Controller 等代码。
- 多种内置功能:逻辑删除、自动填充、乐观锁、防全表更新与删除等。
核心功能:
-
通用 CRUD
只要继承
BaseMapper<T>
,就能使用大量内置方法:// 插入 int insert(T entity); // 根据 ID 删除 int deleteById(Serializable id); // 更新 int updateById(T entity); // 查询 T selectById(Serializable id); List<T> selectList(Wrapper<T> queryWrapper);
例如:
@Autowired private UserMapper userMapper;@Test public void testInsert() {User user = new User();user.setName("Tom");user.setAge(20);userMapper.insert(user); // 自动生成 SQL }
-
条件构造器
MyBatis-Plus 提供了
QueryWrapper
、LambdaQueryWrapper
等,简化条件拼接。// 传统写法 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("age", 20).like("name", "Tom"); List<User> list = userMapper.selectList(wrapper);// Lambda 写法(更安全,避免硬编码字段名) LambdaQueryWrapper<User> lambda = new LambdaQueryWrapper<>(); lambda.eq(User::getAge, 20).like(User::getName, "Tom"); List<User> list2 = userMapper.selectList(lambda);
-
分页插件
MyBatis-Plus 内置分页插件,只需简单配置:
IPage<User> page = new Page<>(1, 10); // 第1页,每页10条 IPage<User> result = userMapper.selectPage(page, null);
-
代码生成器
自动生成 实体类、Mapper、Service、Controller,极大提高开发效率。
-
常用扩展
-
逻辑删除:配置逻辑删除字段,删除操作会变成
UPDATE
。 -
自动填充:创建时间、更新时间自动填充。
-
乐观锁:防止并发修改数据冲突。
-
防全表更新删除:避免误操作导致数据丢失。
-
典型使用场景:
- 快速开发业务系统(如管理后台、信息系统),减少重复写 SQL。
- 单表操作频繁的场景(批量增删改查)。
- 结合 Spring Boot 使用,可以做到极简配置。
和 MyBatis 的区别:
特性 | MyBatis | MyBatis-Plus |
---|---|---|
SQL | 需要手写 | 提供大量内置方法,少写 SQL |
插件 | 需要额外集成 | 内置分页、逻辑删除、乐观锁 |
代码生成 | 无 | 提供代码生成器 |
学习成本 | 灵活但需要大量 SQL | 兼容 MyBatis,学习成本低 |
快速入门
入门案例
首先引入 MyBatis-Plus 依赖:
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.5</version>
</dependency>
数据库表结构:
CREATE TABLE `emp` (`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',`username` varchar(20) NOT NULL COMMENT '用户名',`password` varchar(32) DEFAULT '123456' COMMENT '密码',`name` varchar(10) NOT NULL COMMENT '姓名',`gender` tinyint unsigned NOT NULL COMMENT '性别, 说明: 1 男, 2 女',`job` tinyint unsigned DEFAULT NULL COMMENT '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',`entrydate` date DEFAULT NULL COMMENT '入职时间',`dept_id` int unsigned DEFAULT NULL COMMENT '部门ID',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '修改时间',PRIMARY KEY (`id`),UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=1983983618 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='员工表'
实体类 Emp:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDate;
import java.time.LocalDateTime;@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {private Integer id;private String username;private String password;private String name;private Short gender;private Short job;private LocalDate entrydate;private Integer deptId;private LocalDateTime createTime;private LocalDateTime updateTime;
}
EmpController:
import com.scarletkite.demo2.pojo.Emp;
import com.scarletkite.demo2.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class EmpController {@Autowiredprivate EmpService empService;@PostMapping("/emp")public void addEmp(@RequestBody Emp emp) {empService.addEmp(emp);}
}
EmpService 接口和 EmpServiceImpl 实现类:
// EmpService 接口
import com.scarletkite.demo2.pojo.Emp;public interface EmpService {void addEmp(Emp emp);
}// EmpServiceImpl 实现类
import com.scarletkite.demo2.mapper.EmpMapper;
import com.scarletkite.demo2.pojo.Emp;
import com.scarletkite.demo2.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.time.LocalDate;
import java.time.LocalDateTime;@Service
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;@Overridepublic void addEmp(Emp emp) {emp.setEntrydate(LocalDate.now());emp.setUpdateTime(LocalDateTime.now());emp.setCreateTime(LocalDateTime.now());empMapper.insert(emp);}
}
EmpMapper:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.scarletkite.demo2.pojo.Emp;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface EmpMapper extends BaseMapper<Emp> {}
让自己的 mapper 接口继承 MyBatis-Plus 提供的 BaseMapper,并指定泛型为对应实体类类型,BaseMapper 中已定义大量增删改查方法。
这样就能实现增删改查的操作,并且原来的 MyBatis 方法仍然生效。
常用注解
MyBatis-Plus 获取数据库信息的原理:MyBatis-Plus 通过扫描实体类,基于反射获取实体类信息作为数据库表信息,遵循 “约定大于配置” 原则。
MyBatis-Plus 的约定规则:
- 类名驼峰转下划线作为表名;
- 名为 id 的字段作为主键;
- 变量名驼峰转下划线作为表的字段名。
MyBatis-Plus 常用注解包括:
- @TableName(指定表名称)
- @TableId(指定表的主键)
- @TableField(标记表的普通字段信息)
@TableName 注解的使用:当实体类名与表名不一致时,需用 @TableName 的 value 属性指定真实表名,例如实体类为 Emp,表名为 tb_emp 时,需添加 @TableName (“tb_emp”)
@TableName ("tb_emp")
public class Emp {// ...
}
@TableId 注解的使用及主键策略:当主键名与 id 不一致或主键不叫 id 时,需用 @TableId 的 value 属性指定主键字段名;主键策略 IdType 有 AUTO(数据库自增长)、INPUT(程序员自己输入)、ASSIGN_ID(MyBatis-Plus 基于雪花算法生成,为 long 型整数,长度 20 位),通过 type 属性设置(若没有设置,默认 ASSIGN_ID)
@TableName ("tb_emp")
public class Emp {@TableId(value="id",type=IdType.AUTO)private Integer EmpId;
}
@TableField 注解的使用场景:成员变量名与数据库字段名不一致时,用 value 属性声明真实字段名
@TableName ("tb_emp")
public class Emp {@TableId(value="id",type=IdType.AUTO)private Integer EmpId;@TableField("username")private String name;
}
@TableField 的特殊场景:
- 以 is 开头的布尔类型字段,需指定真实字段名;
- 变量名与数据库关键字冲突时,需加转义字符;
- 成员变量不是数据库字段时,用 exist=false 标记。
常见配置
MyBatis-Plus 支持多种配置,包括继承自 MyBatis 的原生配置和自身特有的配置:
mybatis-plus:type-aliases-package: com.itheima.mp.domain.pojo # 别名扫描包mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址, 默认值configuration:map-underscore-to-camel-case: true # 是否开启下划线和驼峰的映射cache-enabled: false # 是否开启二级缓存global-config: # 全局配置db-config:id-type: assign_id # id为雪花算法生成update-strategy: not_null # 更新策略: 只更新非空字段
- 类型别名扫描包配置(typeAliasesPackage):需指定 pojo 实体类的包,作用是在定义 mapper XML 语句时,定义实体类类型可直接用类的简化名,无需全路径名
- mapper XML 文件地址配置(mapperLocation):用于指定 mapper XML 文件的地址,使其中的 SQL 语句生效。MyBatis-Plus 擅长单表增删改查,复杂或多表查询仍需手写 SQL,因此需指定该地址
- 下划线转驼峰映射配置(mapUnderscoreToCamelCase):开启后可实现成员变量驼峰形式与数据库下划线形式的自动转换,通常需开启
- 二级缓存配置(cacheEnabled):用于设置是否开启二级缓存,一般不开启,默认值为 false。
- MyBatis 原生配置与 MyBatis-Plus 的关系:上述配置是 MyBatis 的原生配置,MyBatis-Plus 继承了这些配置,使用时配置前缀改为 mybatis-plus,降低学习成本。
- MP 特有的全局配置(globalConfig):包括数据库配置(dbConfig)等,其中 id type 用于设置 id 的类型,如雪花算法(ASSIGN_ID),全局配置优先级低于注解配置。
- 更新策略配置(updateStrategy):默认值为 not null,即只更新非空字段,较为智能。
注意:全局配置的优先级没有注解优先级高
配置的默认值与查询方式:大部分配置有默认值,除类型别名扫描包需自行指定外,其他配置除非有自定义需求,否则无需修改。可通过查阅官网或利用 IDEA 自动提示来了解和配置。