基础
使用方法
- 引入依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.10.1</version>
</dependency>
- 定义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通过扫描实体类,并基于反射获取实体类信息作为数据库表信息。
默认——
-
类名驼峰转下划线为表名
-
名为id字段为主键
-
变量名驼峰转下划线为字段名
如果不符,用注解标出——
-
@TableName:用于指定表名
-
@TableId:指定主键
-
@TableField:指定普通字段信息
IdType枚举:
-
AUTO:数据库自增长
-
INPUT:自定
-
ASSIGN_ID:MybatisPlus(MP)提供接口采用雪花算法生成ID,为long类型
使用@TableField:
-
成员变量名与数据库字段名不一致
-
成员变量以is开头,且是布尔值
-
成员变量名与数据库关键字冲突,需要用反引号标注
-
成员变量不是数据库字段
@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
-
自定义Service接口继承IService接口
-
自定义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();
}
}
}
1824

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



