MybatisPlus

一、快速入门

1.1使用步骤

1.引入MybatisPlus的起步依赖

复制代码
<denpendency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

2.定义Mapper

自定义的Mapper继承MybatisPlus提供的BaseMapper接口:

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

3.在实体类上添加注解声明(可选)

4.在application.yml中根据需要添加配置(可选)

1.2常用注解

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

@TableName:用来指定表名

@TableId:用来指定表中的主键字段信息

IdType枚举:

AUTO:数据库自增长

INPUT:通过set方法自行输入

ASSIGN_ID:分配ID,接口IdentifierGenerator的方法nextId来生成id,默认实现类为DefaultdentifierGenerator雪花算法

@TableField:用来指定表中的普通字段信息

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

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

成员变量名与数据库关键字冲突

成员变量不是数据库字段

java 复制代码
@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;
}

1.3常用配置

MyBatisPlus的配置项继承了MyBatis原生配置和一些自己特有的配置。例如:

bash 复制代码
mybatis-plus:
    type-aliases-package: com.cake.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 #更新策略:只更新非空字段

官网:https://www.baomidou.com

二、核心功能

2.1条件构造器

MyBatisPlus支持各种复杂的where条件,可以满足日常开发的所有需求。

示例:

1.查询出名字中带o的,存款大于等于1000元的人的id、username、info、balance字段

数据库语句:

sql 复制代码
SELECT id,username,info,balance FROM user WHERE username LIKE ? AND balance >= ?

MyBatisPlus实现:

java 复制代码
@Test
void testQueryWrapper(){
    //1.构建查询条件    
    QueryWrepper<User> wrapper = new QueryWrapper<User>()
            .select("id","username","info","balance")
            .like("username","o")
            .ge("balance",1000);//gt是大于,ge是大于等于
                
    //2.查询
    userMapper.selectList(wrapper);
}

使用Lambda

java 复制代码
@Test
void testQueryWrapper(){
    //1.构建查询条件    
    LambdaQueryWrepper<User> wrapper = new LambdaQueryWrapper<User>()
            .select(User::getId,User::getUsername,User::getInfo,User::getBalance)
            .like(User::getUsername,"o")
            .ge(User::getBalance,1000);//gt是大于,ge是大于等于
                
    //2.查询
    userMapper.selectList(wrapper);
}

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

数据库语句:

sql 复制代码
UPDATE user SET balance = 2000 WHERE (username = "jack")

MyBatisPlus实现:

java 复制代码
@Test
void testUpdateByQueryWrapper(){
//1.要更新的数据
User user = new User();
user.setBalance(2000);
//2.更新条件
QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username","jack");
//3.执行更新
userMapper.update(user,wrapper);
}

3.更新id为1,2,4的用户的余额,扣200

数据库语句:

sql 复制代码
UPDATE user SET balance = balance - 200 WHERE id in (1,2,4)

MyBatisPlus实现:

java 复制代码
@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);
}

小结

条件构造器的用法:

QueryWrapper和LambdaQueryWrapper通常用来构建select,delete,update的where条件部分。

UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用。

尽量使用LambdaQueryWrapper和LambdaUpdateWrapper,避免硬编码。

2.2自定义SQL

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

示例:将id在指定范围的用户(例如:1,2,4)的余额扣减指定值

1.基于Wrapper构建where条件

java 复制代码
List<Long> ids = List.of(1L,2L,4L);
int amount = 200;
//1.构建条件
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().in(User::getId,ids);
//2.自定义SQL方法调用
userMapper.updateBalanceByIds(wrapper,amount);

2.在mapper方法参数中用Param注解声明wrapper变量名称,必须是ew

java 复制代码
void updateBalanceByIds(@Param("ew") LambdaQueryWrapper<User> wrapper,@Param("amount") int amount);

3.自定义SQL,并使用Wrapper条件

XML 复制代码
<update id="updateBalanceByIds">
    UPDATE tb_user SET balance = balance - #{amount} ${ew.customSqlSegment}
</update>

2.3Service接口

2.3.1 IService接口基本用法

接口

java 复制代码
public interface IUserService extends IService<User>{

}

实现类

java 复制代码
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService{
    

}

2.3.2 IService的Lambda方法

IService的Lambda查询

java 复制代码
@Override
public List<User> queryUsers(String name,Integer status,Integer minBalance,Integer maxBalance){
    List<User> users = lambdaQuery()
            .like(name != null,User::getUsername,name)
            .eq(status != null,User::getStatus,status)
            .gt(minBalance != null,User::getMinBalance,minBalance)
            .lt(maxBalance != null,User::getMaxBalance,maxBalance)
            .list();
    return users;

IService的Lambda更新

java 复制代码
@Override
@Transactional
public void deductBalance(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.扣减余额
    int remainBalance = user.getBalance() - money;
    lambdaUpdate()
        .set(User::getBalance,remainBalance)
        .set(remainBalance == 0,User::getStatus,2)//status=2 账户冻结
        .eq(User::getId,id)
        .eq(User::getBalance,user.getBalance())// 乐观锁
        .update();
}

2.3.3 IService批量新增

在.yml配置文件的 spring: datasource: url: ......&rewriteBatchedStatements=true<--加这一句

java 复制代码
@Test
void testSaveBatch(){
    //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();
        }    
    }
    long e = System.currentTimeMillis();
    System.out.printLn("耗时:"+(e - b));
}

批处理方案:

-普通for循环逐条插入速度极差,不推荐

-MP的批量新增,基于预编译的批处理,性能不错

-配置jdbc参数,开rewriteBatchedStatements,性能最好

相关推荐
QC班长2 小时前
Maven公司私库配置踩坑点
java·服务器·maven·intellij-idea
Makoto_Kimur2 小时前
java开发面试-AI Coding速成
java·开发语言
wuqingshun3141592 小时前
说说mybatis的缓存机制
java·缓存·mybatis
空中海3 小时前
Kubernetes 生产实践、可观测性与扩展入门
java·贪心算法·kubernetes
Devin~Y3 小时前
大厂Java面试实录:Spring Boot/Cloud、Kafka、Redis、K8s 与 Spring AI(RAG/Agent)三轮连环问
java·spring boot·redis·mysql·spring cloud·kafka·kubernetes
bLEd RING3 小时前
SpringBoot3.3.0集成Knife4j4.5.0实战
java
小松加哲3 小时前
Spring MVC 核心原理全解析
java·spring·mvc
Ulyanov4 小时前
《PySide6 GUI开发指南:QML核心与实践》 第二篇:QML语法精要——构建声明式UI的基础
java·开发语言·javascript·python·ui·gui·雷达电子对抗系统仿真
码界筑梦坊4 小时前
357-基于Java的大型商场应急预案管理系统
java·开发语言·毕业设计·知识分享
云烟成雨TD4 小时前
Spring AI Alibaba 1.x 系列【31】集成 Studio 模块实现可视化 Agent 调试
java·人工智能·spring