电子商务网站的建设开发工具科技创新作文

当前位置: 首页 > news >正文

电子商务网站的建设开发工具,科技创新作文,吉林市网站制作,吉林建设公司网站MybatisPlus 1. 快速入门1.1 入门案例1.2 常见注解1.3 常见配置 2. 核心功能2.1 条件构造器2.2 自定义SQL2.3 Service接口 3. 扩展功能3.1 代码生成3.2 静态工具3.3 逻辑删除 4. 插件功能4.1 分页插件4.2 通用分页实体 1. 快速入门 1.1 入门案例 步骤一#xff1a;引入Mybat… MybatisPlus 1. 快速入门1.1 入门案例1.2 常见注解1.3 常见配置 2. 核心功能2.1 条件构造器2.2 自定义SQL2.3 Service接口 3. 扩展功能3.1 代码生成3.2 静态工具3.3 逻辑删除 4. 插件功能4.1 分页插件4.2 通用分页实体 1. 快速入门 1.1 入门案例 步骤一引入MybatisPlus的起步依赖 MyBatisPlus官方提供了starter,其中集成了Mybatis和MybatisPlus的所有功能,并且实现了自动装配效果。 因此我们可以用MybatisPlus的starter代替Mybatis的starter: dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.3.1/version /dependency步骤二定义Mapper继承MybaitsPlus提供的BaseMapper接口 import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.itheima.mp.domain.po.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param;import java.util.List;Mapper public interface UserMapper extends BaseMapperUser { }注BaseMapper中已经定义了常用的CURD方法 步骤三调用接口中的方法进行测试 1.2 常见注解 MyBatisPlus通过扫描实体类并基于反射获取实体类信息作为数据库表信息。 MybatisPlus中比较常用的几个注解如下 TableName: 用来指定表明TableId: 用来指定表中的主键字段信息TableField: 用来指定表中的普通字段信息 IdType枚举 AUTO: 数据库自增长 INPUT: 通过set方法自行输入 ASSIGN_ID: 分配ID接口IdentifierGenerator的方法nextId来生成id默认实现类为DefaultIdentifierGenerator雪花算法 使用TableFidle的常见场景 成员变量名与数据库字段名不一致 成员变量名以is开头且是布尔值 成员变量名与数据库关键字冲突 成员变量不是数据库字段 1.3 常见配置 MyBatisPlus的配置项继承了MyBatis原生配置和一些自己特有的配置。例如 mybatis-plus:mapper-locations: classpath:mapper/**/.xml # Mapper.xml文件地址默认值type-aliases-package: com.itheima.mp.domain.po # 别名扫描包configuration:map-underscore-to-camel-case: true # 是否开启下户线和驼峰的映射cache-enabled: false # 是否开启二级缓存global-config:db-config:id-type: assign_id # id为雪花算法生成update-strategy: not_null # 更新策略2. 核心功能 2.1 条件构造器 刚才的案例中都是以id为条件的简单CRUD一些复杂条件的SQL语句就要用到一些更高级的功能了。 参数中的Wrapper就是条件构造的抽象类其下有很多默认实现继承关系如图 Wrapper的子类AbstractWrapper提供了where中包含的所有条件构造方法 而QueryWrapper在AbstractWrapper的基础上拓展了一个select方法允许指定查询字段 而UpdateWrapper在AbstractWrapper的基础上拓展了一个set方法允许指定SQL中的SET部分 QueryWrapper无论是修改、删除、查询都可以使用QueryWrapper来构建查询条件。查询查询出名字中带o的存款大于等于1000元的人。代码如下 SpringBootTest public class UserWrapperTest {ResourceUserMapper userMapper;Testvoid testQueryWrapper(){// 1.构建查询条件 where name like %o% AND balance 1000QueryWrapperUser wrapper new QueryWrapperUser().select(id, username, info, balance).like(username, o).ge(balance, 1000);// 2. 查询数据ListUser users userMapper.selectList(wrapper);users.forEach(System.out::println);}UpdateWrapper 更新用户名为jack的用户的余额为2000代码如下 SpringBootTest public class UserWrapperTest {ResourceUserMapper userMapper;Testvoid testUpdateWrapper(){// 1.构建查询条件 set balance 20000 where name JackUpdateWrapperUser wrapper new UpdateWrapperUser().setSql(balance 2000).eq(username, jack);// 2. 查询数据int update userMapper.update(null, wrapper);System.out.println(update);} }更新id为1,2,4的用户的余额扣200代码如下 SpringBootTest public class UserWrapperTest {ResourceUserMapper userMapper;Testvoid testUpdateBatchWrapper(){// 1.构建查询条件UpdateWrapperUser wrapper new UpdateWrapperUser().setSql(balance balance - 200) // SET balance balance - 200.in(id,List.of(1L, 2L, 4L)); // // WHERE id in (1, 2, 4)// 2. 查询数据,注意第一个参数可以给null也就是不填更新字段和数据而是基于UpdateWrapper中的setSQL来更新int update userMapper.update(null, wrapper);System.out.println(update);}}无论是QueryWrapper还是UpdateWrapper在构造条件的时候都需要写死字段名称会出现字符串魔法值。这在编程规范中显然是不推荐的。那怎么样才能不写字段名又能知道字段名呢其中一种办法是基于变量的gettter方法结合反射技术。因此我们只要将条件对应的字段的getter方法传递给MybatisPlus它就能计算出对应的变量名了。而传递方法可以使用JDK8中的方法引用和Lambda表达式。 因此MybatisPlus又提供了一套基于Lambda的Wrapper包含两个 LambdaQueryWrapperLambdaUpdateWrapper 分别对应QueryWrapper和UpdateWrapper SpringBootTest public class UserWrapperTest {ResourceUserMapper userMapper;Testvoid testLambdaQueryWrapper(){// 1.构建查询条件 where name like %o% AND balance 1000LambdaQueryWrapperUser wrapper new LambdaQueryWrapperUser().select(User::getId, User::getUsername, User::getInfo, User::getBalance).like(User::getUsername, o).ge(User::getBalance, 1000);// 2. 查询数据ListUser users userMapper.selectList(wrapper);users.forEach(System.out::println);}Testvoid testLambdaUpdateWrapper(){// 1.构建查询条件LambdaUpdateWrapperUser wrapper new LambdaUpdateWrapperUser().setSql(balance 2000).eq(User::getUsername, jack);// 2. 查询数据int update userMapper.update(null, wrapper);System.out.println(update);} }2.2 自定义SQL 在演示UpdateWrapper的案例中我们在代码中编写了更新的SQL语句 Testvoid testUpdateBatchWrapper(){// 1.构建查询条件UpdateWrapperUser wrapper new UpdateWrapperUser().setSql(balance balance - 200) // SET balance balance - 200.in(id,List.of(1L, 2L, 4L)); // // WHERE id in (1, 2, 4)// 2. 查询数据,注意第一个参数可以给null也就是不填更新字段和数据而是基于UpdateWrapper中的setSQL来更新int update userMapper.update(null, wrapper);System.out.println(update);}这种写法在某些企业也是不允许的因为SQL语句最好都维护在持久层而不是业务层。MybatisPlus提供了自定义SQL功能先利用Wrapper来构建复杂的where条件再结合Mapper.xml或注解自己编写SQL语句。 核心思想将where条件使用Wrapper来构建然后在Mapper.xml进行调用即可 2.3 Service接口 MybatisPlus不仅提供了BaseMapper还提供了通用的Service接口及默认实现封装了一些常用的service模板方法。 通用接口为IService默认实现为ServiceImpl其中封装的方法可以分为以下几类 save新增remove删除update更新get查询单个结果list查询集合结果count计数page分页查询 自定义Service接口继承IService接口 自定义Service实现类实现自定义接口并集成ServiceImpl类 由于Service中经常需要定义与业务有关的自定义方法因此我们不能直接使用IService而是自定义Service接口然后继承IService以拓展方法。同时让自定义的Service实现类继承ServiceImpl这样就不用自己实现IService中的接口了。 首先定义IUserService继承IService package com.itheima.mp.service;import com.baomidou.mybatisplus.extension.service.IService; import com.itheima.mp.domain.po.User;public interface IUserService extends IServiceUser {// 拓展自定义方法 }然后编写UserServiceImpl类继承ServiceImpl实现UserService package com.itheima.mp.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.itheima.mp.domain.po.User; import com.itheima.mp.domain.po.service.IUserService; import com.itheima.mp.mapper.UserMapper; import org.springframework.stereotype.Service;Service public class UserServiceImpl extends ServiceImplUserMapper, User implements IUserService { }接下来实现下面5个接口 首先引入依赖 !–swagger– dependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-openapi2-spring-boot-starter/artifactIdversion4.1.0/version /dependency !–web– dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId /dependency然后需要配置swagger信息 knife4j:enable: trueopenapi:title: 用户管理接口文档description: 用户管理接口文档email: xxxxxconcat: xxxxurl: xxxxversion: v1.0.0group:default:group-name: defaultapi-rule: packageapi-rule-resources:- com.itheima.mp.controller导入相关的UserVo、UserDTO、UserFormDTO(前端传入参数较多的时候封装成类) UserController package com.itheima.mp.controller;import cn.hutool.core.bean.BeanUtil; import com.itheima.mp.domain.dto.UserFormDTO; import com.itheima.mp.domain.po.User; import com.itheima.mp.domain.vo.UserVO; import com.itheima.mp.service.IUserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.;import javax.annotation.Resource; import java.util.ArrayList; import java.util.List;/** author Mr.Lu* version 1.0* date 2024-08-13 20:57/RequestMapping(/users) RestController Slf4j Api(tags 用户管理接口) public class UserController {Resourceprivate IUserService userService;PostMappingApiOperation(新增用户)public void saveUser(RequestBody UserFormDTO userFormDTO){User user new User();BeanUtil.copyProperties(userFormDTO, user);userService.save(user);}DeleteMapping(/{id})ApiOperation(删除用户)public void removeUserById(PathVariable(id) Long userId){userService.removeById(userId);}GetMapping(/{id})ApiOperation(根据id查询用户)public UserVO queryUserById(PathVariable(id) Long userId){User user userService.getById(userId);UserVO userVO new UserVO();BeanUtil.copyProperties(user, userVO);return userVO;}GetMappingApiOperation(根据ids查询批量用户)public ListUserVO queryUserByIds(RequestParam(ids) ListLong ids){ListUser users userService.listByIds(ids);ListUserVO userVOS BeanUtil.copyToList(users, UserVO.class);return userVOS;}PutMapping(/{id}/deduction/{money})ApiOperation(根据id更新金额)public void deduction(PathVariable(id) Long id, PathVariable Integer money){userService.deduction(id, money);}} UserServiceImpl 特别注意ServiceImpl已经注入了badeMapper(泛型指定为userMapper),所以可以直接调用mapper无需注入 package com.itheima.mp.service.impl;import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.itheima.mp.domain.po.User; import com.itheima.mp.mapper.UserMapper; import com.itheima.mp.service.IUserService; import org.springframework.stereotype.Service;/** author Mr.Lu* version 1.0* date 2024-08-13 20:53/Service public class UserServiceImpl extends ServiceImplUserMapper, User implements IUserService {Overridepublic void deduction(Long id, Integer money) {// 1.查询用户User user getById(id);// 2.判断用户状态if (user null || user.getStatus() 2) {throw new RuntimeException(用户状态异常);}// 3.判断用户余额if (user.getBalance() money) {throw new RuntimeException(用户余额不足);}// 4.扣减余额LambdaUpdateWrapperUser wrapper new LambdaUpdateWrapperUser().eq(User::getId, id);baseMapper.deduction(money, warpper);} } IUserService package com.itheima.mp.service;import com.baomidou.mybatisplus.extension.service.IService; import com.itheima.mp.domain.po.User;/** author Mr.Lu* version 1.0* date 2024-08-13 20:52*/public interface IUserService extends IServiceUser {void deduction(Long id, Integer money); } UserMapper package com.itheima.mp.mapper;import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.itheima.mp.domain.po.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Update;Mapper public interface UserMapper extends BaseMapperUser {Update(update tb_user set balance balance - #{money} ${ew.customSqlSegment})void deduction(Param(money)Integer money, Param(ew)LambdaUpdateWrapperUser wrapper); } IService中还提供了Lambda功能来简化我们的复杂查询及更新功能。我们通过两个案例来学习一下。 案例一实现一个根据复杂条件查询用户的接口查询条件如下 name用户名关键字可以为空status用户状态可以为空minBalance最小余额可以为空maxBalance最大余额可以为空 可以理解成一个用户的后台管理界面管理员可以自己选择条件来筛选用户因此上述条件不一定存在需要做判断。 首先定义一个查询条件实体UserQuery实体 package com.itheima.mp.domain.query;import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data;Data ApiModel(description 用户查询条件实体) public class UserQuery {ApiModelProperty(用户名关键字)private String name;ApiModelProperty(用户状态1-正常2-冻结)private Integer status;ApiModelProperty(余额最小值)private Integer minBalance;ApiModelProperty(余额最大值)private Integer maxBalance; }在UserController中定义一个controller方法 GetMapping(/list) ApiOperation(根据id集合查询用户) public ListUserVO queryUsers(UserQuery query){// 1.组织条件String username query.getName();Integer status query.getStatus();Integer minBalance query.getMinBalance();Integer maxBalance query.getMaxBalance();LambdaQueryWrapperUser wrapper new QueryWrapperUser().lambda().like(username ! null, User::getUsername, username).eq(status ! null, User::getStatus, status).ge(minBalance ! null, User::getBalance, minBalance).le(maxBalance ! null, User::getBalance, maxBalance);// 2.查询用户ListUser users userService.list(wrapper);// 3.处理voreturn BeanUtil.copyToList(users, UserVO.class); }在组织查询条件的时候我们加入了 username ! null 这样的参数意思就是当条件成立时才会添加这个查询条件类似Mybatis的mapper.xml文件中的标签。 案例二批量新增,修改项目中的application.yml文件在jdbc的url后面添加参数rewriteBatchedStatementstrue Test void testSaveBatch() {// 准备10万条数据ListUser list new ArrayList(1000);long b System.currentTimeMillis();for (int i 1; i 100000; i) {list.add(buildUser(i));// 每1000条批量插入一次if (i % 1000 0) {userService.saveBatch(list);list.clear();}}long e System.currentTimeMillis();System.out.println(耗时 (e - b)); }3. 扩展功能 3.1 代码生成 3.2 静态工具 有的时候Service之间也会相互调用为了避免出现循环依赖问题MybatisPlus提供一个静态工具类Db其中的一些静态方法与IService中方法签名基本一致也可以帮助我们实现CRUD功能 1. 改造根据id查询用户的接口查询用户的同时查询出用户对应的所有地址改造 Overridepublic UserVO queryUserAndAddress(Long userId) {// 1. 查询用户信息User user (User) Db.getById(userId, User.class);// 2. 判断用户是否存在if(user null) return null;// 3. 查询用户地址ListAddress address Db.lambdaQuery(Address.class).eq(Address::getUserId, userId).list();// 类型转换UserVO userVO BeanUtil.copyProperties(user, UserVO.class);ListAddressVO addressVOList BeanUtil.copyToList(address, AddressVO.class);userVO.setAddresses(addressVOList);return userVO;}2. 根据id批量查询用户的接口查询用户的同时查询出用户对应的所有地址 public ListUserVO queryUsersAndAddresses(ListLong ids) {// 1. 批量查询用户ListUser users Db.listByIds(ids, User.class);if(CollUtil.isEmpty(users)){return Collections.emptyList();}users.forEach(System.out::println);// 2. 查询地址// 需要重新获取userIds不能再直接使用ids, userIds保证都是存在的用户ListLong userIds users.stream().map(User::getId).collect(Collectors.toList());ListAddress addresses Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();ListAddressVO addressVOList BeanUtil.copyToList(addresses, AddressVO.class);MapLong, ListAddressVO addressMap new HashMap(0);if(CollUtil.isNotEmpty(addressVOList)){addressMap addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));}// 3. 转换VO返回ListUserVO list new ArrayList(users.size());for(User user : users){UserVO userVO BeanUtil.copyProperties(user, UserVO.class);userVO.setAddresses(addressMap.get(user.getId()));list.add(userVO);}return list;}3.3 逻辑删除 对于一些比较重要的数据我们往往会采用逻辑删除的方案即 在表中添加一个字段标记数据是否被删除当删除数据时把标记置为true查询时过滤掉标记为true的数据 一旦采用了逻辑删除所有的查询和删除逻辑都要跟着变化非常麻烦。开启了逻辑删除功能以后我们就可以像普通删除一样做CRUD基本不用考虑代码逻辑问题。还是非常方便的。 然后给Address实体添加deleted字段 在application.yml中配置逻辑删除字段 mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)测试 Testvoid testDeleteByLogic() {// 删除方法与以前没有区别addressService.removeById(59L);}Testvoid testQuery() {ListAddress list addressService.list();list.forEach(System.out::println);}逻辑删除本身也有自己的问题比如 会导致数据库表垃圾数据越来越多从而影响查询效率SQL中全都需要对逻辑删除字段做判断影响查询效率 因此我不太推荐采用逻辑删除功能如果数据不能删除可以采用把数据迁移到其它表的办法

  1. 插件功能 4.1 分页插件 在未引入分页插件的情况下MybatisPlus是不支持分页功能的IService和BaseMapper中的分页方法都无法正常起效。 所以我们必须配置分页插件。 配置分页插件 编写一个分页查询的测试 Testvoid testPage(){int pageNo 1, pageSize 2;// 1. 分页参数PageUser page Page.of(pageNo, pageSize);// 1.1 设置排序条件page.addOrder(new OrderItem(balance, true));page.addOrder(new OrderItem(id, true));// 2. 分页查询PageUser p userService.page(page);// 3. 解析long total p.getTotal();System.out.println(total: total);long pages p.getPages();System.out.println(pages: pages);ListUser users p.getRecords();users.forEach(System.out::println);}4.2 通用分页实体 现在要实现一个用户分页查询的接口接口规范如下 返回值 需要定义3个实体 UserQuery分页查询条件的实体包含分页、排序参数、过滤条件 PageDTO分页结果实体包含总条数、总页数、当前页数据 UserVO用户页面视图实体
    UserQuery具体代码如下 package com.itheima.mp.domain.query;import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data;Data ApiModel(description 用户查询条件实体) public class UserQuery {ApiModelProperty(用户名关键字)private String name;ApiModelProperty(用户状态1-正常2-冻结)private Integer status;ApiModelProperty(余额最小值)private Integer minBalance;ApiModelProperty(余额最大值)private Integer maxBalance; }其中缺少的仅仅是分页条件而分页条件不仅仅用户分页查询需要以后其它业务也都有分页查询的需求。因此建议将分页查询条件单独定义为一个PageQuery实体 PageQuery是前端提交的查询参数一般包含四个属性 pageNo页码 pageSize每页数据条数 sortBy排序字段 isAsc是否升序
    Data ApiModel(description 分页查询实体) public class PageQuery {ApiModelProperty(页码)private Long pageNo;ApiModelProperty(页码)private Long pageSize;ApiModelProperty(排序字段)private String sortBy;ApiModelProperty(是否升序)private Boolean isAsc; }然后让UserQuery继承这个实体 package com.itheima.mp.domain.query;import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode;EqualsAndHashCode(callSuper true) Data ApiModel(description 用户查询条件实体) public class UserQuery extends PageQuery {ApiModelProperty(用户名关键字)private String name;ApiModelProperty(用户状态1-正常2-冻结)private Integer status;ApiModelProperty(余额最小值)private Integer minBalance;ApiModelProperty(余额最大值)private Integer maxBalance; }PageDTO具体代码如下 package com.itheima.mp.domain.dto;import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data;import java.util.List;Data ApiModel(description 分页结果) public class PageDTOT {ApiModelProperty(总条数)private Long total;ApiModelProperty(总页数)private Long pages;ApiModelProperty(集合)private ListT list; }UserVO具体代码如下 package com.itheima.mp.domain.vo;import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data;import java.util.List;Data ApiModel(description 用户VO实体) public class UserVO {ApiModelProperty(用户id)private Long id;ApiModelProperty(用户名)private String username;ApiModelProperty(详细信息)private String info;ApiModelProperty(使用状态1正常 2冻结)private Integer status;ApiModelProperty(账户余额)private Integer balance;ApiModelProperty(用户使用地址)private ListAddressVO addresses; } 开发接口 在UserController中定义分页查询用户的接口 package com.itheima.mp.controller;import cn.hutool.core.bean.BeanUtil; import com.itheima.mp.domain.dto.PageDTO; import com.itheima.mp.domain.dto.UserFormDTO; import com.itheima.mp.domain.po.User; import com.itheima.mp.domain.query.UserQuery; import com.itheima.mp.domain.vo.UserVO; import com.itheima.mp.service.IUserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.;import javax.annotation.Resource; import java.util.ArrayList; import java.util.List;RequestMapping(/users) RestController Slf4j Api(tags 用户管理接口) public class UserController {Resourceprivate IUserService userService;GetMapping(/page)ApiOperation(分页查询)public PageDTOUserVO queryUsersPage(UserQuery query){return userService.queryUsersPage(query);} } 在IUserService中创建queryUsersPage方法 public interface IUserService extends IServiceUser {PageDTOUserVO queryUsersPage(UserQuery query); } 在UserServiceImpl中实现该方法 package com.itheima.mp.service.impl;import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.toolkit.Db; import com.itheima.mp.domain.dto.PageDTO; import com.itheima.mp.domain.po.Address; import com.itheima.mp.domain.po.User; import com.itheima.mp.domain.query.UserQuery; import com.itheima.mp.domain.vo.AddressVO; import com.itheima.mp.domain.vo.UserVO; import com.itheima.mp.mapper.UserMapper; import com.itheima.mp.service.IUserService; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Service;import java.util.; import java.util.stream.Collectors;Service public class UserServiceImpl extends ServiceImplUserMapper, User implements IUserService {Overridepublic PageDTOUserVO queryUsersPage(UserQuery query) {// 1. 构造条件// 1.1 分页条件int pageNo query.getPageNo();int pageSize query.getPageSize();PageUser page Page.of(pageNo, pageSize);// 1.2 排序条件if(query.getSortBy() ! null){page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));} else {// 默认按照更新时间排序page.addOrder(new OrderItem(update_time, false));}// 2. 查询// userService.page(page),由于是userService类自身的方法所以不用再写userService// 2.1 不带筛选条件的// PageUser p page(page);// 2.2 带筛选条件的PageUser p lambdaQuery().like(query.getName() ! null, User::getUsername, query.getName()).eq(query.getStatus() ! null, User::getStatus, query.getStatus()).ge(query.getMaxBalance() ! null, User::getBalance, query.getMinBalance()).lt(query.getMinBalance() ! null, User::getBalance, query.getMaxBalance()).page(page);// 3. 数据校验是否合法ListUser users p.getRecords();if(users null || users.size() 0){// 无数据返回空结果return new PageDTO(p.getTotal(), p.getPages(), Collections.emptyList());}// 4. 有数据转换ListUserVO list BeanUtil.copyToList(users, UserVO.class);// 5 返回封装结果return new PageDTO(p.getTotal(), p.getPages(), list);} }