一、 基本知识
1. 介绍
yBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上增加了大量功能和简化操作,以提高开发效率。
2. 特点
- 无侵入:只做增强不做改变,引入它不会对现有项目产生影响。
- 依赖少:仅仅依赖 MyBatis 和 MyBatis-Spring。
- 扩展性强:提供了丰富的插件机制,可以根据需求进行扩展。
- 多种插件支持:分页插件、性能分析插件、数据权限插件等。
- 全方位覆盖 CRUD 操作:提供了丰富的 CRUD 接口,简化了单表操作的代码编写。
- 代码生成器:支持根据数据库表结构生成对应的实体类、Mapper 接口、Service 层代码。
3. MyBatis与MyBatisPlus
特性 | MyBatis | MyBatis-Plus |
---|---|---|
入侵性 | 低 | 低(对现有项目无影响,只做增强) |
依赖性 | 需要 MyBatis | 依赖 MyBatis 和 MyBatis-Spring |
简化 CRUD 操作 | 不提供,需要手动编写 | 提供丰富的 CRUD 接口,自动生成单表 CRUD 代码 |
分页支持 | 需要自行实现 | 提供分页插件,开箱即用 |
动态 SQL | 需要手动编写动态 SQL | 提供更加简化的动态 SQL 支持 |
代码生成器 | 不提供 | 提供代码生成器,可根据数据库表生成实体类、Mapper、Service |
逻辑删除 | 不提供 | 提供逻辑删除注解 |
自动填充 | 不提供 | 提供字段自动填充注解 |
拓展性 | 通过插件实现 | 提供丰富的内置插件,并支持自定义插件 |
性能分析 | 不提供 | 提供性能分析插件 |
字段验证 | 需要手动实现 | 提供校验插件 |
多租户支持 | 需要手动实现 | 提供多租户插件 |
热加载 | 需要手动实现 | 支持热加载,方便开发调试 |
SQL 执行效率分析 | 不提供 | 提供 SQL 执行效率分析插件 |
复杂 SQL 支持 | 强 | 强,但通过条件构造器简化复杂 SQL |
主键生成策略 | 需要手动设置 | 提供多种主键生成策略 |
性能 | 高 | 高 |
二、基本使用
1. 配置
- 引入依赖:在 Maven 项目中,引入 MyBatis-Plus 依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version>
</dependency>
- 配置文件:在 application.yml 或 application.properties 中配置数据源和 MyBatis-Plus
spring:datasource:url: jdbc:mysql://localhost:3306/mydatabaseusername: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus:mapper-locations: classpath:/mapper/*.xmltype-aliases-package: com.example.entity
**2.注解 **
MyBatis-Plus通过反射获取实体类信息作为表数据信息。
(1)当实体类命名与数据库表一一对应时:
- 类名转驼峰命名,作为表名
- 名为id的变量作为表的主键
- 成员变量转驼峰命名作为表的字段名
(2)当实体类命名与数据库表不对应时使用注解 - @TableName:用于指定表名
- @TableId:指定主键字字段信息,可以指定IdType(auto、assigned_id、input)
- @TableField:指定普通字段名及相关配置(如是否存在、类型handler等)
3. 基本使用CRUD
(1)创建与数据库表对应的实体类
package com.example.entity;import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import lombok.Data;@Data
@TableName("users")
public class User {@TableId(value = "id", type = IdType.AUTO)private Long id;private String name;private String email;private Integer age;private String address;
}
(2)创建 Mapper 接口并继承 MyBatis-Plus 提供的 BaseMapper
package com.example.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper extends BaseMapper<User> {
}
(3) 创建 Service 接口和实现类
package com.example.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.User;public interface UserService extends IService<User> {
}
package com.example.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import com.example.service.UserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
(4)创建 Controller 类来处理请求,基础的增删改查直接调用basemapper里面的函数接口
package com.example.controller;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@GetMappingpublic List<User> getAllUsers() {return userService.list();}@GetMapping("/{id}")public User getUserById(@PathVariable Long id) {return userService.getById(id);}@PostMappingpublic void createUser(@RequestBody User user) {userService.save(user);}@PutMappingpublic void updateUser(@RequestBody User user) {userService.updateById(user);}@DeleteMapping("/{id}")public void deleteUser(@PathVariable Long id) {userService.removeById(id);}
}
三、高级功能
(一). 条件构造器(Wrapper)
1. 介绍
条件构造器(Wrapper)是 MyBatis-Plus 提供的一个强大的工具,用于简化复杂查询的构造。它通过链式调用的方式生成 SQL 语句,支持多种条件组合。
2.常见方法
- eq(String column, Object val):等于条件
- ne(String column, Object val):不等于条件
- gt(String column, Object val):大于条件
- ge(String column, Object val):大于等于条件
- lt(String column, Object val):小于条件
- le(String column, Object val):小于等于条件
- like(String column, Object val):模糊匹配
- between(String column, Object val1, Object val2):范围匹配
- in(String column, Collection<?> value):IN 查询
- isNull(String column):字段为 NULL
3. 示例
// 查询名字为"John"且年龄大于等于18的用户
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "John").ge("age", 18);
List<User> users = userMapper.selectList(queryWrapper);
4. Lamba表达式
尽量使用LambdaQueryWrapper和LambdaUpdateWrapper,避免硬编码。
(二)自定义sql
1.介绍
MyBatis-Plus 支持在 Mapper 接口中自定义 SQL 语句,主要是处理那些条件构造器无法涵盖的复杂查询、批量操作等场景。
2. 实现方式
(1)XML 文件定义自定义 SQL
- 定义
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper"><!-- 根据邮箱查询用户 --><select id="selectByEmail" resultType="com.example.entity.User">SELECT * FROM users WHERE email = #{email}</select><!-- 根据年龄范围查询用户 --><select id="selectByAgeRange" resultType="com.example.entity.User">SELECT * FROM users WHERE age BETWEEN #{minAge} AND #{maxAge}</select><!-- 批量插入用户 --><insert id="batchInsert">INSERT INTO users (name, email, age) VALUES<foreach collection="list" item="item" separator=",">(#{item.name}, #{item.email}, #{item.age})</foreach></insert>
</mapper>
- 使用
// UserMapper.java
package com.example.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;import java.util.List;public interface UserMapper extends BaseMapper<User> {User selectByEmail(@Param("email") String email);List<User> selectByAgeRange(@Param("minAge") int minAge, @Param("maxAge") int maxAge);int batchInsert(@Param("list") List<User> users);
}
注:@Param不要忘记
(2)使用注解定义自定义 SQL
// UserMapper.java
package com.example.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;import java.util.List;public interface UserMapper extends BaseMapper<User> {@Select("SELECT * FROM users WHERE email = #{email}")User selectByEmail(@Param("email") String email);@Select("SELECT * FROM users WHERE age BETWEEN #{minAge} AND #{maxAge}")List<User> selectByAgeRange(@Param("minAge") int minAge, @Param("maxAge") int maxAge);@Insert({"<script>","INSERT INTO users (name, email, age) VALUES ","<foreach collection='list' item='item' separator=','>","(#{item.name}, #{item.email}, #{item.age})","</foreach>","</script>"})int batchInsert(@Param("list") List<User> users);
}
(3)结合条件构造器与自定义 SQL(将指定id的用户的余额减少200)
- service实现类:基于Wrapper构建where条件
List<Long> ids = List.of( 1L,2L,4L);int amount = 200;
//1.构建条件
LambdaQuerywrapper<User> wrapper = new LambdaQuerywrapper<User>( ) .in(User::getId,ids); / 2.自定义SQL方法调用
userMapper.updateBalanceByIds(wrapper, amount) ;
- mapper接口:在mapper方法参数中用Param注解声明wrapper变量名称,必须是ew
void updateBalanceByIds (@Param("ew") LambdaQueryWwrapperUser> wrapper,@eParam(" amount") int amount);
- xml映射文件:自定义SQL,并使用Wrapper条件
<update id="updateBalanceByIds">
UPDATE tb_user SET balance - balance - #{amount]${ew.customSqlSegment}</ update>
(三)service接口
1. 介绍
- MyBatis-Plus 提供了 IService 接口和 ServiceImpl 基类,极大地简化了 Service 层的开发。
- 使用时只需要定义一个service接口继承 IService 接口,相应的实现类继承 ServiceImpl 基类
2. 核心功能 - 创建 Service 接口和实现类
接口:
package com.example.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.User;public interface UserService extends IService<User> {
}
实现类:
package com.example.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import com.example.service.UserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
- 使用
package com.example.controller;import com.example.entity.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;// 增加用户@PostMappingpublic boolean addUser(@RequestBody User user) {return userService.save(user);}// 根据ID删除用户@DeleteMapping("/{id}")public boolean deleteUser(@PathVariable Long id) {return userService.removeById(id);}// 更新用户信息@PutMappingpublic boolean updateUser(@RequestBody User user) {return userService.updateById(user);}// 根据ID查询用户@GetMapping("/{id}")public User getUserById(@PathVariable Long id) {return userService.getById(id);}// 查询所有用户@GetMappingpublic List<User> getAllUsers() {return userService.list();}
}
注:简单的增删改查直接在servi接口调用方法可以,复杂的需要逻辑判断的功能需要在service实现类中自己处理逻辑
(四)MyBatisPlus扩展功能
(1)代码生成器
使用插件生成和数据库表对应的代码,包括controller、service、serviceimpl等。
(2)逻辑删除
- MyatstPus提供了逻辑盯赊功能,无需改变方法调用的方式,而是在底层帮我们自动修改CRUD的语句。只需要在application.yaml文件中配置逻辑删除的字段名称和值即可
mybatis-plus:global-config:db-config:logic-delete-field: flag # 全局逻辑删除的实体字段名,字段类型可以是 boolean、integerlogic-delete-value: 1 #逻辑已删除值(默认为1)logic-not-delete-value: 0#逻辑未删除值(默认为0)
- 然后,在实体类中添加逻辑删除字段,并使用 @TableLogic 注解标识。
package com.example.entity;import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;@Data
@TableName("user")
public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private Integer age;@TableLogic // 标记逻辑删除字段@TableField(value = "is_deleted", fill = FieldFill.INSERT) // 指定逻辑删除字段名和填充策略private Integer deleted;
}
(3)枚举处理器
MyBatis-Plus 支持枚举类型的处理,可以将数据库中的枚举值和实体类中的枚举类型进行映射。
- 在yml中配置
mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
- PO类中的枚举类型变量与数据库字段的转换:给枚举中的与数据库对应value值添加@EnumValue注解
public enum UserStatus {ACTIVE(1, "Active"),INACTIVE(2, "Inactive");@EnumValueprivate final int code;private final String label;UserStatus(int code, String label) {this.code = code;this.label = label;}
(4)Json处理器
当数据库存储了Json格式的数据时,需要进行JSON 数据与Java 对象中之间的映射
- 数据库表对应的实体类上配置autoResultMap = true
- 对应实体类中对应字段配置:@TableFiled(typeHandler=JacksonTypeHandler.calss)
注:JSON类型数据的处理无法进行全局配置,只能在每一个变量上使用@TableFiled进行配置
Data
@TableName(“user”,autoResultMap = true)
public class User{
private Long id;
private String username ;
@TaTableField(typeHandler = JacksonTypeHandler.class)
private UserInfo info ;
}
(5)全局分页插件
1. 配置分页插件属性
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.dialects.MySqlDialect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor () {
// 1.初始化核心插件
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//2添加分页插件
PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType .MYsQL);pageInterceptor.setMaxLimit( 1000L);//设置分页上限
interceptor.addInnerInterceptor(pageInterceptor) ;
return interceptor;
}