一、是什么?
mybatis-plus 是 Mybatis 增强工具包 - 只做增强不做改变,简化CRUD操作。
- 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
- 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
- 损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作
- 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可*配置,完美解决主键问题
- 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
- 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
-
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
-内置分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于写基本List查询 - 内置性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作
二、官方参考文档 https://baomidou.com/guide/
三、强大的 wrapper
mybatis-plus的wapper继承图
Wraper的介绍:
- Wrapper : 条件构造抽象类,最顶端父类,抽象类中提供4个方法西面贴源码展示
- AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
- AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
- LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
- LambdaUpdateWrapper : Lambda 更新封装Wrapper
- QueryWrapper : Entity 对象封装操作类,不是用lambda语法
- UpdateWrapper : Update 条件封装,用于Entity对象更新操作
例如:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "zhangsan");
queryWrapper.ge("age", "18");
.......// 后面可以继续使用下图的函数,用于拼接sql。
函数说明:
AbstractWrapper的子类均可使用下面的函数。
四、代码实战
源代码地址:https://github.com/Dr-Water/mybatis-plus-demo
示例源代码目录结构:
- 新建一个springboot 工程 引入以下依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--mybatis-plus的核心依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies>
- 数据库配置文件:
# 应用名称
spring.application.name=mp
# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis-plus?serverTimezone=UTC&characterEncoding=UTF-8
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456
# 打印 mybatis-plus 的sql日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#mybatis mapper 定义的位置
mybatis-plus.mapper-locations= classpath*:/mappers/*.xml
#实体扫描,多个package用逗号或者分号分隔
mybatis-plus.typeAliasesPackage=com.ratel.mp.entity
- entity
package com.ratel.mp.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Builder;
import lombok.Data;
/**
* @业务描述:
* @package_name: com.ratel.mp.entity
* @project_name: mybatis-plus-demo
* @author: ratelfu@qq.com
* @create_time: 2020-12-13 10:14
* @copyright (c) ratelfu 版权所有
*/
@Data
@Builder
public class User {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private Integer age;
private String email;
}
- dao
package com.ratel.mp.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ratel.mp.entity.User;
import org.apache.ibatis.annotations.Param;
/**
* @业务描述:
* @package_name: com.ratel.mp
* @project_name: mybatis-plus-demo
* @author: ratelfu@qq.com
* @create_time: 2020-12-02 20:45
* @copyright (c) ratelfu 版权所有
*/
public interface UserDao extends BaseMapper<User> {
/**
* 自定义的getById
* @param id
* @return
*/
User myGetById(@Param("id") Integer id);
}
- mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ratel.mp.dao.UserDao">
<!--自定义的sql写在这里-->
<select id="myGetById" resultType="com.ratel.mp.entity.User">
select * from user where id=#{id}
</select>
</mapper>
- service
package com.ratel.mp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ratel.mp.entity.User;
/**
* @业务描述:
* @package_name: com.ratel.mp.service
* @project_name: mybatis-plus-demo
* @author: ratelfu@qq.com
* @create_time: 2020-12-13 10:34
* @copyright (c) ratelfu 版权所有
*/
public interface UserService extends IService<User> {
User myGetById(Integer id);
}
- serviceImpl
package com.ratel.mp.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ratel.mp.dao.UserDao;
import com.ratel.mp.entity.User;
import com.ratel.mp.service.UserService;
import org.springframework.stereotype.Service;
/**
* @业务描述:
* @package_name: com.ratel.mp.service
* @project_name: mybatis-plus-demo
* @author: ratelfu@qq.com
* @create_time: 2020-12-13 10:36
* @copyright (c) ratelfu 版权所有
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {
@Override
public User myGetById(Integer id) {
//baseMapper为ServiceImpl 定义好且已经注入的,这里无需再次 定义和注入
return baseMapper.myGetById(id);
}
}
- 简单的crud
package com.ratel.mp;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ratel.mp.entity.User;
import com.ratel.mp.service.UserService;
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 MpApplicationTests {
@Autowired
private UserService userService;
@Test
void queryTest(){
//普通写法
List<User> userList = userService.list(Wrappers.<User>query().eq("id",1));
System.out.println(userList);
//lambda写法
List<User> list = userService.list(Wrappers.<User>lambdaQuery().eq(User::getId,1));
list.forEach(System.out::println);
//new LambdaQueryWrapper<>(entity) 这种写法会将 entity中不为null的属性 拼接成where后的条件,且是 拼接出来是:eq(eg: id=1 and name = 'zs'...)
// 便于日常开发使用,比如说 前端会根据 id/name/age/email 这四种的任意一个或多个 进行查询,list,手动一个一个 .eq 太麻烦,就可以使用这种方式
List<User> list2 = userService.list(Wrappers.<User>lambdaQuery(User.builder().id(1).build()));
list.forEach(System.out::println);
}
@Test
void saveTest(){
//由于主键是自增的所以这里就不用设置id的值了
boolean isSuccess = userService.save(User.builder().name("zhangsan").age(18).email("zhangsan@qq.com").build());
System.out.println(isSuccess);
}
@Test
void updateTest(){
User user = User.builder().name("zhangsan2").age(20).email("zhangsan2@qq.com").build();
boolean isSuccess = userService.update(user, Wrappers.<User>update().eq("id",13));
System.out.println(isSuccess);
//用于构成 update语句的where部分
User condition = User.builder().id(13).build();
UpdateWrapper<User> updateWrapper = Wrappers.<User>update(condition)
.setSql("name=" + "'zhangsan3'," + "age=" + 18); //设置 set 语句(name=zs,age=18...)
boolean isSuccess2 = userService.update(updateWrapper);
System.out.println(isSuccess2);
}
@Test
void deleteTest(){
boolean isSuccess = userService.removeById(14);
System.out.println(isSuccess);
//删除一个不存在的数据 返回false
boolean isSuccess2 = userService.removeById(-1);
System.out.println(isSuccess2);
}
//测试自定义代码
@Test
void myGetByIdTest(){
User user = userService.myGetById(1);
System.out.println(user);
}
}