当前位置: 首页 > news >正文

Mybatis-Plus

大家学习的时候可以参照官网简介 | MyBatis-Plus

目录

基本流程

1.在pom.xml导入依赖

2.给自己的类继承父类

3.常见注解

4.常见配置

核心功能

1.条件构造器

2.自定义sql

3.IService接口

扩展功能

1.代码生成器

2.Db静态工具

3.逻辑删除

4.枚举处理器

5.JSON处理器

插件功能


基本流程

1.在pom.xml导入依赖

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

2.给自己的类继承父类

之后测试类就可以直接用了,直接用类的Mapper点,然后挑选方法

3.常见注解

1.可以用这个来指定表名,在这个例子中,表的名字和类名字不一样,所以要用这个注解。

2.这个是用来表示主键的注解,type来定义属性,自增长

3.这个是因为表里面属性的名字和类的属性名字不一致,需要用这个注解

4.同3

5.order是关键字,所以需要转义重新命名

6.此属性在表里面不存在,所以需要用到exit这个属性

4.常见配置

在application.yaml里面配置

核心功能

1.条件构造器

1.查询名字带o,余额大于1000的

    void testQueryWrapper() {
        //构建查询条件
        QueryWrapper<User> wrapper=new  QueryWrapper<User>()
                .select("id,username,balance,info")
                .like("username","o")
                .ge("balance",1000);
        //查询
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);

    }
  • QueryWrapper<User>
    泛型为 User,表示这是一个针对 User 实体类的查询条件构造器。

  • .select("id,username,balance,info")
    指定查询的字段(若省略,默认查询所有字段 SELECT *)。

  • .like("username", "o")
    生成 username LIKE '%o%' 的模糊查询条件。

  • .ge("balance", 1000)
    生成 balance >= 1000 的范围查询条件。

  • userMapper.selectList(wrapper)
    调用 MyBatis-Plus 的 selectList 方法,传入 QueryWrapper 对象,执行查询并返回符合条件的 User 列表。

2.更新用户名字为jack的余额为2000

    @Test
    void testUpdateQueryWrapper() {
        User user = new User();
        user.setBalance(2000);
        //构建查询条件
        QueryWrapper<User> wrapper=new  QueryWrapper<User>()
                .eq("username","jack");
        //查询
        userMapper.update(user,wrapper);


    }

         这段代码的作用是找到用户名为"jack"的用户,并仅更新该用户的余额(balance)至2000。其他未设置的字段不会受到影响,因为MyBatis Plus默认只会更新你明确设置了值的字段。不过,这依赖于MyBatis Plus的版本和配置,确保你使用的版本支持这种行为。

3.将id 为 1   2   4用户的余额扣200

    @Test
    void testUpdateWrapper() {
       List <Long> ids=List.of(1L,2L,4L);
        //构建查询条件
        UpdateWrapper<User> wrapper=new  UpdateWrapper<User>()
                .setSql("balance =balance-200")
                .in("id",ids);
        //查询
        userMapper.update(null,wrapper);


    }

2.自定义sql

  @Test
    void testUpdateWrapper() {
       List <Long> ids=List.of(1L,2L,4L);
       int amount=200;
        //构建查询条件
       LambdaUpdateWrapper<User> wrapper=new  LambdaUpdateWrapper<User>()
               .in(User::getId,ids);
        //查询
        userMapper.updatebalance(wrapper,amount);


    }
public interface UserMapper extends BaseMapper<User> {

      //一定要加注解 ew amount
    void updatebalance(@Param("ew") LambdaUpdateWrapper<User> wrapper, @Param("amount") int amount);
}

    <update id="updatebalance">
    UPDATE user SET  balance= balance-#{amount} ${ew.customSqlSegment}

    </update>

3.IService接口

本质还是调用mapper

按照下面创建接口和实现类,然后接口继承

IService<User>

然后实现类继承

ServiceImpl<UserMapper, User>

UserMapper是用到的mapper,因为本质还是调用mapper,User是你要操作的类

实现接口

接口

package com.itheima.mp.Service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;

public interface IUserService extends IService<User> {
}

实现类

package com.itheima.mp.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.Service.IUserService;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}

给接口创建一个测试类

package com.itheima.mp.Service;

import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDateTime;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class IUserServiceTest {
    @Autowired
    private IUserService userService;

    @Test
    void testSaveUser() {
        User user = new User();
        user.setId(6L);
        user.setUsername("lilei");
        user.setPassword("123");
        user.setPhone("18688996666");
        user.setBalance(200);
        user.setInfo("{\"age\": 25, \"intro\": \"地理老师\", \"gender\": \"male\"}");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userService.save(user);
    }

    @Test
    void testQuery() {
        List<User> users = userService.listByIds(List.of(1L, 2L, 3L, 4L));
        users.forEach(System.out::println);
    }
}

业务接口

新建controlller,在里面写各个接口

package com.itheima.mp.controller;


import cn.hutool.core.bean.BeanUtil;
import com.itheima.mp.Service.IUserService;
import com.itheima.mp.domain.dto.UserFormDTO;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.Tag;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.service.Tags;

import java.util.List;

@RequestMapping("/users")
@RestController
@Api(tags="用户管理接口")
public class UserControlller {

    @Autowired
    private IUserService userService;

    @ApiOperation("新增用户接口")
    @PostMapping
    public void saveUser(@RequestBody UserFormDTO userDTO){
        User user = BeanUtil.copyProperties(userDTO, User.class);
        userService.save(user);

    }

    @ApiOperation("删除用户接口")
    @DeleteMapping("{id}}")
    public void deleteUserById(@ApiParam("用户id") @PathVariable("id") Long id){

        userService.removeById(id);

    }

