MyBatis-Plus 简介
什么是MyBatis-Plus?
MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。
核心特性
1. 无侵入
只做增强不做改变,引入它不会对现有工程产生影响。
2. 损耗小
启动即会自动注入基本CRUD,性能基本无损耗,直接面向对象操作。
3. 强大的CRUD操作
内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分CRUD操作。
4. 支持Lambda形式
通过Lambda表达式,方便的编写各类查询条件,无需担心字段写错。
5. 支持主键自动生成
支持多达4种主键策略,可自由配置,完美解决主键问题。
6. 支持ActiveRecord模式
支持ActiveRecord形式调用,实体类只需继承Model类即可进行强大的CRUD操作。
7. 支持自定义全局通用操作
支持全局通用方法注入。
8. 内置代码生成器
采用代码或Maven插件可快速生成Mapper、Model、Service、Controller层代码。
9. 内置分页插件
基于MyBatis物理分页,开发者无需关心具体操作,配置好插件后,写分页等同于普通List查询。
10. 内置性能分析插件
可输出SQL语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询。
11. 内置全局拦截插件
提供全表delete、update操作智能分析阻断,也可自定义拦截规则,预防误操作。
快速开始
1. 添加依赖
Maven:
xml
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>2. 配置数据源
application.yml:
yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: password
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # SQL日志
map-underscore-to-camel-case: true # 下划线转驼峰
global-config:
db-config:
id-type: auto # 主键自增
table-prefix: t_ # 表名前缀
logic-delete-field: deleted # 逻辑删除字段
logic-delete-value: 1 # 逻辑删除值
logic-not-delete-value: 0 # 逻辑未删除值
mapper-locations: classpath*:/mapper/**/*.xml3. 创建实体类
java
@Data
@TableName("user") // 指定表名
public class User {
@TableId(type = IdType.AUTO) // 主键自增
private Long id;
@TableField("user_name") // 指定字段名
private String username;
private String email;
private Integer age;
@TableField(fill = FieldFill.INSERT) // 插入时自动填充
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新时自动填充
private LocalDateTime updateTime;
@TableLogic // 逻辑删除
private Integer deleted;
@Version // 乐观锁
private Integer version;
@TableField(exist = false) // 非数据库字段
private String extra;
}4. 创建Mapper接口
java
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 继承BaseMapper后,无需编写任何代码即可使用CRUD方法
}5. 使用BaseMapper
java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// 插入
public void insert() {
User user = new User();
user.setUsername("张三");
user.setEmail("zhangsan@example.com");
user.setAge(25);
userMapper.insert(user);
}
// 根据ID查询
public User getById(Long id) {
return userMapper.selectById(id);
}
// 查询所有
public List<User> getAll() {
return userMapper.selectList(null);
}
// 更新
public void update() {
User user = userMapper.selectById(1L);
user.setAge(26);
userMapper.updateById(user);
}
// 删除
public void delete(Long id) {
userMapper.deleteById(id);
}
}BaseMapper方法
MyBatis-Plus提供的通用CRUD方法:
Insert
java
// 插入一条记录
int insert(T entity);Delete
java
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件删除
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 entity 条件删除
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 根据 ID 批量删除
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);Update
java
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
// 根据 whereWrapper 条件修改 entity
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);Select
java
// 根据 ID 查询
T selectById(Serializable id);
// 根据 ID 批量查询
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 columnMap 条件查询
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 wrapper 条件查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 wrapper 条件查询总记录数
Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 wrapper 条件查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 wrapper 条件查询全部记录并分页
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);条件构造器
QueryWrapper
java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// 基本条件
public List<User> queryExample1() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username", "张三") // username = '张三'
.ne("age", 18) // AND age != 18
.gt("age", 20) // AND age > 20
.ge("age", 18) // AND age >= 18
.lt("age", 30) // AND age < 30
.le("age", 25); // AND age <= 25
return userMapper.selectList(wrapper);
}
// 模糊查询
public List<User> queryExample2() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("username", "张") // username LIKE '%张%'
.likeLeft("username", "三") // username LIKE '%三'
.likeRight("username", "张"); // username LIKE '张%'
return userMapper.selectList(wrapper);
}
// IN查询
public List<User> queryExample3() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.in("id", 1, 2, 3, 4, 5); // id IN (1,2,3,4,5)
return userMapper.selectList(wrapper);
}
// BETWEEN
public List<User> queryExample4() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age", 18, 30); // age BETWEEN 18 AND 30
return userMapper.selectList(wrapper);
}
// IS NULL / IS NOT NULL
public List<User> queryExample5() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNull("email") // email IS NULL
.isNotNull("username"); // AND username IS NOT NULL
return userMapper.selectList(wrapper);
}
// OR条件
public List<User> queryExample6() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username", "张三")
.or()
.eq("username", "李四"); // username = '张三' OR username = '李四'
return userMapper.selectList(wrapper);
}
// 嵌套查询
public List<User> queryExample7() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username", "张三")
.and(w -> w.eq("age", 25).or().eq("age", 30));
// username = '张三' AND (age = 25 OR age = 30)
return userMapper.selectList(wrapper);
}
// 排序
public List<User> queryExample8() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age") // ORDER BY age ASC
.orderByDesc("create_time"); // , create_time DESC
return userMapper.selectList(wrapper);
}
// 选择字段
public List<User> queryExample9() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("id", "username", "email"); // SELECT id, username, email
return userMapper.selectList(wrapper);
}
}LambdaQueryWrapper(推荐)
使用Lambda表达式,避免字段名写错:
java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List<User> queryWithLambda() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getUsername, "张三")
.gt(User::getAge, 18)
.like(User::getEmail, "@example.com")
.orderByDesc(User::getCreateTime);
return userMapper.selectList(wrapper);
}
// 条件动态拼接
public List<User> queryDynamic(String username, Integer minAge, Integer maxAge) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StringUtils.isNotBlank(username), User::getUsername, username)
.ge(minAge != null, User::getAge, minAge)
.le(maxAge != null, User::getAge, maxAge);
return userMapper.selectList(wrapper);
}
}UpdateWrapper
java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void updateExample1() {
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("username", "张三")
.set("age", 26)
.set("email", "new@example.com");
userMapper.update(null, wrapper);
}
// Lambda方式
public void updateExample2() {
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getUsername, "张三")
.set(User::getAge, 26)
.set(User::getEmail, "new@example.com");
userMapper.update(null, wrapper);
}
}分页查询
1. 配置分页插件
java
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
paginationInterceptor.setDbType(DbType.MYSQL);
paginationInterceptor.setOverflow(false); // 溢出总页数后是否进行处理
paginationInterceptor.setMaxLimit(500L); // 单页分页条数限制
interceptor.addInnerInterceptor(paginationInterceptor);
return interceptor;
}
}2. 使用分页
java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public IPage<User> pageQuery(int current, int size) {
Page<User> page = new Page<>(current, size);
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(User::getAge, 18)
.orderByDesc(User::getCreateTime);
return userMapper.selectPage(page, wrapper);
}
}java
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/page")
public IPage<User> page(@RequestParam(defaultValue = "1") int current,
@RequestParam(defaultValue = "10") int size) {
return userService.pageQuery(current, size);
}
}IService接口
MyBatis-Plus提供了IService接口,包含更多实用方法。
1. 创建Service接口和实现
java
public interface UserService extends IService<User> {
// 自定义方法
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
// 自定义方法实现
}2. 使用IService方法
java
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
// 保存
@PostMapping
public boolean save(@RequestBody User user) {
return userService.save(user);
}
// 批量保存
@PostMapping("/batch")
public boolean saveBatch(@RequestBody List<User> users) {
return userService.saveBatch(users);
}
// 保存或更新
@PostMapping("/saveOrUpdate")
public boolean saveOrUpdate(@RequestBody User user) {
return userService.saveOrUpdate(user);
}
// 根据ID查询
@GetMapping("/{id}")
public User getById(@PathVariable Long id) {
return userService.getById(id);
}
// 条件查询一条
@GetMapping("/one")
public User getOne(@RequestParam String username) {
return userService.getOne(
new LambdaQueryWrapper<User>().eq(User::getUsername, username)
);
}
// 查询列表
@GetMapping("/list")
public List<User> list() {
return userService.list();
}
// 条件查询列表
@GetMapping("/listByAge")
public List<User> listByAge(@RequestParam Integer age) {
return userService.list(
new LambdaQueryWrapper<User>().gt(User::getAge, age)
);
}
// 分页查询
@GetMapping("/page")
public IPage<User> page(@RequestParam int current, @RequestParam int size) {
return userService.page(new Page<>(current, size));
}
// 更新
@PutMapping
public boolean updateById(@RequestBody User user) {
return userService.updateById(user);
}
// 根据ID删除
@DeleteMapping("/{id}")
public boolean removeById(@PathVariable Long id) {
return userService.removeById(id);
}
// 批量删除
@DeleteMapping("/batch")
public boolean removeBatchByIds(@RequestBody List<Long> ids) {
return userService.removeBatchByIds(ids);
}
// 统计
@GetMapping("/count")
public long count() {
return userService.count();
}
}