所需依赖
<!-- Mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>xxx</version>
</dependency>
<!--mybatis-plus-generator-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>xxx</version>
</dependency>
<!--和生成器搭配使用-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>xxx</version>
</dependency>
自动生成代码
由generator和mybatisx搭配使用,generator的好处是,一键生成mapper,mapper.xml,service和controller,并且搭配BaseMapper,可以提供一套简单的通用api。
mybatisx的好处是更快的构建比较复杂条件的crud,因为它有详细到每个字段的方法供选择,选择方法之后会直接在mapper.xml层生成很标准的sql语句,并且提供了mapper和mapper.xml的快速切换。mybatisx也可以直接生成service,mapper这些,但是它需要IDEA连接数据库,并且配置项也比较复杂,不像generator一次写好可以供所有人一直使用。
Mapper
mapper是调用数据库语句的最底层,它通过继承了BaseMapper拥有了一些最通用的crud方法(需要更复杂的字段选择需要自己写或者使用mybatisx生成)
在我们使用了generator生成mapper之后它往往已经继承好了BaseMapper
public interface RbacUserMapper extends BaseMapper<RbacUserEntity> {}
条件构造器
类型
queryWrapper
用来附加sql条件的wrapper,以下是添加了account字段等于传进来的req中account变量值的条件。
Entity entity = mapper.selectOne(
new QueryWrapper<Entity >()
.eq("account", req.getAccount())
);
lambdaQueryWrapper
作用是直接将实体类的参数名当成搜索时条件的字段名,这样做最大的好处就是避免了字段写错
Entity entity = mapper.selectOne(
new LambdaQueryWrapper<Entity >()
.eq(Entity ::getAccount, req.getAccount())
);
其他Wrapper
updateWrapper和lambdaUpdateWrapper是两个修改的wrapper,完全可以被querywrapper替代
基本语法
如果直接链式,那么就相当于使用了and,如果使用了and(),就会起括号的作用
而如果要达到or的效果,就需要增加一个.or()
在sql中and优先级高于or,所以如果真正要得到a or b的效果,需要.and(a.or().b),这里就是用了and()的括号作用
可以在condition中添加是否增加该值作为判断的条件,比如!=null
图片取自尚硅谷
如图效果为
like user_name like ‘a’ and (age >= 20 or email is NULL)
重要拦截插件
插件前提条件
需要创造一个配置类,比如
@Configuration
public class MyBatisPlusConfig {
/**
* 分页插件
* 乐观锁插件
* @return
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
分页
分页是一种查询进阶操作,用于规定要第几行开始的n行
Page<Entity> page = new Page<>(2,3);
rbacUserMapper.selectPage(page,null);
这表示这第2页,每页为3行,所以返回的是第四行开始的三行
事务
为什么还需要一层事务
我们知道spring和数据库都会提供事务,为什么mybatis-plus还要提供一层呢?
对于数据库而言,只会对一次操作进行事务操作,而我们需要的是先完成了查询,再改变,再存入,所以数据库锁无效。而spring事务锁判断的是这操作是否失误,比如存入失败了,就会回滚到查询之前。但是我们并不是操作失误,而是未察觉数据版本的更新。
mybatis-plus提供的就是一种在操作数据时,会比较数据版本的机制,如果版本不对,那么这次的操作就不会生效。
使用
只需要在实体类多加一个@version字段,如
@TableName("rbac_user")
public class RbacUserEntity extends Model<RbacUserEntity> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户id
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 账户
*/
private String account;
@version
private int version;
,在之后每次数值被修改都会增加version值,如果所需version和实际不匹配,操作就会取消
参考
尚硅谷 2022版MyBatisPlus教程(一套玩转mybatis-plus)