一、快速入门
1.入门案例
2.常见注解
(1)@TableName:用来指定表名
(2)@TableId:用来指定表中的主键字段信息
- @TableId注解中有一个属性叫做type,它是一个枚举类型(AUTO、INPUT、ASSIGN_ID)

(3)@TableField:用来指定表中的普通字段信息
- 注1:上面三个注解主要用于当数据库表中的表名、id名、普通字段不一致时进行使用
- 注2:如果属性值和数据库表中字段名字能够对应,但是该字段是is开头且是布尔类型的,也要用注解指明对应的字段(底层是基于反射的,会将is去掉作为变量名,导致字段不一致问题)
- 注3:当出现实体类的字段与数据库中的关键字重复的时候,也要加上@TableField,例如order
- 注4:如果实体类中的字段在表中没有对应,那么应该加上@TableField(exist = false)标记该字段不存在
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("user")
public class User {
/**
* 用户id
*/
@TableId
private Long id;
/**
* 用户名
*/
@TableField(value = "username")
private String username;
/**
* 密码
*/
private String password;
/**
* 注册手机号
*/
private String phone;
/**
* 详细信息
*/
private String info;
/**
* 使用状态(1正常 2冻结)
*/
private Integer status;
/**
* 账户余额
*/
private Integer balance;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
3.常见配置

二、核心功能
1.条件构造器
(1)继承关系

(2)AbstractWrapper:抽象类,用于构建复杂的 SQL 查询条件,它提供了一系列方法来方便地拼接、组合查询条件,如等于、不等于、大于、小于、模糊查询、范围查询等,使得开发者可以更加灵活地编写数据库查询逻辑,而无需手动编写大量的 SQL 条件语句

(3)UpdateWrapper:对更新操作进行了扩展(可以用set自定义sql)

- 需求:更新id为1,2,4的用户的余额,扣200
- 实现SQL:UPDATE user SET balance = balance -200 WHERE id in(1, 2, 4)
-
@Test void testUpdateWrapper() { List<Long> ids = List.of(1L, 2L, 4L); UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.setSql("balance = balance - 200"); wrapper.in("id", ids); userMapper.update(null, wrapper); }
(4)QueryWrapper:对查询相关条件进行了扩展

(5)LambdaUpdateWrapper 以及 LambdaQueryWrapper 功能和UpdateWrapper 、 QueryWrapper功能是一样,它增加了Lambda表达式的使用
- 需求:更新id为1,2,4的用户的余额,扣200
- 实现SQL:UPDATE user SET balance = balance -200 WHERE id in(1, 2, 4)
@Test
void testLambdaUpdateWrapper(){
List<Long> ids = List.of(1L, 2L, 4L);
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.setSql("balance = balance - 200");
wrapper.in(User::getId, ids);
userMapper.update(null, wrapper);
}
(7)条件构造器的用法
- QueryWrapper和LambdaQueryWrapper通常用来构建select、delete、update的wher条件部分
- UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用
- 尽量使用LambdaQueryWrapper和LambdaUpdateWrapper避免硬编码
2.自定义SQL
- 我们可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分。
- 在上面介绍的方法中,我们一部分sql其实是在service中写的,为了规范,service应该是处理业务的,数据库相关不应该写到里面,那么我们可以利用自定义SQL去解决这种问题
(1)需求:更新id为1,2,4的用户的余额,扣200
(2)实现SQL:UPDATE user SET balance = balance -200 WHERE id in(1, 2, 4)
(3)service
@Test
void testCustomSQL(){
List<Long> ids = List.of(1L, 2L, 4L);
int account = 200;
// 1.构建条件
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().in(User::getId, ids);
// 2.自定义SQL方法的调用
userMapper.updateByCustomSQL(account, wrapper);
}
(3)mapper:在mapper方法参数中用Param注解声明wrapper变量必须是ew
public interface UserMapper extends BaseMapper<User> {
/**
*
* @param account
* @param wrapper
*/
void updateByCustomSQL(@Param("account") int account, @Param("ew") LambdaQueryWrapper<User> wrapper);
}
- 也可以使用mp自带的常量
(4)mapper.xml(调用自定义条件)
<?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.itheima.mp.mapper.UserMapper">
<update id="updateByCustomSQL">
update user set balance = balance + #{account} ${ew.customSqlSegment}
</update>
</mapper>
3.IService接口
- 功能相比于之前我们继承的BaseMapper更加的强大
(1)基本用法
- 自定义接口继承Iservice接口
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;
public interface IUserService extends IService<User> {
}
-
自定义Service实现类,实现自定义接口并继承ServiceImpl类
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}
- service实现类中调用
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
@Autowired
private UserMapper userMapper;
public void add(User user){
this.save(user);
}
public void list(User user){
this.listByIds(null);
}
}
- 注1:按照上面步骤写完以后,我们就能够直接调用 Service接口 给我们提供的各种各样丰富的方法了
(2)Service接口中lambdaQuery方法:在写sql的时候,我们经常会遇到先判断条件为null的情况,使用lambdaQuery方法就不需要在做这样的判断了
- 普通写法

