一、快速入门
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 #更新策略:只更新非空字段
二、核心功能
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,性能最好