【MyBatis-Plus】MyBatis-Plus 学习笔记

MyBatisPlus (简称MP)是基于 MyBatis 框架基础上开发的增强型工具,旨在简化开发、提高效率,遵守约定大于配置。

简化单表操作

简介 | MyBatis-Plus

快速入门

  1. 引入MyBatisPlus的起步依赖

把原来的MyBatis依赖删除

Java 复制代码
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId> 
    <version>3.4.1</version> 
</dependency>
  1. 定义的 Mapper继承 MybatisPlus 提供的 Base 接口

指定泛型为相对应的实体类

Java 复制代码
public interface UserMapper extends BaseMapper<User> {
}

直接调用方法

常见注解

MybatisPlus 通过扫描实体类,并基于反射获取实体类中的信息作为数据库表信息。

  • 类名驼峰转下划线作为表名
  • 名为 id 的字段作为主键
  • 变量名驼峰转下划线作为字段名

MyBatisPlus 中比较常见的注解

  • @TableName:用来制定表名
  • @Table:用来指定主键字段信息
  • @TableField:用来指定表中不同字段信息
Java 复制代码
@TableName("tb_user")
public class User {
    @TableId("id")
    private Long id;
    
    @TableField("username")
    private String name;
    
    @TableField("`order`")
    private Integer order;
    
    @TableField(exist = false)
    private String address;
}

使用@TableField的常见场景:

  • 成员变量名与数据库字段名不一致
  • 成员变量名以is开头·且是布尔值
  • 成员变量名与数据库关键字冲突
  • 成员变量不是数据库字段

常见配置

MyBatisPlus 的配置项继承了 MyBatis 的原生配置和自己的特有配置

Java 复制代码
mybatis-plus:
    type-aliases-package: com.itheima.mp.domain.po # 别名扫描包
    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 # 更新策略:只更新非空字段

核心功能

条件构造器

基于 QueryWrapper 的查询

需求:

  1. 查询名字中带o的,存款大于1000元的人的id、username、info、balance
SQL 复制代码
SELECT id,username,info,balance
FROM user
WHERE username like '%o%' AND balance >= 1000;

使用 QueryMapper 查询

Java 复制代码
void testQueryWrapper(){
    //1.构建查询条件
    QueryWrapper<User> wrapper = new QueryWrapper<User>()
        .select("id","username","info","balance")
        .like("username","o")
        .ge("balance",1000);
    //2.执行查询
    List<User> users = userMapper.selectList(wrapper); 
}
  1. 更新用户名为jack的用户的余额为2000
SQL 复制代码
UPDATE user
    SET balance = 2000
    WHERE username = 'jack';

使用 QueryMapper 查询

Java 复制代码
void testUpdateWrapper(){
    //要更新的数据
    User user = new user();
    user.setBalance(2000);
    //2.更新的条件
    QueryWrapper<User> wrapper = new QueryWrapper<User>()
        .eq("username","jack");
    //3.执行更新
    userMapper.update(user,wrapper);
}
  1. 更新 id 为1,2,4的用户的余额
SQL 复制代码
UPDATE user
    SET balance = balance - 200
WHERE id IN (1,2,4);

使用 QueryMapper 查询

Java 复制代码
void testUpdateWrapper(){
List<Long> ids = List.of(1,2,4);
    UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
        .setSql("balance = balance - 200")
        .in("id",ids);
    userMapper.update(null,wrapper);
}
  1. LambdaQueryWrapper 查询名字中带o的,存款大于1000元的人的id、username、info、balance
Java 复制代码
void testLambdaQueryWrapper() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
            .select(User::getId, User::getUsername, User::getInfo, User::getBalance)
            .like(User::getUsername,"o")
            .ge(User::getBalance, 1000);
}

自定义 SQL

利用 MyBatisPlus 的 Wrapper 语句构建复杂的 where 条件,然后自己定义 SQL 语句中剩余的部分。

上面3中,setSql("balance = balance - 200")的形式不规范,实际生产中一般不能这样写 现在可以自定义 SQL

  1. 基于 Wrapper 条件构造 where 语句