- 使用LambdaQuery

(3)Service接口中lambdaUpdate方法:可以添加条件,直接做更新

(4)批量插入
- 性能
三、扩展功能
1.代码生成器
(1)安装插件:mybatisplus插件

(2)在idea的工具中填写数据库连接(版本不同位置可能有所不同,我的是23版本)


(3)连接成功,后点击生成代码


(4)查看生成的代码:在我们设置的包下面就可以看到生成的代码了
- Controller
/**
* <p>
* 前端控制器
* </p>
*
* @author author
* @since 2024-12-26
*/
@RestController
@RequestMapping("/address")
public class AddressController {
}
- servece
/**
* <p>
* 服务实现类
* </p>
*
* @author author
* @since 2024-12-26
*/
@Service
public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> implements IAddressService {
}
-
entity
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author author
* @since 2024-12-26
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("address")
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 省
*/
private String province;
/**
* 市
*/
private String city;
/**
* 县/区
*/
private String town;
/**
* 手机
*/
private String mobile;
/**
* 详细地址
*/
private String street;
/**
* 联系人
*/
private String contact;
/**
* 是否是默认 1默认 0否
*/
private Boolean isDefault;
/**
* 备注
*/
private String notes;
/**
* 逻辑删除
*/
private Boolean deleted;
}
2.静态工具(最新版本才有)
- 与IService接口相似,但是它没有泛型,需要我们手动传入class
- 为什么有IService接口还需要这个静态工具类呢?
因为在某些连表查询的场景,表1有可能需要用到表2的信息,表2也有可能用到表1的信息,就会形成循环依赖,为了解决这种场景,就可以使用静态工具,我们不指定具体的类去操作

- 注1:spring可以开启循环依赖:spring.main.allow-circular-references=true
- 注2:连表查询可使用手写xml
3.逻辑删除
(1)逻辑删除:开发中我们的一些数据删除是伪删除,也就是逻辑删除,即在表中加一个字段,用0 1 表示正常或者删除,当我们查询的时候加上条件为0即可
(2)mybatisplus提供了逻辑删除的功能,无需改变方法的调用方式(我们可以调用本来的方法去进行删除或者查询),只要我们配置了逻辑删除的相关配置,调用原来的方法时,他会自动根据我们配置的字段去删除查询(删除方法变成了更新,查询方法底层增加了对应条件)

- 注:不推荐使用
4.枚举处理器
(1)枚举映射
- 在实体类中,某些字段填写的是数字,为了代码的可读性,可以用枚举类去做替换,替换以后其类型和数据库中的类型就对不上了,枚举处理器就是解决这种问题的

- 上图中,可以将status字段替换为枚举类,用@EnumValue标注真正和数据库中字段对应的值即可
- 在VO中,给前端返回数据时默认是枚举名(NORMAL、FREEZE),要想给前端返回 0 1,那么我们可以在value上方加上@JsonValue
(2)配置全局枚举处理器
mybatis-plus:
configuration:
default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
5.JSON处理器
(1)Json和实体类映射
- JSON处理器是用来解决数据库中json类型和java类型转换的问题

- 在上图中,数据库中的json字段要映射到实体类中,需要加上注解(没有全局配置,只能一个一个去配):@TableField(typeHandler = JacksonTypeHandler.class)
- 还需要在@TableName中开启我们复杂结果的映射:autoResultMap = true
四、插件功能
1.Mybatis-Plus分页插件
(1)基本使用
- 要在配置类中注册MyBatisPlus的核心插件,同时添加分页插件
@Configuration
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// 1.创建分页插件
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
paginationInnerInterceptor.setMaxLimit(1000L); // 设置单页最大条数
// 2.添加分页插件
mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
return mybatisPlusInterceptor;
}
}
- 使用
@Test
void testPage(){
int pageNumber = 1;
int pageSize = 2;
// 准备分页
Page<User> page = Page.of(pageNumber, pageSize);
// 添加排序
page.addOrder(new OrderItem("balance", true));// true是升序
userService.page(page);
System.out.println(page.getTotal());
}
- 结果

3273

被折叠的 条评论
为什么被折叠?



