当前位置:   article > 正文

学习笔记 -- MybatisPlus_mybatisplus工作原理

mybatisplus工作原理

一、基础了解

官网

1.1、学前配置

  • 创建一个实体类
public class User {
    private int  id;
    private String username;
    private String password;
    private String address;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 创建一个mapper
public interface UserMapper  {}
  • 1
  • 启动类增加mapper扫描
  • 引入依赖(可以用MybatisPlus的starter代替Mybatis的starter:
    )
<!--MybatisPlus-->
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.5.3.1</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 让自己的mapper继承basemapper
public interface UserMapper extends BaseMapper<User> {}
  • 1

1.2、常用注解

1.2.1、mybatisPlus工作原理

约定大于配置
MyBatisPlus通过扫描实体类,并基于反射获取实体类信息作为数据库表信息。
在这里插入图片描述

  • 实体类和表的映射关系
    1. 类名驼峰转下划线作为表名 uerInfo -> user_info
    2. 名为id的字段作为主键。
    3. 变量名驼峰转F划线作为表的字段名 userName - > user_name

1.2.2、常用注解详解

  • @TableName:用来指定表名。
  • @Tableld:用来指定表中的主键字段信息。
    • value:对应表内主键的名称
    • type:主键增长类型
      • IdType.AUTO:数据库自增长
      • IdType.INPUT:通过set方法自行输入
      • IdType.ASSIGN_ID:分配ID ,接口oldentifierGenerator的方法nextld来生成id,默认实现类为DefaultldentifierGenerator雪花算法。
  • @TableField:用来指定表中的普通字段信息。 使用场景如下
    • 成员变量名与数据库字段名不一致
    • 成员变量名以 is 开头,且是布尔值。
    • 成员变量名与教据库关健字冲突。@TableField(“order”)。
    • 成员变量不是数据库字段。@TableField((exist=false)。

1.3、常用配置

MyBatisPlus的配置项继承了MyBatis原生配置和一些自己特有的配置。

mybatis-plus:
  type-aliases-package: com.po #别名扫持包
  mapper-locations: "classpath*:/mapper/**/*.xml" # Mappe.xml文件地址,默认值
  configuration:
	map-underscore-to-camel-case: true 中是否开启下划线和轮峰的关射
	cache-enabled: false #是否开启二级缓存
  global-config:
	db-config: 
	  id-type: assign_id #id为雪花算法生成
	  update-strategy: not_null #更新策略: 只更新非空字段
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

其他配置官网可查
在这里插入图片描述

二、实战演练

2.1、条件构造器

2.1.1、详解

在这里插入图片描述
条件构造器的"族谱"
在这里插入图片描述
构造器举例
在这里插入图片描述

2.1.2、举例

在这里插入图片描述

1、Query
(1).查询出名字中带o的,存款大于等于1000元的人的id、 username、info、balance字段

sql语句

SELECT id ,username, info , balance
FROM user
WHERE username LIKE ? AND balance >= ?
  • 1
  • 2
  • 3

代码

// 1.构建查询条件
QueryWrapper<User> wrapper=new QueryWrapper<User>()
	.select("id", "username", "info", "balance"')
	.like("username","o")
	.ge("balance",1000);
// 2.查询
List<User> users = userMapper.selectlist(wrapper);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
(2).更新用户名为jack的用户的余额为2000

sql语句

UPDATE user
SET balance = 2000
WHERE (username  = "jack")
  • 1
  • 2
  • 3

代码

// 1. 要更新的数据
new User();
user.setBalance(2000);
// 2.更新的条件
QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "jack");
// 3.执行更新
userMapper.update(user, wrapper);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
2、Update
(1).更新id为1,2,4的用户的余额,扣200

sql语句

UPDATE user
	SET balance = balance - 200
	WHERE id in (1, 2, 4)
  • 1
  • 2
  • 3

代码

	List<Long> ids = List.of(1L, 2L4L);
	UpdateWrapper<User> wrapper = new UpdateWrapper<user>()
		.setSql("balance = balance - 200")
		.in("id", ids) ;
	userMapper.update(null, wrapper);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
3、Lambda
// 1.构建查询条件
LambdaQueryWrapper<User> wrapper  = new LambdaQueryWrapper<User>()
	.select(User::getId, 
			User::getUsername, 
			User::getInfo, 
			User::getBalance)
	.like(User::getUsername, "o")
	.ge(User::getBalance, 1000);
// 2.查询
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
4、总结
  • QueryWrapperLambdaQueryWrapper通常用来构建selectdeleteupdatewhere条件部分。
  • UpdateWrapperLambdaUpdateWrapper通常只有在set语句比较特殊才使用。
  • 尽量使用LambdaQueryWrapperLambdaUpdateWrapper,避免硬编码。

2.2、自定义Sql

我们可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分。

2.2.1、举例

在这里插入图片描述

1、将id在指定范围的用户(例如1. 2. 4 )的余额扣减指定值
  • 原来的实现方式
    在这里插入图片描述
  • 自定义实现
    可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分。
  1. 基于wrapper构建where条件
ListcLong> ids = List.of(1L, 2L4L);
int amount  = 200 ;
// 1. 构建来件
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().in(User::getId, ids);
// 2. 自定XSQL方法调用
userHapper .updateBalanceByIds (wrapper, amount);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 在mapper方法参数中用Param注解声明wrapper变量名称,必须是ew,可以用Constants.WRAPPER属性。
void updateBalanceByIds (@Param("ew") LambdaQueryWrapper<User> wrapper, @Param ("amount") int amount) ;
  • 1
  1. 自定义SQL,并使用Wrapper条件
<update id="updateBalanceByIds">
		UPDATE tb_user SET balance = balance - #{amount} ${ew.customsqtsegment}
</update>
  • 1
  • 2
  • 3

2.3、Service接口

在这里插入图片描述

2.3.1、使用步骤

在这里插入图片描述

  1. 用自己的接口继承mp的接口
    在这里插入图片描述
  2. 自己的实现类实现自己的接口并且继承mp的实现类。
    在这里插入图片描述

2.4、Service实际案例

2.4.1、需求

基于Restful风格实现下面的接口:
在这里插入图片描述

2.4.2、配置

  • pom
<!-- swagger-->
<dependency>  
    <groupId>com.github.xiaoymin</groupId>  
    <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>  
    <version>4.1.0</version>  
</dependency>
<!-- web-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • swagger的简单配置
knife4j:
  enable: true
  openapi :
	title: 用户管理接口文档
    description: "用户管理接口文档"
    email:  
	concat: 作者
	url: https://www.xxx.cn
	version: V1.0.0
	group:
	  default:
	    group-name: default
	    api-rule: package
	    api-rule-resources :
		- com.ai.www.controller
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.4.3、controller

@Api(tags="用户管理接口") 
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor//只会为需要注入的变量注入(加final或者@NonNull就是可以自动注入的)
public class UserController {
	//@Autowired
	//private IUserService userService;//spring不推荐
	
	private final IUserService userService;

	@ApiOperation("新增用户接口")
	@PostMapping
	public void saveUser (@RequestBody UserFormDTO userDTO){
		// 1. 把DTO拷贝到PO
		User user = Beanutil.copyProperties(userDT0, User.class) ;
	// 2.新增
		userService.save(user);
	}

	@ApiOperation("删除用户接口")
	@DeleteMapping("{id}")
	public void deleteUserById(@ApoParam("用户ID") @Pathvariable("id") Long id{
		userService.removeById(user);
	}

	@ApiOperation("根据id查询用户接口")
	@GetMapping("{id}")
	public UserVo queryUserById(@ApiParam("用户id") @PathVariable("id") Long id) {
		// 1.查询用户PO
		User user = userservice. getById(id);
		// 2. 把PO拷贝到Vo
		return BeanUtil.copyProperties(user, UserVo.class) ;
	}

	@ApiOperation("根据id批最查询用户接口")
	@GetMapping
	public List<UserVO> queryUserByIds(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids) {
		// 1.查沟用户PO
		List<User> users = userService.listByIds(ids);
		// 2. 把PO拷贝到Vo
		return Beanutil.copyTolist(users, Uservo.class);
	}
	
	
	@ApiOperation("扣减用户余额接口")
	@PutMapping("/{id}/deduction/{money}")
	public void deductMoneyById(@ApiParam("用户id")@Pathvariable("id") Long id,
								@ApiParam("扣减的金额")@PathVariable("money") Integer money){
		userService.removeById(id);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

2.4.4、Mapper

代码

public interface UserMapper extends BaseMapper<user> {
		List<User> queryUserByIds(@Param("ids") List<Long> ids);
		
		void updateBalanceByIds(@Param(Constants.WRAPPER) {Querywrapper<User> wrapper, @Param("anount") int amount);
		
		@Update("UPDATE tb_user SET balance = balance - #{money} WHERE id = #{id}")
		void deductbalance (@Param("id") Long id, @Param("money")Integer money);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

mapper文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxx.mp.mapper.UserMapper">
	<update id="updateBalanceByIds">
		UPDATE tb_user SET balance = balance  - #{amount} ${ew.customSqlSegment}
	</update>
	<select id="queryUserByIds" resultType="com.xxx.mp.donain.po.User">
		SELECT *  
		FROM tb_user
		<if test="ids != null">
			WHERE id IN
			<foreach collection="ids" open="(" close=")" item="id" separator=",">
				#{id}
			</foreach>
		</if>
		LIMIT 10;
	</select>
</mapper>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

2.4.5、doman包

  • UserFromDto
@Data
@ApiModel(description = "用户表单实体")
public class UserFormDTO {

	@ApiModelProperty("id")
	private Long id;
	@ApiModelProperty("用户名")
	private string username;
	@ApiModelProperty("密码")
	private string password;
	@ApiModetProperty("注册手机号")
	private String phone;
	@ApiModelProperty("详细信息,JSON风格")
	private string info;
	@ApiModelProperty("账户余额")
	private Integer balance;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • userPo
@Data
@TableName("tb_user")
public class pser {
	//用户id
	// @TableId(type.IdType.AUTO)
	private Long id;
	
	//用户名
	// @TableField("username“")
	private string username;
	
	//密码
	// @TableField(exist = false)
	private string password;
	//注册手机号
	private string phone;

	//详细信息
	private string info;
	
	//使用状态(1正常2陈结)
	private Integer status;

	//账户余额
	private Integer balance;
	
	//创建时间
	private LocalDateTime createTime;

	//更新时间
	private LocalDateTime updateTime;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • userVo
@Data
@ApiModel (description="用户Vo实体")
public class UserVo {
	@ApiModelProperty("用户id"')
	private Long id;
	
	@ApiModetProperty("用户名")
	private string user name;
	
	@ApiModelProperty("详细信息")
	private String info;
	
	@ApiModelProperty("使用状态(1正常2陈结) ")
	private Integer status;
	
	@ApiModelProperty("账户余额")
	private Integer balance;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2.4.6、Service

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
	@Override
	public void deductBalance(Long id, Integer money) {
		// 1. 查询用户
		User user = this.getById(id);
		// 2.校验用户状态
		if (user == null || user.getstatus() == 2){
			throw new RuntimeException("用户状态异常! ");
		}
		// 3. 校验余额是否充足
		if (user.getBalance() < money) {
			throw new RuntimeException("用户余额不足! ");
		}
		// 4.扣减余额update tb_ user set balance = balance  -?
		baseMapper.deductBlance(id, money);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2.5、Service的Lambda实际案例

2.5.1、查询案例

1、需求

需求:实现一个根据复杂条件查询用户的接口,查询条件如下:

  • name:用户名关键字,可以为空。
  • status:用户状态,可以为空。
  • minBalance:最小余额,可以为空。
  • maxBalance:最大余额,可以为空。
    原版实现
    在这里插入图片描述
2、代码
@Apioperat ion("根据复杂条件查询用户接口")
QGetMapping("/List")
public List<UserVo> queryusers(Userquery query){
	// 1. 查淘用户PO
	List<user> users = userService.queryUsers(query.getName(),query.getstatus(),query.getaxBalance(), query.getMaxBalance())
	// 2. PO 拷贝到Wo
	return Beanutil.copyTolist(users, Uservo.class);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • service
    注意lambdaQuery() 可以换成Db.lambdaQuery,当然可以直接导包
@Override
public List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {
	return lambdaQuery()
			.like(name != null, User::getUsername,name)
			.eq(status != null, User::igetstatus, status)
			.gt(minBalance != null,User::getBalance,minBalance)
			.lt(maxBalance != null, User::getBalance, maxBalance)
			.list();//其他查询方法看编译器提醒就行
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.5.2、更新案例

1、需求

需求:改造根据id修改用户余额的接口,要求如下:

  • 完成对用户状态校验
  • 完成对用户余额校验
  • 如果扣减后余额为0,则将用户status修改为冻结状态(2)
2、代码

@Transactional
public void deductBalance(Long id, Integer money) {
	// 1.查询用户
	User user = getById(1d);
	// 2.校验用户状态
	if (user == null | user.getstatus() == 2) {
		throw new Runt imeExcept ion("用户状态异常! ");
	}
	// 3. 校验余额是否充足
	if (user.getBalance() < money) {
		throw new RuntimeExcept ion("用户余额不足! ");
	}
	// 4.加减余额 update tb_user set balonce = balance - 1
	int remainBalance = user.getBalance() - money;
	lambdaUpdate()
			.set(User::getBalance, remainBalance)
			.set(remainBalance == 0, User::getstatus, 2)
			.eq(User::getId, id)
			.eq(User::getBalance(), user::getBalance())//加锁,乐观锁,防止并发一起改
			.update();

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2.5.3、批处理案例

连接时拼上参数

&rewriteBatchedStatements=true
  • 1

三、拓展功能

3.1、代码生成

在这里插入图片描述

使用方式

新版在Tools,旧版在上面的Other
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2、DB静态工具

import com.baomidou.mybatisplus.extension.toolkit.Db;
在这里插入图片描述

3.1、实例

需求:

  • 改造根据id查询用户的接口,查询用户的同时,查询出用户对应的所有地址。
@Override
public Uservo queryUserAndAddressById(Long id) {
	// 1.查询用户
	User user = getById(4L) ;
	if (user = null || user .getstatus() == 2) {
		throw new Runt imeException("用户状态异常! ");
	}
	// 2.查询地址
	List<Address> addresses = Db.lambdaQuery(Address.class).eq(Address::getUserId,id).1ist();
	// 3.对Vo 
	// 3.1.转User的PO%为V0
	UserVo userVo = BeanUtil.copyProperties(user, Uservo.class);
	// 3.2.转地hv0 
	if (CollUtil.isNotEmpty(addresses)) {
		uservo.setAddresses(BeanUtil.copyToList(addresses, AddressVo.class));
	}
	return uservo;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 改造根据id批量查询用户的接口,查询用户的同时,查询出用户对应的所有地址。
	// 1.查询用户
	List<User> users = listByIds(ids);
	if (Collutil.isEmpty(users)) {
		return Collections.emptylist();
	}
	// 2.查询地址
	// 2.1.获收用户id集合
	List<Long> userIds = users.stream().map(User::getId).collect(Collectors.tolist());
	// 2.2. 根据用户id查询地址
	List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId,userIds).list();
	// 2.3. 转换地址VO
	List<AddressVo> addressVoList = BeanUtil.copyTolist(addresses, AddressVo.class);
	// 2.4.用户地址集合分出处理,相同用户的放入一个集合(组)中
	Map<Long,List<AddressVo>> addressMap = new HashMap<>(0) ;
	if(CollUtil.isNotEmpty(addressVoList )){
		addressMap = addressVoList.stream().collect(Collectors.groupingBy(Addressvo::getUserId));
	}
	// 3.转换Vo返回
	List<UserVo> list = new ArrayList<>(users.size());
	for (User user : users) {
		// 3.1.转换User MPO为VO
		UserVO vo = BeanUtil.copyProperties(user,Uservo.class);
		list.add(vo);
		// 3.2.转换地hVO 
		vo.setAddresses(adlressMap.get(user.getId());
	}
	return list;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

3.3、逻辑删除

逻辑删除就是基于代码逻辑模拟删除效果,但并不会真正删除数据。

3.3.1、实现思路

  • 在表中添加一个字段标记数据是否被删除。
  • 当删除数据时把标记置为1。
  • 查询时,只查询标记为0的数据。

删除操作
在这里插入图片描述
查询操作
在这里插入图片描述

3.3.2、配置方式

MybatisPlus提供了逻辑删除功能,无需改变方法调用的方式,而是在底层自动修改CRUD的语句。我们要做的就是在application.yaml文件中配置逻辑删除的字段名称和值即可。

mybatis-plus:
  globa1-config:
	db-config:
	  logic-delete-field: flag #全局逻辑删除的实体字段名,字服类型可以是boolean, integer
	  logic-delete-value: 1 #逻辑已删除值(默认为1)
	  logic-not-delete-value: 0 #逻辑未删除值(默认为0)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.3.3、注意

  • 逻辑删除本身也有自己的问题,比如:
    • 会导致数据库表垃圾数据越来越多, 影响查询效率。
    • SQL中全都需要对逻辑删除字段做判断,影响查询效率。
  • 因此,不太推荐采用逻辑删除功能,如果数据不能删除,可以采用把数据迁移到其它表的办法。

3.4、枚举处理器

在这里插入图片描述

3.4.1、使用方法

修改配置

mybatis-plus:
  configuration:
    default-enum-type-handter: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
  • 1
  • 2
  • 3

枚举加注解

@Getter
public enum UserStatus {
	NORMAL(1, "正常"),
	FROZEN(2, "冻结"),
	;
	@EnumValue
	@JsonValue()//枚举返回值,返回给前端value值
	private final int value;
	private final String desc;
	
	UserStatus(int value, String desc) {
		this.value = value;
		this.desc = desc;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

3.5、Json处理器

在这里插入图片描述

3.5.1、使用方式

@Data
@TableName ( value= "user", autoResultMap = true )
public class User {

	private Long id;
	
	private String username;
	
	@TableField(typeHandler = JacksonTyeHandler.class)
	private UserInfo info;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
@Data
public class  UserInfo {
	private Integer age;
	private String intro;
	private String gender;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

四、插件功能

MyBatisPlus提供的内置拦截器有下面这些:
在这里插入图片描述

4.1、分页插件

4.1.1、配置

@Configuration
public class MybatisConfig {
	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		// 1.初始化核心播件
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		// 2. 添加分页插件
		PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
		pageInterceptor.setMaxLimit(1000L); //设置分页上限
		interceptor.addInnerInterceptor(pageInterceptor);
		return interceptor;
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

4.1.2、简单示例

@Test
void testPageQuery() {
	// 1.查询
	int pageNo = 1, pageSize = 5;
	// 1.1.分页参数
	Page<User> page = Page.of(pageNo, pageSize) ;
	// 1.2. 排序参数,通orderItem来指定
	page.addOrder(new OrderItem("balance", false)); 
	// 1.3. 分页查询
	Page<User> p = userService.page(page);
	// 2.总来数
	System.out.println("total = " + p.getTotal());
	// 3.总页数
	System.out.println("pages = " + p.getPages());
	// 4.分页数据
	List<User>records  = p.getRecords();
	records.forEach(System.out::println);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

4.1.3、通用分页实体

1、请求实体

其他的查询继承此类即可

@Data
@ApiModel (description ="分页查削实体")
public class PageQuery{

	@ApiModelProperty("页码")
	private Integer pageNo;
	
	@ApiModeProperty("页码")
	private Integer pagesize;
	
	@ApiModelProperty("排序字段")
	private String sortBy;
	
	@ApiModelProperty("是否升序")
	private Boolean isAsc ;

	public <T> Page<T> toMpPage(orderItem ... items){
		// 1.分页条件
		PagecT> page = Page.of(pageNo, pagesize);
		// 2.排序条件
		if(StrUtil.isNotBlank(sortBy)){
			//不为空
			page.addorder(new orderItem(sortBy, isAsc));
		}else if(items != null){
			//为空默以招序
			page.addorder (items);
		}
		return page;
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
2、返回值实体
@Data
@ApiModel (description = "分页结果")
public class PageDTO<T> {

	QApiModelProperty("总条数")
	private Integer total;
	
	QApiModelProperty("总页数")
	private Integer pages;
	
	@ApiModetProperty("集合")
	private List<T> list;
	
public static <Po,Vo>PageDTO<VO> of(Page<Po> p,Class<Vo> clazz){
	PageDTO<VO> dto = new PageDT0<>();
	// 1.总条数
	dto.setTotal(p.getTotal());
	// 2.总页数
	dto.setPages(p.getPages());
	// 3.当前页数
	List<userPo> records = p.getRecords();
	if (Collutil.isEmpty(records)) {
		dto.setList(Collections.emptylist());
		return dto; 
	}
	// 4.拷贝V0
	dto.setList(BeanUtil.copyTolist(records, clazz));
	// 5.返回
	return dto;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

4.1.4、完整示例

遵循下面的接口规范,编写一个UserController接口, 实现User的分页查询。
在这里插入图片描述
省略其他一些东西,直接核心代码

service 代码
注意lambdaQuery() 可以换成Db.lambdaQuery,当然可以直接导包

@override
public PageDTocUserV0> quer yUser sPage (UserQuery query) {
	String name = query.getName();
	Integer status = query.getstatus();
	// 1. 构建分页条件
	// 1.1.分页条件
	Page<User> page = Page.of(query.getPageNo(), query.getPagesize());
	// 1.2.那序条件
	if(Strutil.isNotBlank(query.getSortBy())){
		//不为空
		page.addOrder(new orderItem(query.getSorBy(), query.getIsAsc());
	}else{
		//为空,默认按照更新时间排序
		page.addOrder(new OrderItem("update_time", false));
	// 2.分页查询
	Page<User> p = lambdaQuery()
						.like(nane != null, User::getUsername, nane)
						.eq(status != null, User::gotStatus, status) 
						.page(page);
	// 3.封装Vo结果
	PageDTO<UserVo> dto = new PageDTO<>();
	// 3.1.总条数
	dto.setTotal(p.getTotal());
	// 3.2.总页数
	dto.setPages(p.getPoges());
	// 3.3. 当前页数据
	List<User> records = p.getRecords(); 
		if(CollUtil.isEmpty(records)) {
			dto.setList(Collections.emptylist();
			return dto;
	}
	// 3.4.传userVO
	dto.setList(Beanutil.copyTolist(records,UserVo.class));
	// 4.返回
	return dto;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/661678
推荐阅读
相关标签
  

闽ICP备14008679号