Java 复制代码
void testCustomSqlUpdate() {
    //1.更新条件
    List<Long> ids = List.of(1,2,4);
    int amount = 200;
    //2.定义条件
    UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
        .in("id",ids);
    //3.调用自定义 SQL 方法
    userMapper.updateBalanceByIds(wrapper, amount);
}
  1. 在 mapper 方法参数中用 Param 注解声明 Wrapper 变量名称,必须是 ew
Java 复制代码
    void updateBalanceByIds(@Param("ew") QueryWrapper<User> wrapper ,@Param("amount") int amount);
  1. 自定义 SQL,并使用 Wrapper
xml 复制代码
<update id="updateBalanceByIds">
    UPDATE tb_user SET balance = balance - #{amount} ${ew.customSqlSegment}
</update>

Service 接口

Mybatis Plus提供了默认的Service接口和实现类

  • 自定义接口需要继承 IService 接口
  • 我们的实现类要继承 IService 接口的实现类 ServiceImpl
Java 复制代码
public interface IUserService extends IService<User> {
}
Java 复制代码
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService{
}

表单提交要有DTO实体,用户查询结果返回要有VO实体
注入变量推荐使用@RequiredArgsConstructor 和 private final

Java 复制代码
@PostMapping
public void saveUser(@RequestBody UserFormDTO userDTO) {
    User user = BeanUtil.copyProperties(userDTO,User.class);
    userService.save(user);
}

@DeleteMapping("{id}")
public void deleteUserById(@PathVariable("id") Long id) {
    userService.removeById(id);
}

@GetMapping("{id}")
public UserVO queryUserById(@PathVariable("id") Long id) {
    User user = userService.getById(id);
    return BeanUtil.copyproperties(User,UserVO.class);
}

@GetMapping
public List<UserVO> queryUserByIds(@RequestParam("ids") List<Long> ids) {
    List<User> users = userService.getByIds(ids);
    retrun BeanUtil.copyToList(users,UserVO.class);
}

@PutMapping("/{id}/deduction/{money}")
public void deductionMoneyById(@PathVariable("id") Long id,@PathVariable("money") Integer money) {
    userService.deductionBalance(id, money);
}

userService 中没有这个方法,需要 userService 写,userServiceImpl 实现这个方法。

Java 复制代码
public void deductionBalance(Long id, Integer money) {
    //1.查询用户
    User user = userService.getById(id);
    //2.校验用户状态
    if(user == null or user.getStatus() == "2"){
        throw new RuntimeException("用户状态异常");
    }
    //3.校验余额是否充足
    Integer balance = user.getBalance();
    if(balance < money){
        throw new RuntimeException("余额不足");
    }
    //4.扣减余额
    baseMapper.deductionBalance(id, money);
}

在 UserMapper 中写

Java 复制代码
@Update("UPDATE tb_user SET balance = balance - #{money} WHERE id = #{id}")
void deductBalance(@Param("id")Long id, @Param("money")Integer money);
相关推荐
_code_bear_1 小时前
OpenSpec CLI 与 OPSX 工作流说明
前端·后端·架构
用户8356290780511 小时前
使用 Python 在 PowerPoint 中添加并控制音频播放
后端·python
用户8356290780511 小时前
使用 Python 在 PowerPoint 中生成并自定义饼图与环形图
后端·python
念何架构之路2 小时前
Go语言常见并发模式
开发语言·后端·golang
Cosolar2 小时前
大模型应用开发面试 • 第4期|A2A、复杂挑战与具身智能
人工智能·后端·面试
迷渡2 小时前
聊一聊 Bun 用 Rust 重写这件事
开发语言·后端·rust
王中阳Go2 小时前
秒杀、分库分表、全链路追踪:一个电商微服务的架构全拆解
后端·go
正儿八经的少年3 小时前
Spring Boot 两种激活配置方式的作用与区别
java·spring boot·后端
回家路上绕了弯3 小时前
AgentScope Java实战博客:从入门到落地,解锁智能代理开发新范式
后端