六、条件构造器
MP提供了很强大的条件构造器
AbstractWrapper: QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类
用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件
注意: entity 生成的 where 条件与 使用各个 api 生成的 where 条件没有任何关联行为
条件构造器 | 作用 | 条件构造器例子 | 对应sql语句例子 |
---|---|---|---|
allEq | 全等于 | allEq({id:1,name:"老王",age:null}) | allEq({id:1,name:"老王",age:null}) |
eq | 等于= | eq("name", "老王") | name = '老王' |
ne | 不等于<> | ne("name", "老王") | name <> '老王' |
gt | 大于> | gt("age", 18) | age > 18 |
ge | 大于等于>= | ge("age", 18) | age >= 18 |
lt | 小于< | lt("age", 18) | age < 18 |
le | 小于等于<= | le("age", 18) | age <= 18 |
between | between值1and值2 | between("age", 18, 30) | age between 18 and 30 |
not between | not between值1and值2 | notBetween("age", 18, 30) | age not between 18 and 30 |
like | like '%值%' | like("name", "王") | name like '%王%' |
not like | not like '%值%' | notLike("name", "王") | name not like '%王%' |
likeLeft | like '%值' | likeLeft("name", "王") | name like '%王' |
likeRight | like '值%' | likeRight("name", "王") | name like '王%' |
isNull | 字段 is null | isNull("name") | name is null |
isNotNull | 字段 is not null | isNotNull("name") | name is not null |
in | 字段in(v0,v1,…) | in("age", 1, 2, 3) | age in (1,2,3) |
notIn | 字段notIn(v0,v1,…) | notIn("age", 1, 2, 3) | age not in (1,2,3) |
inSql | in子查询 | inSql("id", "select id from table where id < 3") | id in (select id from table where id < 3) |
notInSql | not in子查询 | notInSql("id", "select id from table where id < 3") | age not in (select id from table where id < 3) |
groupBy | 分组:group by | groupBy("id", "name") | group by id,name |
orderByAsc | 升序排序:order by 字段,… asc | orderByAsc("id", "name") | order by id ASC,name ASC |
orderByDesc | 降序排序:order by 字段,… desc | orderByDesc("id", "name") | order by id DESC,name DESC |
orderBy | 排序:order by 字段 | orderBy(true, true, "id", "name") | order by id ASC,name ASC |
having | having(sql语句) | having("sum(age) > 10") | having sum(age) > 10 |
or | 拼接or | or(i -> i.eq("name", "李白").ne("status", "活着")) | or (name = '李白' and status <> '活着') |
and | and嵌套 | and(i -> i.eq("name", "李白").ne("status", "活着")) | and (name = '李白' and status <> '活着') |
nested | 正常嵌套不带and或者or | nested(i -> i.eq("name", "李白").ne("status", "活着")) | (name = '李白' and status <> '活着') |
apply | 拼接sql | apply("id = 1") id = 1 | |
last | 无视优化规则直接拼接到sql的最后 | last("limit 1") | |
exists | 拼接exists(sql语句) | exists("select id from table where age = 1") | exists (select id from table where age = 1) |
notExists | 拼接not exists(sql语句) | notExists("select id from table where age = 1") | not exists (select id from table where age = 1 |
queryWrapper继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件
及 LambdaQueryWrapper, 可以通过 new QueryWrapper().lambda() 方法获取
条件构造器 | 作用 | 条件构造器例子 | 对应sql语句例子 |
---|---|---|---|
select | 设置查询字段 | select("id", "name", "age") | select id, name, age |
UpdateWrapper继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件
及 LambdaUpdateWrapper, 可以通过 new UpdateWrapper().lambda() 方法获取!
条件构造器 | 作用 | 条件构造器例子 | 对应sql语句例子 |
---|---|---|---|
set | sql set字段 | set("name","老李头") | set name = "老李头" |
setSql | 设置set部分sql | setSql("name"='老李头') | set name = "老李头" |
七、自定义SQL
八、分页查询
mabtis提供的是逻辑分页,先查出所有,消耗内存,查询速度慢,然而,MP采用的是物理分页查询。
MP分页步骤:
添加配置类
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
在BashMapper中可以看到,MP提供了两个分页方法,一个是根据实体类,一个根据 Wrapper 条件
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件
* @param queryWrapper 实体对象封装操作类
*/
>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper);
测试:查询年龄大于21 的用户信息,并以每页容量为两条分页的形式返回
@Test
public void testPage() {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age",21);
System.out.println("根据 entity 条件");
//设置当前页和页容量
Page page = new Page(1, 2);
IPage userIPage = userMapper.selectPage(page, queryWrapper);
System.out.println("总页数:"+userIPage.getPages());
System.out.println("总记录数:"+userIPage.getTotal());
userIPage.getRecords().forEach(System.out::println);
System.out.println("根据 Wrapper 条件");
Page
控制台输出
根据 entity 条件
2020-03-31 17:24:15.078 INFO 6812 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2020-03-31 17:24:15.250 INFO 6812 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
总页数:3
总记录数:5
User(id=2, name=Tom, age=28, [email protected], managerId=1, createTime=null)
User(id=3, name=Sandy, age=21, [email protected], managerId=2, createTime=null)
根据 Wrapper 条件
总页数:3
总记录数:5
{manager_id=1, name=Tom, id=2, age=28, [email protected]}
{manager_id=2, name=Sandy, id=3, age=21, [email protected]}
扩展知识:分页查询的时候,不查询总记录数,分页查询Page类的构造参数提供了参数的重载,第三个参数为false时,不会查询总记录数。
public Page(long current, long size, boolean isSearchCount) {
this(current, size, 0, isSearchCount);
}
九、AR模式(Active Record)
简介:通过实体类对象直接对表进行增删改查操作,方便开发人员开发
要求
1、实体类继承Model<>类
@Data
@EqualsAndHashCode(callSuper = false)
public class User extends Model {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
private String managerId;
private LocalDateTime createTime;
}
2、必须存在对应原始Mapper接口,并继承BashMapper<>接口并且可以使用
public interface UserMapper extends BaseMapper {
}
Model类中封装了很多增删改查方法,不用使用UserMapper即可完成对数据的增删改查。
@Test
public void selectAll(){
User user = new User();
user.selectAll().forEach(System.out::println);
}
控制台输出
2020-03-31 16:33:21.608 INFO 19004 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2020-03-31 16:33:21.992 INFO 19004 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
User(id=1, name=Jack, age=20, [email protected], managerId=null, createTime=null)
User(id=2, name=Tom, age=28, [email protected], managerId=1, createTime=null)
User(id=3, name=Sandy, age=21, [email protected], managerId=2, createTime=null)
User(id=4, name=Billie, age=24, [email protected], managerId=2, createTime=null)
User(id=5, name=Lida, age=24, [email protected], managerId=2, createTime=null)
User(id=1244645982902157314, name=null, age=20, email=null, managerId=2, createTime=2020-03-30T15:21:41)
User(id=1244646703630483458, name=null, age=21, email=null, managerId=2, createTime=2020-03-30T15:24:33)
十、主键策略
MP主键策略定义在了IdType枚举类中,定义了6种,1依赖数据库,2跟从全局策略,
3用户自己维护,剩下三个当插入id为空时才填充
public enum IdType {
/**
* 数据库ID自增
*/
AUTO(0),
/**
* 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
*/
NONE(1),
/**
* 用户输入ID
* 该类型可以通过自己注册自动填充插件进行填充
*/
INPUT(2),
/* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
/**
* 分配ID (主键类型为number或string),
* 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花算法)
*
* @since 3.3.0
*/
ASSIGN_ID(3),
/**
* 分配UUID (主键类型为 string)
* 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-",""))
*/
ASSIGN_UUID(4),
/**
* @deprecated 3.3.0 please use {@link #ASSIGN_ID}
*/
@Deprecated
ID_WORKER(3),
/**
* @deprecated 3.3.0 please use {@link #ASSIGN_ID}
*/
@Deprecated
ID_WORKER_STR(3),
/**
* @deprecated 3.3.0 please use {@link #ASSIGN_UUID}
*/
@Deprecated
UUID(4);
private final int key;
IdType(int key) {
this.key = key;
}
}
在实体类中对应数据库中的主键id属性上标注注解TableId(type='xxx')即可完成主键配置。
@TableId(type = IdType.AUTO)
private Long id;
这种配置方式的主键策略只能在该表中生效,但是其他表还需要进行配置,为了避免冗余,麻烦,MP提供了全局配置,MP默认全局策略是基于雪花算法的自增id,在配置文件中配置主键策略即可实现。
mybatis-plus:
mapper-locations: mapper/*.xml
global-config:
db-config:
id-type: auto
十一、基本配置
mybatis-plus:
mapper-locations: mapper/*.xml
global-config:
db-config:
# 主键策略
id-type: auto
# 表名前缀
table-prefix: t
# 表名是否使用下划线间隔,默认:是
table-underline: true
# 添加mybatis配置文件路径
config-location: mybatis-config.xml
# 配置实体类包地址
type-aliases-package: org.ywb.demo.pojo
# 驼峰转下划线
configuration:
map-underscore-to-camel-case: true
本文参考自:MybatisPlus学习总结
上一篇