依赖#
使用SpringBoot时在Maven添加Starter:
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 这个Generator根据需要添加 -->
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3</version>
</dependency>配置#
与在SpringBoot中使用Mybatis一样,在application配置文件中配置数据源即可。
spring:
datasource:
# MySQL 8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 114514
url: jdbc:mysql://localhost:3306/tutorial
# 日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImplMapper#
声明Mapper接口并继承MyBatisPlus中的BaseMapper<Entity>:
public interface MyMapper extends BaseMapper<My>{...}这里My为这个Mapper主要操作的实体类。
然后在你@SpringBootApplication注解的启动类加上@MapperScan(“mapper包根目录”)
脱裤子放屁,只需要在Mapper接口上写上@Mapper注解就行了。
BaseMapper提供许多简单的、便利的操作功能。
Service#
MybatisPlus的偷懒魔爪伸到了业务层,但实际上和Mapper的操作差不多。
public class MyServiceImpl extends ServiceImpl<MyMapper,My> implements MyServiceIntf{...}实体#
实体和往常一样创建一个POJO类就行,但MybatisPlus提供了一些注解。
不要使用基本类型!
- TableName
对实体类,默认是类名与表名完全对应(驼峰与下划线自动转换),当不对应是需要指定实体对应表名。
@TableName("normal_table")
public class MySuperObject{...}- TableId
与上述类似,当主键名称不对应可以指示(第一个参数value)。
第二个参数Type设置这个主键的生成策略,常用的有以下:
| 策略 | 效果 |
|---|---|
| IdType.NONE | 默认,如果主键为空也不管,和往常一样引发异常 |
| IdType.AUTO | 当数据库设置了主键自增,那么会自己填写自增后的ID;如果数据库中没有设置,同NONE |
| IdType.ASSIGN_ID | 不管数据库有没有设置自增,如果为空都根据雪花算法生成一个ID |
@TableId("normal_id",IdType.ASSIGN_ID)
private Long superId;
//数据库中为normal_id而代码实体类为superId,
//想要生成正经的ID应该使用Long,数据库使用BIGINT。- TableField
与TableID基本一致,就是不用于主键。
- TableLogic
启用逻辑删除。
在实体类某个属性(数据库表中也要有)添加,启用逻辑删除,此时Mybatis的各种操作只是将行数据(的那个属性)设置为已删除而不物理上地删除。
@TableLogic
private Integer isDeleted;另外可以指定什么值代表已删除。
@TableLogic("未删除值","已删除值")
条件构造器#
备忘录解释那么多干什么,看官网文档!
其实就是类似于某些ORM框架,把SQL转化为有类型的、链式的方法调用,如query.like(My::Name, "江").gt(My::Age, 96)。
条件构造器按如何区分字段可分为XxxWrapper和LambdaXxxWrapper(上面的例子就是),按可以进行的操作可以分为QueryWrapper和UpdateWrapper。尽量使用LambdaXxxWrapper。
如果Mapper是继承了BaseMapper的话,他都会有使用条件构造器的方法,简单使用如下:
...
QueryWrapper<My> wp = new QueryWrapper<>();
wp.like(My::getName, "江")
.gt(My::getAge, 96)
.orderByAsc(My::getAge);
myMapper.selectList(wp);
...使用QueryWrapper也可以修改:
My newMy = new My();
...
//设置newMy的变化属性
QueryWrapper<My> wp = new QueryWrapper<>();
wp.like(My::getName, "江")
.gt(My::getAge, 96)
.orderByAsc(My::getAge);
myMapper.update(newMy, wp);但修改的正统方法是通过UpdateWrapper:
UpdateWrapper<My> wp = new UpdateWrapper<>();
wp.like(My::getName, "江")
.gt(My::getAge, 96)
.orderByAsc(My::getAge)
.set(My::getAge, 95)
.set()
...
myMapper.update(null, wp);子查询可以通过.inSql()或.notInSql()方法判断是否在子查询集合。
需要根据条件开关Wrapper某个小条件,注意到condition参数。
自带的分页插件#
MybatisPlus的插件的添加方法都是通过配置类(本文是SpringBoot!):
//这段代码添加的就是分页插件!
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.你的数据库类型));
return interceptor;
}
}使用:
//定义Page实体,决定范围,类似但不同于limit ?,?
Page<My> toPage = new Page<>(从1起的页数不是INDEX, 每页多少条);
// 设置查询条件
QueryWrapper<My> wrapper = new QueryWrapper<>();
wrapper.like(My::getName, "江");
// 执行查询,用IPage来接收
IPage<My> iPage = myMapper.selectPage(toPage, wrapper);
//实际上你后面直接用toPage也可以!
// 查看分页信息
System.out.println("当前页:" + iPage.getCurrent());
System.out.println("总页数:" + iPage.getPages());
System.out.println("每一页显示的条数:" + iPage.getSize());
System.out.println("总条数:" + iPage.getTotal());
// 分页后的数据列表
return iPage.getRecords();自定义查询中也可以使用这个分页插件,只需要第一个参数为Page,SQL中不需要写limit之类的。
