官方文档:https://mp.baomidou.com/
MyBatis-Plus 入门 - 视频教程 - 慕课网:https://www.imooc.com/learn/1130
MyBatis-Plus 进阶 - 视频教程 - 慕课网:https://www.imooc.com/learn/1171
文章目录
一、环境搭建
文件目录结构,一直截图不利于排版,请将后面代码片段对应此图建立
1、创建测试用的数据库和表(直接复制sql语句执行即可,如果不会,请先学习mysql数据库,这是基础中的基础)
#创建数据库
create database `mybatis_plus_test`;
#指定数据库为
use `mybatis_plus_test`;
drop table if exists `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,'testmybatis1@qq.com'),
(2,'Jack',20,'testmybatis2@qq.com'),
(3,'Tom',28,'testmybatis3@qq.com'),
(4,'Sandy',21,'testmybatis4@qq.com'),
(5,'Billie',24,'testmybatis5@qq.com');
2、使用maven引入依赖(mysql版本请根据自己版本装配)(不会的参考以下两篇文章,分别是maven的使用和spring boot的使用以及lombok的使用)
maven:========https://blog.csdn.net/grd_java/article/details/105089100
spring boot:==https://blog.csdn.net/grd_java/article/details/105140042
lombok:=======https://blog.csdn.net/grd_java/article/details/105923234
<parent>
<!--spring boot 父依赖-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependencies>
<!--starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<!--spring boot web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.3.1</version>
</dependency>
<!--整合mybatis-plus和spring boot 的包 这里和以往不同,使用mybatis plus专用整合包-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.2</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
3、创建spring boot启动类(这里不做介绍,上面给出的spring boot链接中有)
package com.testMybatisPlus;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication //标志这个类为spring boot 启动类
@MapperScan(value = "com.testMybatisPlus.mapper") //自动扫描指定包下的mapper映射,有了这个就不需要在配置文件中指定mapper映射了.value="需要扫描的包"
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
4、配置application.yml文件
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver #这个已经淘汰了,如果是8.0版本请使用com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus_test?serverTimeZone=GMT%2B8 #?后面参数表示时区,非常重要,8.0以后的版本是一定需要的,spring boot集成了8.0的驱动,所以要加,这里我先前依赖中添加了5.0版本驱动,不写也行
username: root
password: 123456
5、编写相应实体类
package com.testMybatisPlus.entity;
import lombok.Data;
@Data //lombok工具,为我们自动生成get,set,有了它,如果生效了,类中的字段名会变色,没有则不变
public class User {
/**
* 这里的变量类型和名字应该都和数据库中一一对应
* */
private Long id;
private String name;
private Integer age;
private String email;
}
6、编写持久层接口,mapper映射
package com.testMybatisPlus.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.testMybatisPlus.entity.User;
import org.springframework.stereotype.Repository;
@Repository //让spring boot通过注解将接口扫描到容器中
public interface UserMapper extends BaseMapper<User> {//mybatis plus 中,通用mapper无需配置了,只需要继承BaseMapper即可完成动态关联实体类,后面跟着的泛型就是结果集封装的实体类
/**
* 单表的增删改查,都由通用mapper提供了,
* 使用通用mapper,在mybatis plus中,无需配置,继承BaseMapper类即可,泛型指定结果集封装的实体类
* 但是mybatis依然找不到这些mapper映射文件,这时有两种方法可供选择
* 1、配置mybatis,指定mapper映射的位置
* 2、在spring boot启动类上添加 @MapperScan(Value="映射文件位置")
* 注解,即可自动扫描mapper映射
*
* 若有多表操作,才需要编写抽象方法,若只有单表操作,就无需编写此接口了,继承与通用mapper的方法就够用
*/
}
7、编写service处理业务
package com.testMybatisPlus.service;
import com.testMybatisPlus.entity.User;
import com.testMybatisPlus.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserMapper userMapper; //此处报错是因为接口不能直接创建对象,但是我们使用的是通用mapper,所以忽略即可
public User selectById(Long id){
return userMapper.selectById(id);
}
}
8、编写前端控制器进行测试
package com.testMybatisPlus.Controller;
import com.testMybatisPlus.entity.User;
import com.testMybatisPlus.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserHandler {
@Autowired
private UserService userService;
@GetMapping("selById")
@ResponseBody
public User selById()
{
return userService.selectById(4L);//数字后面跟L才能表示为Long类型数据
}
}
9、测试(若是8.0数据库请向下看)
10、解决8.0mysql的时区问题
- 1、重新设置时区,修改后需要重启才能看到效果
- 2、重新配置application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver #使用最新的驱动类
url: jdbc:mysql://localhost:3306/mybatis_plus_test?serverTimeZone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
#serverTimeZone:设置时区,UTC表示世界通用时区
#useUnicode=true:使用字符集Unicode
#characterEncoding=utf-8:编码为utf-8
#useSSL=false:不使用SSL服务器
username: root
password: 123456
- 3、maven的pom.xml文件中 驱动必须和你的mysql版本对应
- 11、其它问题
二、单表通用mapper进行CRUD(增删改查)
常用注解
@TableName(value="user") //指定实体类对应的表名,一般用于实体类名字不同于数据库表名的时候,其他时候会自动映射
@TableId //指定此字段为主键,用于当表主键不叫id的时候,这时默认使用id作为主键,当然查询不到,用此注解即可标识此
@TableField(value="name") //指定此属性对应表中哪个字段,用于实体类属性名字与表中字段名不匹配的情况下,
@TableField(exist = false)//推荐,exist默认为true表示数据库中存在的字段,当设置为false时,表示这个属性在数据库中没有对应字段
常用条件构造器(全部拷贝官方文档的)
语法
QueryWrapper<User> queryWrapper=new QueryWrapper<>();//条件构造器需要此对象,泛型传入返回的实体类对象
queryWrapper.like("name","%o%").lt("age",40); //对象.条件构造方法1.方法2....的形式判断
userMapper.selectList(queryWrapper); //将条件作为参数传入方法即可
1、eq
等于 =
例: eq("name", "老王")--->name = '老王'
2、ne
不等于 <>
例: ne("name", "老王")--->name <> '老王'
3、gt
大于 >
例: gt("age", 18)--->age > 18
4、ge
大于等于 >=
例: ge("age", 18)--->age >= 18
5、lt
小于 <
例: lt("age", 18)--->age < 18
6、le
小于等于 <=
例: le("age", 18)--->age <= 18
7、between
BETWEEN 值1 AND 值2
例: between("age", 18, 30)--->age between 18 and 30
8、notBetween
NOT BETWEEN 值1 AND 值2
例: notBetween("age", 18, 30)--->age not between 18 and 30
9、like
LIKE '%值%'
例: like("name", "王")--->name like '%王%'
10、notLike
NOT LIKE '%值%'
例: notLike("name", "王")--->name not like '%王%'
11、likeLeft
LIKE '%值'
例: likeLeft("name", "王")--->name like '%王'
12、likeRight
LIKE '值%'
例: likeRight("name", "王")--->name like '王%'
13、isNull
字段 IS NULL
例: isNull("name")--->name is null
14、isNotNull
字段 IS NOT NULL
例: isNotNull("name")--->name is not null
15、in
字段 IN (value.get(0), value.get(1), ...)
例: in("age",{1,2,3})--->age in (1,2,3)
字段 IN (v0, v1, ...)
例: in("age", 1, 2, 3)--->age in (1,2,3)
16、notIn
字段 IN (value.get(0), value.get(1), ...)
例: notIn("age",{1,2,3})--->age not in (1,2,3)
字段 NOT IN (v0, v1, ...)
例: notIn("age", 1, 2, 3)--->age not in (1,2,3)
17、inSql
字段 IN ( sql语句 )
例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)
18、notInSql
字段 NOT IN ( sql语句 )
例: notInSql("age", "1,2,3,4,5,6")--->age not in (1,2,3,4,5,6)
例: notInSql("id", "select id from table where id < 3")--->id not in (select id from table where id < 3)
19、groupBy
分组:GROUP BY 字段, ...
例: groupBy("id", "name")--->group by id,name
20、orderByAsc
排序:ORDER BY 字段, ... ASC
例: orderByAsc("id", "name")--->order by id ASC,name ASC
21、orderByDesc
排序:ORDER BY 字段, ... DESC
例: orderByDesc("id", "name")--->order by id DESC,name DESC
22、orderBy
排序:ORDER BY 字段, ...
例: orderBy(true, true, "id", "name")--->order by id ASC,name ASC
23、having
HAVING ( sql语句 )
例: having("sum(age) > 10")--->having sum(age) > 10
例: having("sum(age) > {0}", 11)--->having sum(age) > 11
24、or
拼接 OR
注意事项:
主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)
例: eq("id",1).or().eq("name","老王")--->id = 1 or name = '老王'
OR 嵌套
例: or(i -> i.eq("name", "李白").ne("status", "活着"))--->or (name = '李白' and status <> '活着')
25、and
AND 嵌套
例: and(i -> i.eq("name", "李白").ne("status", "活着"))--->and (name = '李白' and status <> '活着')
26、nested
正常嵌套 不带 AND 或者 OR
例: nested(i -> i.eq("name", "李白").ne("status", "活着"))--->(name = '李白' and status <> '活着')
27、apply
拼接 sql
例: apply("id = 1")--->id = 1
例: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
28、last
无视优化规则直接拼接到 sql 的最后
例: last("limit 1")
29、exists
拼接 EXISTS ( sql语句 )
例: exists("select id from table where age = 1")--->exists (select id from table where age = 1)
30、notExists
拼接 NOT EXISTS ( sql语句 )
例: notExists("select id from table where age = 1")--->not exists (select id from table where age = 1)
31、select
设置查询字段
例: select("id", "name", "age")
例: select(i -> i.getProperty().startsWith("test"))
=================================修改======================================
UpdateWrapper<User> updateWrapper=new UpdateWrapper<>(); //注意这里使用的是UpdateWrapper
UpdateWrapper.set("name", "老李头");
userMapper.update(User.Class,UpdateWrapper);
1、set
SQL SET 字段
例: set("name", "老李头")
例: set("name", "")--->数据库字段值变为空字符串
例: set("name", null)--->数据库字段值变为null
2、setSql
设置 SET 部分 SQL
例: setSql("name = '老李头'")
1、为了更好理解,我们配置一下日志打印,这样我们执行mapper接口方法时,就有日志参考了(以下是更新后的application.yml文件)
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus_test?serverTimeZone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false #?后面参数表示时区,非常重要
username: root
password: 123456
logging:
level:
root: warn
com.testMybatisPlus.mapper: trace #设置日志输出,帮我监听com.testMybatisPlus.mapper包下的接口日志
pattern:
console: '%p%m%n' #日志格式
2、mybatis plus常用注解,给User实体类加注解,一般用于java实体类与数据库的名称不对应的情况
package com.testMybatisPlus.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data //lombok工具,为我们自动生成get,set,有了它,如果生效了,类中的字段名会变色,没有则不变
@TableName(value="user") //指定实体类对应的表名,一般用于实体类名字不同于数据库表名的时候,其他时候会自动映射
public class User {
/*
* 这里的变量类型和名字应该都和数据库中一一对应
* */
@TableId //指定此字段为主键,用于当表主键不叫id的时候,这时默认使用id作为主键,当然查询不到,用此注解即可标识此字段为主键,从而不使用id作为主键
private Long id;
@TableField(value="name") //指定此属性对应表中哪个字段,用于实体类属性名字与表中字段名不匹配的情况下,
private String name;
private Integer age;
private String email;
/*当我们实体类中需要定义一些属性,而这些属性不存在与数据库时,mybatis plus是依然会自动进行
* 数据库映射的,这时找不着对应字段就会报错,解决这种问题有3种方法*/
private transient String 备注1; //transient关键字可以让这个属性不参与序列化
private static String 备注2; //定义为静态,可以参与序列化,但静态变量不会生成get set方法,也就不会进行映射了
@TableField(exist = false)
private String 备注3; //推荐,exist默认为true表示数据库中存在的字段,当设置为false时,表示这个属性在数据库中没有对应字段
}
3、编写针对User表的UserService(我的UserService)
@Service
public class UserService {
@Autowired
private UserMapper userMapper; //此处报错是因为接口不能直接创建对象,但是我们使用的是通用mapper,所以忽略即可
/**
* 查询
*/
/*根据id查询数据*/
public User selectById(Long id){
return userMapper.selectById(id);
}
/*根据多个id查询*/
public List<User> selectBatchIds(Long ...id){
/**
* 查询id为2,3,4的3条数据
* select * from user where id in (2,3,4)*/
List<Long> list = Arrays.asList(id);//将数组转化为List集合
return userMapper.selectBatchIds(list);
}
/*根据map查询*/
public List<User> selectByMap(Map<String,Object> map){
/**
* 查询姓名为Jone年龄18岁的数据
* select * from user where name = 'Jone' and age = 18*/
return userMapper.selectByMap(map);
}
/*模糊查询(条件构造器查询)like 和 lt小于*/
public List<User> selectList()
{
/**
* 查询名字中包含字母o 年龄小于40的数据
* where name like '%o%' and age<40*/
/*queryWrapper是条件构造器,详情观看官方文档的条件构造器,lt表示小于*/
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.like("name","%o%").lt("age",40);
return userMapper.selectList(queryWrapper);
}
/*between isNotNull*/
public List<User> selectList2()
{
/**
* 名字中包含o,20到25岁之间,邮箱不为null的用户
* where name like '%o%' and
* age between 20 and 40 and
* email is not null
* */
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.like("name", "%o%").between("age", 20, 40).isNotNull("email");
return userMapper.selectList(queryWrapper);
}
/*只展示指定字段,而不将所有字段查询*/
public List<User> selectList3()
{
/**
* 查询名字中包含字母o 年龄小于40的数据
* where name like '%o%' and age<40*/
/*queryWrapper是条件构造器,详情观看官方文档的条件构造器,lt表示小于*/
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
// queryWrapper.select("name","age").like("name","%o%").lt("age",40); select name age from...
/*select 除了name的字段 from...*/
queryWrapper.select(User.class,i -> !i.getProperty().startsWith("name")).like("name","%o%").lt("age",40);
return userMapper.selectList(queryWrapper);
}
/**
* 插入
*/
/*插入数据,依然使用通用mapper提供的方法*/
public void insert(User user){
userMapper.insert(user);
}
/**
* 修改
* */
public void update(User user)
{
userMapper.updateById(user);
}
/**
* 删除,除了selecte换成了delete 其它的和查询一毛一样1
* */
public void delete(Long id)
{
userMapper.deleteById(id);
}
}
4、编写前端控制器Controller中的UserHandler
@Controller
public class UserHandler {
@Autowired
private UserService userService;
/*按id查询*/
@GetMapping("selById")
@ResponseBody
public User selById()
{
return userService.selectById(4L);//数字后面跟L才能表示为Long类型数据
}
/*根据多个id查询*/
@GetMapping("selectBatchIds")
@ResponseBody
public List<User> selectBatchIds(){
return userService.selectBatchIds(2L,3L,4L);
}
/*根据map查询*/
@GetMapping("selectByMap")
@ResponseBody
public List<User> selectByMap(){
Map<String,Object> map=new HashMap<>();
map.put("name","Jone");//注意这里的key 不是java中实体类的属性,而是数据库中字段名,所以名字要和数据库一致
map.put("age",18);
/*使用map 生成的sql语句为 where name='Jone' and age=18*/
return userService.selectByMap(map);
}
/*模糊查询(条件构造器查询)like 和 lt小于*/
@GetMapping("selectList")
@ResponseBody
public List<User> selectList()
{
return userService.selectList();
}
/*between isNotNull*/
@GetMapping("selectList2")
@ResponseBody
public List<User> selectList2(){
return userService.selectList2();
}
/*只显示姓名和年龄*/
@GetMapping("selectList3")
@ResponseBody
public List<User> selectList3(){
return userService.selectList3();
}
/*插入数据*/
@GetMapping("insert")
@ResponseBody
public void insert(){
/*创建User对象,这里我没有给id值,mybatis plus 支持主键生成,我不给会自动帮我生成的*/
User user=new User();
user.setName("new");
user.setAge(15);
user.setEmail("959595@qq.com");
userService.insert(user);
}
/*修改,按id进行修改*/
@GetMapping("update")
@ResponseBody
public void update(){
User user=new User();
user.setId(1L);
user.setName("update");
user.setAge(15);
user.setEmail("update@qq.com");
userService.update(user);
}
/*按id删除*/
@GetMapping("deleteById")
@ResponseBody
public void deleteById()
{
userService.selectById(1L);//数字后面跟L才能表示为Long类型数据
}
}
三、自动填充
什么是自动填充
就是在插入或修改数据时,某些内容无需设置,会按你的要求,自动填充数据
1、数据库中添加两个字段,create_time添加时间,update_time 修改时间
ALTER TABLE `mybatis_plus_test`.`user`
ADD COLUMN `create_time` datetime NULL AFTER `email`,
ADD COLUMN `update_time` datetime NULL AFTER `create_time`;
2、实体类中添加这两个字段,并添加注解
@TableField(fill= FieldFill.INSERT) //添加时做改变
private Date createTime;
@TableField(fill= FieldFill.INSERT_UPDATE) //添加或修改时做改变
private Date updateTime;
3、编写实现类
package com.testMybatisPlus.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/*使用mp(MyBatis plus)添加时执行*/
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
/**
* metaObject:源数据对象,表示当前表中的数据对象
* setFieldValByName:根据名称设置字段的属性值
* 第一个参数 就是要修改的字段名称
* 第二个参数 就是要设置的属性值
* 第三个参数 就是源数据对象,找不到表一切都是空谈
*/
}
/*使用mp进行修改时执行*/
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
4、测试
四、乐观锁(事务隔离级别)
什么是乐观锁
1、乐观锁就是锁数据库版本号的一种方式的简称
当我们多个用户同时操作同一条数据时,有可能发生脏读、不可重复读或幻读,为了避免这些状况,我们可以
为数据库添加一个版本号,当用户1修改数据时,数据库版本就自动更改,假设原来是1,改过后是2。
这时其它用户使用的还是版本1的数据库,修改时就会因为版本不对应问题而无法操作,就避免了问题
1、为数据库添加一个version字段,表示版本号
ALTER TABLE `mybatis_plus_test`.`user`
ADD COLUMN `version` int(10) NULL AFTER `update_time`;
2、实体类中加一个version属性,并添加version注解
@Version //标志此字段是版本号
private Integer version;
3、配置乐观锁插件
package com.testMybatisPlus.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan(value = "com.testMybatisPlus.mapper") //自动扫描指定包下的mapper映射,有了这个就不需要在配置文件中指定mapper映射了,value="需要扫描的包"
public class MpConfig {
//乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
4、测试(乐观锁机制是,你当前看到的内容版本,与真实版本不同,才会生效。也就是你要先查出来看到然后修改才会执行,这也是我们期望的效果)
/*修改,测试乐观锁*/
@GetMapping("updateNew")
@ResponseBody
public void updateNew(){
User user=userService.selectById(1257962056288407554L);//先查指定id的数据
user.setName("updateNew");//然后改
user.setAge(5);
user.setEmail("updateNew@qq.com");
userService.update(user);//执行修改
}
5、需要注意的问题 数据库中version字段不能为null
数据库version字段不能为null,因为它每次执行都是+1,而null+1还是null,无法达到效果
五、分页插件
什么是分页插件:就是数据库的分页查询,查询表时,数据达到一定条数时,自动分页
1、配置分页插件(和乐观锁一样,可以配置在启动类,也可以放置配置类中)
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
2、编写Userservice 分页查询方法(我的UserService类)
/*分页查询*/
public Page<User> testPage()
{
//1、创建page对象,传入两个参数 当前页,每页记录数
Page<User> page = new Page<>(1,3);
//2、调用mp中分页查询方法,所有数据都会封装到page对象中
userMapper.selectPage(page,null);//第二个参数是queryWrapper 条件构造器,这里我们不用,传null
//3、通过page对象获取分页数据
return page;
}
3、编写前端控制器Handler
/*分页查询*/
@GetMapping("testPage")
@ResponseBody
public String testPage()
{
Page<User> page =userService.testPage();
String str=page.getCurrent()+ //当前页
"\n"+page.getPages()+ //总页数
"\n"+page.getRecords()+ //每页数据List集合
"\n"+page.getSize()+ //记录数
"\n"+page.getTotal()+ //总记录数
"\n"+page.hasNext()+ //是否有下一页数据
"\n"+page.hasPrevious();//是否有上一页
System.out.println(str);//浏览器看着不好看,输出到控制台观察比较方便
return str;
}
六、逻辑删除
什么是逻辑删除
删除有两种形式,物理删除和逻辑删除
物理删除:永久删除数据
逻辑删除:通过特定条件,表面上删除了,但实际会根据条件是否成立来删除
比如,我们为表添加一个字段,专门用于判断是否删除,当数据为0时表示
不删除,为1就删除
1、数据库添加字段
2、实体类添加属性和注解
@TableLogic //标志此字段用于逻辑删除
private Integer deleted;
3、测试(注意,这种方法只对mp提供的方法有效,自己写xml需要自己再配置)
4、再查询时,就应该判断deleted的值是不是1,若是1就不显示。mp封装了此判断,无需添加,但我们自己写的时候需要添加where deleted <> 1 或 where deleted =0
七、性能分析插件(3.2.0版本以上已移除,官方推荐使用第三方插件)
什么是性能分析插件:用于跟踪sql语句的执行,查看其执行完毕共耗费多少时间
1、配置性能分析插件
/**
* SQL执行效率插件
*/
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
}