    @ApiOperation("查询单个用户接口")
    @GetMapping("{id}}")
    public UserVO queryUserById(@ApiParam("用户id") @PathVariable("id") Long id){

        User user=userService.getById(id);
        return BeanUtil.copyProperties(user, UserVO.class);
    }

    @ApiOperation("查询多个用户接口")
    @GetMapping
    public List<UserVO> queryUserByIds(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids){

        List<User> users=userService.listByIds(ids);
        return BeanUtil.copyToList(users, UserVO.class);
    }

    @ApiOperation("扣减单个用户余额接口")
    @GetMapping("/{id}}/deduction/{money}")
    public void deducteMoneyById(
            @ApiParam("用户id") @PathVariable("id") Long id,
            @ApiParam("扣减的钱") @PathVariable("money") Integer money

    ){

       userService.deducteById(id,money);

    }


}

其中,最后一个接口,业务复杂,mp的iservice没有符合这个功能的方法,所以要自己定义

在接口中定义

然后在实现类里面定义

package com.itheima.mp.Service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.Service.IUserService;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {


    @Override
    public void deducteById(Long id, Integer money) {
        // 1. 查询用户
        User user = getById(id);
        // 2. 校验用户状态
        if(user==null||user.getStatus()==2){
            throw  new RuntimeException("用户状态异常");
        }
        // 3. 校验余额是否充足
        if(user.getBalance()<money){
            throw  new RuntimeException("用户余额不足");
        }

        // 4. 扣减余额
        baseMapper.deductBalance(id,money);
//此处也可以使用条件构造器
    }
}
  • 继承 ServiceImpl 后,你无需手动注入 Mapper 接口(如 UserMapper),因为 baseMapper 已经提供了对它的访问。

通过baseMapper来访问UserMapper

UserMapper.java

package com.itheima.mp.mapper;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserMapper extends BaseMapper<User> {

      //一定要加注解 ew amount
    void updatebalance(@Param("ew") LambdaUpdateWrapper<User> wrapper, @Param("amount") int amount);

    void deductBalance(@Param("id")Long id, @Param("money")Integer money);
}

UserMapper.xml

    <update id="deductBalance">
        UPDATE user SET  balance= balance-#{money} where id=#{id}
    </update>

当你使用 MyBatis-Plus 的 lambdaUpdate() 方法时,实际上是通过动态构建 SQL 语句,并最终调用 BaseMapper 中的基础方法来执行数据库操作。

有   更新的   lambdaUpdate   后面要加    .update();

有 查询的   lambdaQuery   

扩展功能

1.代码生成器

要安装一个插件

2.Db静态工具

可能service会互相注入,循环注入,所以使用静态工具避免循环注入

3.逻辑删除

因为有时候某个数据很重要,不能直接删除,所以定义一个属性可以标记他是否被删除,就不用真的删除,当你需要找他的时候,就根据这个标记的属性来查询(比如0是未被删除,1是被删除)

首先你的表里面要有某个字段作为逻辑删除的标记字段

在yaml里面配置逻辑删除字段

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted # 全局逻辑删除的实体字段名
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

就可以了

package com.itheima.mp.Service;

import com.itheima.mp.domain.po.Address;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class IAddressServiceTest {

    @Autowired
    private IAddressService addressService;

    @Test
    void testDeleteByLogic() {
        // 删除方法与以前没有区别
        addressService.removeById(59L);
        //查询
        Address address = addressService.getById(59L);
        System.out.println("address = " + address);
    }
}

4.枚举处理器

  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
package com.itheima.mp.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;

    @Getter
    public enum UserStatus {
        NORMAL(1, "正常"),
        FREEZE(2, "冻结");
        @EnumValue
        private final int value;
        @JsonValue
        private final String desc;

        UserStatus(int value, String desc) {
            this.value = value;
            this.desc = desc;
        }
    }

5.JSON处理器

表里面有字段是json类型的数据,处理JSON就可以使用JacksonTypeHandler处理器。

插件功能

相关文章:

  • 数据结构:栈和队列
  • 灵办AI助手Chrome插件全面评测:PC Web端的智能办公利器
  • 学习总结2.14
  • 科普:Docker run的相关事项
  • Redis缓存雪崩、击穿、穿透
  • 第一章 Java面向对象进阶
  • 利用AFE+MCU构建电池管理系统(BMS)
  • 设计模式相关知识点
  • 驱动开发、移植
  • 2025最新智能优化算法:改进型雪雁算法(Improved Snow Geese Algorithm, ISGA)求解23个经典函数测试集,MATLAB
  • MYSQL总结(1)
  • 鸿道Intewell操作系统:赋能高端装备制造,引领国产数控系统迈向新高度
  • C++中为什么有了tuple还需要pair?
  • 【C++】 Flow of Control
  • 同花顺C++面试题及参考答案
  • 【Elasticsearch】查询规则_query_rules
  • 【核心算法篇十四】《深度解密DeepSeek量子机器学习:VQE算法加速的黑科技与工程实践》
  • 【数据挖掘】
  • Leetcode - 周赛436
  • 通过监督微调提升多语言大语言模型性能
  • 重庆大学通报本科生发14篇SCI论文处理结果
  • 要更加冷静地看待“东升西降”的判断
  • 深圳两家会所涉卖淫嫖娼各被罚7万元逾期未缴,警方发催告书
  • 壹基金发布2024年度报告,公益项目惠及937万人次
  • 毕赣新作《狂野时代》入围戛纳主竞赛单元,易烊千玺舒淇主演
  • 专访|高圆圆:像鸟儿一样,柔弱也自由