MyBatisPlus 基础入门
1. 数据库初始化
- 创建数据库
创建User表
CREATE TABLE user ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id) );
插入数据
INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, '[email protected]'), (2, 'Jack', 20, '[email protected]'), (3, 'Tom', 28, '[email protected]'), (4, 'Sandy', 21, '[email protected]'), (5, 'Billie', 24, '[email protected]');
2. 创建SpringBoot项目
1. 导入依赖
<!-- mp依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!--lombok以来-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
以上依赖中,mp和mysql驱动为必须添加的
2. 添加配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.3.66/mybatisplus_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: oyl
password: 123123
3. 主类添加扫描注解
@MapperScan("com.oylong.mptest.mapper") //添加此注解
@SpringBootApplication
public class MpTestApplication {
public static void main(String[] args) {
SpringApplication.run(MpTestApplication.class, args);
}
}
4. 创建实体类
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
3. MybatisPlus 使用
1. 创建Mapper接口,继承自BaseMapper
package com.oylong.mptest.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.oylong.mptest.entity.User;
public interface UserMapper extends BaseMapper<User> {
}
//此接口要放在主类扫描注解对应的mapper包下
2. 测试类测试
注入UserMapper,并且使用userMapper查询所有的用户
@Autowired private UserMapper userMapper; @Test void contextLoads() { userMapper.selectList(null).stream().forEach(System.out::println); }
如图,打印了数据库中的所有数据
开启详细日志
控制台打印的数据并不是很详细,不能看到具体的sql语句,添加如下:
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.3.66/mybatisplus_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai username: oyl password: 123123 # 添加的配置 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
再次运行:
控制台中打印了详细的sql语句.
3. 主键自增策略
通过注解设置:
@Data public class User { //通过此注解设置自增策略 @TableId(type = IdType.ASSIGN_ID) private Long id; private String name; private Integer age; private String email; }
可以通过
@TableId(type = IdType.xxxxx)
这个注解来设置自增策略,MyBatisPlus默认的自增策略为雪花算法,几种自增策略为:- IdType.Auto: 表示数据库ID自增,设置为此项需要设置数据库的主键字段为自增
IdType.UUID: 表示设置主键ID为UUID
- IdType.ASSIGN_ID: 表示通过雪花算法设置主键ID
通过全局配置设置
mybatis-plus: global-config: db-config: id-type: assign_id
也可以通过添加如上的配置,来全局统一的配置自增策略
4. CRUD
- 查询
如上图所示的方法,查询有很多,通常使用较多的就是selectList
,selectOne
,selectById
,selectCount
,selectPage
这几个,通常会搭配QuerryWrapper
这个对象用来进行条件查询,如下代码:
@Test
void selectTest() {
List<User> users = userMapper.selectList(null);
for(User user: users) {
System.out.println(user);
}
User user = userMapper.selectById(1);
System.out.println(user);
User user1 = userMapper.selectOne(new QueryWrapper<User>().eq("name", "Jack"));
System.out.println(user1);
}
插入
插入操作较为简单,如下:
User user = new User(); user.setAge(18); user.setEmail("[email protected]"); user.setName("oyLong"); userMapper.insert(user);
删除
删除也比较简单,可以通过querryWrapper对象进行条件删除,也可以通过
deleteById
通过id来删除userMapper.delete(new QueryWrapper<User>().eq("id", 1)); userMapper.deleteById(1);
以上两种方式都可用于删除
更新
更新则通过
updeteXXX
方法来进行更新User user = new User(); user.setId(1296392290754887684L); //必须要设置id user.setName("oyl"); user.setAge(22); userMapper.updateById(user);
或者通过
querryWrapper
来条件查询更新User user = new User(); user.setName("oyl"); user.setAge(22); userMapper.update(user, new QueryWrapper<User>().eq("id", 1296392290754887684L));
两种方法都可用于更新
5. 返回值
select
方法通常返回对应的实体类或者实体类列表,而其他的三个增删改方法则返回影响的行数
6. 自动填充功能
在<<阿里巴巴Java开发手册>>中有这样的规范:
【强制】表必备三字段:id, gmt_create, gmt_modified。 说明:其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。gmt_create, gmt_modified 的类型均为 datetime 类型,前者现在时表示主动式创建,后者过去分词表示被动式更新
而在业务中如果执行了更新或者插入操作,通常需要手动设置,比较麻烦,因此可以使用MybatisPlus的自动填充功能,如下:
a. 添加注解
@Data
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
}
如上代码中,在两个时间的属性上面,添加@TableField
注解,并且注明填充的时机.
- FieldFill.INSERT : 在插入时填充
- FieldFill.UPDATE : 在更新时填充
- FieldFill.INSERT_UPDATE : 在插入和更新时都填充
b. 实现元对象处理器接口
package com.oylong.mptest.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @ProjectName: mp-test
* @Description:
* @Author: OyLong
* @Date: 2020/8/20 18:34
*/
@Slf4j
@Component //别忘记注入spring容器
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("insertFill....");
this.strictInsertFill(metaObject, "gmtCreate", Date.class, new Date());
this.strictInsertFill(metaObject, "gmtModified", Date.class, new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("updateFill....");
this.strictInsertFill(metaObject, "gmtModified", Date.class, new Date());
}
}
这个实现类其中一个需要注意的点就是别忘记了添加@Component注解
将此类注入spring容器
4. 测试
接下来进行测试,首先插入一个
可以在输出的sql语句上看到,已经成功的自动设置了时间
然后update
也可以在输出的sql语句中看到,自动添加了gmt_modified
这个字段
7. 分页
添加MybatisPlus 分页配置
@Configuration public class MPConfig { @Bean PaginationInterceptor paginationInterceptor(){ return new PaginationInterceptor(); } }
通过
selectPage
方法@Test void selectTest() { Page<User> userPage = userMapper.selectPage(new Page<User>(1, 3), null); List<User> records = userPage.getRecords(); long total = userPage.getTotal(); }
如上,可以通过设置
selectPage
的第一个参数,传入一个Page对象,设置分页的参数,当前页数和每页大小,后面还可以传入一个QueryWrapper
对象用于条件查询.可以通过getRecords
获得所有的记录,getTotal
获得总共的记录数.通过selectMapsPage返回Map对象
我们还可以通过selectMapsPage,这个方法来使返回的列表是一个Map对象,如下
@Test void selectTest() { Page<Map<String, Object>> page = new Page(1,3); Page<Map<String, Object>> mapPage = userMapper.selectMapsPage(page, null); List<Map<String, Object>> records = mapPage.getRecords(); System.out.println(records); }
输出结果:
[{name=Jack, id=2, age=20, email=[email protected]}, {name=Tom, id=3, age=28, email=[email protected]}, {name=Sandy, id=4, age=21, email=[email protected]}]
8. 逻辑删除
逻辑删除表示并不会真正的在数据库中删除对应的记录,而是将某个特定的字段置为特定的值,然后再查询时通过条件将其过滤.
- 先在数据库中添加字段值 idDeleted
在实体类中通过
@TableLogic
注解标注此属性@TableLogic private Integer isDeleted;
public @interface TableLogic { /** * 默认逻辑未删除值(该值可无、会自动获取全局配置) */ String value() default ""; /** * 默认逻辑删除值(该值可无、会自动获取全局配置) */ String delval() default ""; }
通过上面的注解源码可以看到,我们可以设置其是否被删除的默认值,如下:
@TableLogic(value = "0", delval = "1") private Integer isDeleted;
表示未删除时用0表示,删除了用1表示
也可以通过设置全局配置文件的方式来设置默认值:
mybatis-plus: global-config: db-config: logic-delete-value: 1 logic-not-delete-value: 0
测试
执行删除时输出的sql
==> Preparing: UPDATE user SET is_deleted=1 WHERE id=? AND is_deleted=0
==> Parameters: 2(Integer)
<== Updates: 1执行查询时的sql:
==> Preparing: SELECT id,name,age,email,gmt_create,gmt_modified,is_deleted FROM user WHERE is_deleted=0
==> Parameters:可以看到,后面都加上了一个判断,即is_deleted=0来过滤已经被逻辑删除的记录
9.条件构造器
包含以下这些类
- Wrapper : 条件构造抽象类,最顶端父类
- AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
- QueryWrapper : 查询条件封装
- UpdateWrapper : Update 条件封装
- AbstractLambdaWrapper : 使用Lambda 语法
- LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
- LambdaUpdateWrapper : Lambda 更新封装Wrapper
查询方式 | 说明 |
---|---|
setSqlSelect | 设置 SELECT 查询字段 |
where | WHERE 语句,拼接 + WHERE 条件 |
and | AND 语句,拼接 + AND 字段=值 |
andNew | AND 语句,拼接 + AND (字段=值) |
or | OR 语句,拼接 + OR 字段=值 |
orNew | OR 语句,拼接 + OR (字段=值) |
eq | 等于= |
allEq | 基于 map 内容等于= |
ne | 不等于<> |
gt | 大于> |
ge | 大于等于>= |
lt | 小于< |
le | 小于等于<= |
like | 模糊查询 LIKE |
notLike | 模糊查询 NOT LIKE |
in | IN 查询 |
notIn | NOT IN 查询 |
isNull | NULL 值查询 |
isNotNull | IS NOT NULL |
groupBy | 分组 GROUP BY |
having | HAVING 关键词 |
orderBy | 排序 ORDER BY |
orderAsc | ASC 排序 ORDER BY |
orderDesc | DESC 排序 ORDER BY |
exists | EXISTS 条件语句 |
notExists | NOT EXISTS 条件语句 |
between | BETWEEN 条件语句 |
notBetween | NOT BETWEEN 条件语句 |
addFilter | 自由拼接 SQL |
last | 拼接在最后,例如:last(“LIMIT 1”) |
通常使用QuerryWrapper对象的查询方式即可完成大部分的条件查询.