MybatisPlus学习笔记:引入+使用

基础

使用方法

  1. 引入依赖:
<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <version>3.5.10.1</version>
        </dependency>
  1. 定义Mapper接口并继承BaseMapper
package com.itheima.ai.mapper;

import com.itheima.ai.entity.po.Course;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 * 学科表 Mapper 接口
 * </p>
 *
 * @author wensiiy
 * @since 2025-11-24
 */
public interface CourseMapper extends BaseMapper<Course> {

}

案例

package com.itheima.ai.tools;

import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.itheima.ai.entity.po.Course;
import com.itheima.ai.entity.po.CourseReservation;
import com.itheima.ai.entity.po.School;
import com.itheima.ai.entity.query.CourseQuery;
import com.itheima.ai.service.ICourseReservationService;
import com.itheima.ai.service.ICourseService;
import com.itheima.ai.service.ISchoolService;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@RequiredArgsConstructor
public class CoursesTools {
    private final ICourseService courseService;
    private final ISchoolService schoolService;
    private final ICourseReservationService courseReservationService;

    @Tool(description = "根据条件查询课程")
    public List<Course> queryCourses(@ToolParam(description = "查询的条件", required = false) CourseQuery courseQuery) {
        if (courseQuery == null) {
            return courseService.list();
        }
        QueryChainWrapper<Course> wrapper = courseService.query()
                .eq(courseQuery.getType() != null, "type", courseQuery.getType())
                .le(courseQuery.getEdu() != null, "edu", courseQuery.getEdu());
        if (courseQuery.getSorts() != null && !courseQuery.getSorts().isEmpty()) {
            for (CourseQuery.Sort sort : courseQuery.getSorts()) {
                wrapper.orderBy(true, sort.getAsc(), sort.getField());
            }
        }
        return wrapper.list();
    }

    @Tool(description = "查询所有校区")
    public List<School> querySchools() {
        return schoolService.list();
    }

    @Tool(description = "生成预约单,返回预约单号")
    public Integer saveCourseReservation(@ToolParam(description = "预约课程") String course,
                                         @ToolParam(description = "预约校区") String school,
                                         @ToolParam(description = "学生姓名") String studentName,
                                         @ToolParam(description = "联系电话") String contactInfo,
                                         @ToolParam(description = "备注", required = false) String remark) {
        CourseReservation courseReservation = new CourseReservation();
        courseReservation.setCourse(course);
        courseReservation.setSchool(school);
        courseReservation.setStudentName(studentName);
        courseReservation.setContactInfo(contactInfo);
        courseReservation.setRemark(remark);
        courseReservationService.save(courseReservation);

        return courseReservation.getId();
    }
}

常用注解

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

默认——

  1. 类名驼峰转下划线为表名

  2. 名为id字段为主键

  3. 变量名驼峰转下划线为字段名

如果不符,用注解标出——

  1. @TableName:用于指定表名

  2. @TableId:指定主键

  3. @TableField:指定普通字段信息

IdType枚举:

  1. AUTO:数据库自增长

  2. INPUT:自定

  3. ASSIGN_ID:MybatisPlus(MP)提供接口采用雪花算法生成ID,为long类型

使用@TableField:

  1. 成员变量名与数据库字段名不一致

  2. 成员变量以is开头,且是布尔值

  3. 成员变量名与数据库关键字冲突,需要用反引号标注

  4. 成员变量不是数据库字段

@TableName("tb_user")
public class User {
  @TableId(value="id",type= IdType.AUTO)
  private Long id;
  @TableField("username")
  private String name;
  @TableField("is_married")
  private Boolean isMarried;
  @TableField("`order`")
  private Integer order;
  @TableField(exist = false)
  private String address;
}

常见配置

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 # 更新策略:只更新非空字段

条件构造器

MyBatisPlus支持各种复杂的where条件,可满足开发需求:

在这里插入图片描述

案例

void testQueryWrapper(){
  QueryWrapper<User> wrapper = new QueryWrapper<User>()
    .select("id", "username")
    .like("username", "o")
    .ge("balance", 1000);
  List<User> users = userMapper.selectList(wrapper);
  users.forEach(System.out::println);
}

void testLambdaQueryWrapper(){
  LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
    .select(User::getid, User::getUsername)
    .like(User::getUsername, "o")
    .ge(User::getBalance, 1000);
  List<User> users = userMapper.selectList(wrapper);
  users.forEach(System.out::println);
}

void testUpdateByQueryWrapper(){
  User user = new User();
  user.setBalance(200);
  QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "jack");
  userMapper.update(user, wrapper);
}

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);
}

自定义Sql

我们可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分。

生成Service

  1. 自定义Service接口继承IService接口

  2. 自定义Service实现类,实现自定义接口并继承ServiceImpl类

注意指定泛型类型,Mapper类型和实体类类型

进阶

IService的Lambda方法

@override
public List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {
  return lambdaQuery()
    .like(name != null, User::getUsername, name)
    .eq(status != null, User::getStatus, status)
    ·ge(minBalance != null, User::getBalance, minBalance)
    .le(maxBalance != null, User::getBalance, maxBalance)
    .list();
}


@override
public void deductBalance(Long id, Integer money) {
  //1.查询用户
  User user = getById(id) ;
  //2.校验用户状态
  if (user == null |l user.getstatus() == 2) {
    thrownewRuntimeException("用户状态异常!");
  }
  //3.校验余额是否充足
  if (user.getBalance() < money) {
    thrownewRuntimeException("用户余额不足!");
  }
  // 4.扣减余额 update tb_user set balance = balance - ?
  int remainBalance = user.getBalance() - money;
  lambdaUpdate ()
    .set(User::getBalance, remainBalance)
    .set(remainBalance == θ, User::getStatus, 2)
    .eq(User::getId, id)
    .eq(User::getBalance, user.getBalance()) // 乐观锁:当前用户的余额是否已经发生改变
    .update();
}

IService批处理

要实现批处理,只需要在yaml中mysql的请求路径后面开启参数:&rewriteBatchedStatements=true即可。

private User buildUser(int i) {
  User user = new User();
  user.setUsername("user_" + i);
  user.setPassword("123") ;
  user.setPhone("" + (18688190000L + i));
  user.setBalance(2000) ;
  user.setInfo("{\"age\":24,\"intro\":\"英文老师\",\"gender\":\"female\"}");
  user.setCreateTime(LocalDateTime.now()) ;
  user.setUpdateTime(user.getCreateTime());
  return user;
}

void testSaveBatch() {
  //我们每次批量插入1000条件,插入100次即10万条数据
  //1.准备一个容量为1000的集合
  List<User> list = new ArrayList<>(1000);
  long b = System.currentTimeMillis();
  for (int i = 1; i <= 100000; i++) {
    //2.添加一个user
    list.add(buildUser(i)) ;
    //3.每1000条批量插入一次
    if (i % 1000 == 0){
      userService.saveBatch(list) ;
      //4.清空集合,准备下一批数据
      list.clear();
    }
  }
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值