如何建一个论坛网站,高端品牌羽绒服前十名,知乎企业网站建设,wordpress 首页调用Mybatis Plus分页实现逻辑整理#xff08;结合芋道整合进行解析#xff09; 我希望如春天般的你#xff0c;身着白色的婚纱#xff0c;向我奔赴而来#xff0c;我愿意用全世界最温情的目光#xff0c;朝着你的方向望去——姗姗来迟。
1.背景介绍 https://baomidou.com/p…Mybatis Plus分页实现逻辑整理结合芋道整合进行解析 我希望如春天般的你身着白色的婚纱向我奔赴而来我愿意用全世界最温情的目光朝着你的方向望去——姗姗来迟。
1.背景介绍 https://baomidou.com/pages/2976a3/#mybatisplusinterceptor 官方文档 首先我们都知道Mybatis Plus是Mybatis 的升级版只做了功能增强不做代码变动现在我们就对于Mybatis Plus的分页实现做一个介绍概括
MyBatis-Plus分页实现主要通过Page对象来实现该对象封装了分页相关的信息例如当前页码、每页记录数等。以下是MyBatis-Plus分页实现的概述 Page对象 MyBatis-Plus使用Page对象来表示分页信息。这个对象包含了当前页码、每页记录数、总记录数等信息。 分页查询方法 在进行查询时你可以通过传递Page对象来告诉MyBatis-Plus你需要进行分页查询。MyBatis-Plus会在执行查询语句时根据Page对象的信息生成对应的分页SQL语句。 分页插件 MyBatis-Plus提供了分页插件可以在项目配置中进行配置。这个插件会在执行SQL前自动拦截根据Page对象的信息生成对应的分页SQL并在查询结果中封装到Page对象中。 返回结果 分页查询的结果将被封装到Page对象中你可以通过该对象获取分页相关的信息例如总记录数、总页数等以及实际的查询结果列表。
总体而言MyBatis-Plus分页实现简化了分页查询的操作通过传递Page对象即可轻松实现分页查询无需手动编写复杂的分页SQL语句。这使得分页操作更加方便同时也提高了代码的可维护性。
2.代码结构 3.依赖导入和相关配置
依赖导入
首先要想完成代码演示和功能实现我们需要再pom文件中加入如下依赖
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactIdscoperuntime/scope/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactIdversion1.2.20/version/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.3.1/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdjakarta.validation/groupIdartifactIdjakarta.validation-api/artifactIdversion2.0.2/version/dependencydependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.22/version/dependencydependencygroupIdcom.github.yulichang/groupIdartifactIdmybatis-plus-join-core/artifactIdversion1.4.7/version/dependency/dependencies当然让我们逐个介绍这些依赖项 org.springframework.boot:spring-boot-starter-web: 描述 提供了构建基于Spring Boot的Web应用程序所需的基本依赖项。包括处理HTTP请求、管理会话和提供静态资源等功能。用途 通常用于开发Spring Boot Web应用程序。 org.springframework.boot:spring-boot-starter-test: 描述 包含用于测试Spring Boot应用程序的依赖项。提供对单元测试、集成测试等测试相关功能的支持。用途 用于编写Spring Boot应用程序的测试。 com.mysql:mysql-connector-j: 描述 MySQL官方的JDBC驱动程序用于将Java应用程序连接到MySQL数据库。用途 当Spring Boot应用程序需要与MySQL数据库进行连接时使用。 com.alibaba:druid-spring-boot-starter:1.2.20: 描述 集成了Druid连接池它是一个高性能的开源JDBC连接池还提供了监控和管理功能。用途 当你想要使用Druid作为数据库连接池并享受其监控和管理功能时使用。 com.baomidou:mybatis-plus-boot-starter:3.5.3.1: 描述 MyBatis-Plus是MyBatis的增强工具包简化了MyBatis的使用提供了许多便利功能包括分页查询。用途 用于简化MyBatis的使用包括分页查询等功能。 org.projectlombok:lombok: 描述 Lombok是一个Java库通过注解消除了样板代码提高了开发效率。用途 简化Java代码减少样板代码的编写。 jakarta.validation:jakarta.validation-api:2.0.2: 描述 Jakarta Bean Validation API提供了一套用于声明性数据验证的API。用途 用于在应用程序中执行数据验证。 cn.hutool:hutool-all:5.8.22: 描述 Hutool是一个Java工具包提供了许多实用的工具方法简化了Java开发。用途 提供各种实用工具简化Java开发中的常见任务。 com.github.yulichang:mybatis-plus-join-core:1.4.7: 描述 一个用于MyBatis-Plus的插件简化了多表关联查询的操作。用途 简化MyBatis-Plus中多表关联查询的实现。 基础配置 server:port: 8181
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/yudao?useUnicodetruecharacterEncodingUTF-8username: rootpassword: rootmybatis-plus:mapper-locations: classpath:/mapper/**/*.xmltypeAliasesPackage: com.cnbai.*.*global-config:db-config:id-type: AUTO# 数据库字段驼峰下划线转换db-column-underline: truerefresh-mapper: trueconfiguration:# 自动驼峰命名map-underscore-to-camel-case: true# 查询结果中包含空值的列在映射的时候不会映射这个字段call-setters-on-nulls: true# 开启 sql 日志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 关闭 sql 日志# log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl这是一个Spring Boot项目的配置文件主要包含了服务器端口、数据库连接信息以及MyBatis-Plus的配置。下面是对其中的关键配置项的解读 server.port: 配置了应用的端口号这里设置为8181。 spring.datasource: 配置了数据源相关信息。 driver-class-name: 指定了数据库驱动的类名。url: 指定了数据库连接的URL包括数据库类型、主机地址、端口号以及数据库名称等。username 和 password: 指定了数据库的用户名和密码。 mybatis-plus.mapper-locations: 指定了MyBatis Mapper XML 文件的位置。 mybatis-plus.typeAliasesPackage: 指定了MyBatis扫描实体类别名的包路径。 mybatis-plus.global-config: 全局配置包括数据库配置和刷新映射器。 db-config.id-type: 设置主键生成策略这里设定为自动增长。db-config.db-column-underline: 数据库字段驼峰下划线转换设置为true表示启用。db-config.refresh-mapper: 刷新映射器设置为true表示刷新XML中的缓存。 mybatis-plus.configuration: MyBatis 配置项。 map-underscore-to-camel-case: 开启自动驼峰命名。call-setters-on-nulls: 查询结果中包含空值的列在映射时不会映射这个字段设置为true表示调用setter方法设置null值。log-impl: 开启 SQL 日志这里设置为在控制台输出。
总体而言这份配置文件包括了服务器端口、数据库连接信息以及MyBatis-Plus的配置其中包含了数据库驱动、URL、用户名、密码、Mapper XML 文件位置、实体类别名扫描包路径等。 MyBatis-Plus的配置包括了全局配置和MyBatis的一些常用配置如主键生成策略、字段命名策略、映射器刷新等。
4.编写MybatisPlusConfig配置类
这是一个使用MyBatis-Plus的配置类主要用于配置分页插件。让我对这段代码进行解读一下
Configuration
public class MybatisPlusConfig {/*** 添加分页插件*/Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加return interceptor;}
}Configuration: 这个注解表示这是一个配置类会被Spring容器扫描并加载。 Bean: 这个注解标志着这是一个Bean的定义方法它将返回一个被Spring管理的对象。 MybatisPlusInterceptor: 这是MyBatis-Plus提供的插件拦截器用于自定义MyBatis的行为。 mybatisPlusInterceptor(): 这个方法用于创建并配置MybatisPlusInterceptor的实例。 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)): 这行代码添加了一个内部插件即PaginationInnerInterceptor用于实现分页功能。DbType.MYSQL指定了数据库类型为MySQL。如果有多个插件要确保分页插件是最后一个添加以确保正确的执行顺序。
总体来说这段配置代码的作用是创建一个MyBatis-Plus的拦截器配置了分页插件确保在进行数据库查询时自动添加分页的功能。这样你在使用MyBatis-Plus进行分页查询时就无需手动编写分页SQL而是通过配置实现了分页的自动化。
5.创建基础工具类
PageParam分页基础实体类
import lombok.Data;import javax.validation.constraints.Min;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import java.io.Serializable;Data
public class PageParam implements Serializable {private static final Integer PAGE_NO 1;private static final Integer PAGE_SIZE 10;/*** 每页条数 - 不分页** 例如说导出接口可以设置 {link #pageSize} 为 -1 不分页查询所有数据。*/public static final Integer PAGE_SIZE_NONE -1;NotNull(message 页码不能为空)Min(value 1, message 页码最小值为 1)private Integer pageNo PAGE_NO;NotNull(message 每页条数不能为空)Min(value 1, message 每页条数最小值为 1)Max(value 100, message 每页条数最大值为 100)private Integer pageSize PAGE_SIZE;}这个类定义了用于分页查询的参数通过 Lombok 注解减少了冗长的 getter 和 setter 方法的编写而通过 Bean Validation 注解确保了参数的合法性。其中通过静态常量和注释提供了对默认分页参数和不分页情况的解释 PageResult分页基础实体类
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;Data
public final class PageResultT implements Serializable {private ListT list;private Long total;public PageResult() {}public PageResult(ListT list, Long total) {this.list list;this.total total;}public PageResult(Long total) {this.list new ArrayList();this.total total;}public static T PageResultT empty() {return new PageResult(0L);}public static T PageResultT empty(Long total) {return new PageResult(total);}}这是一个用于表示分页查询结果的 Java 类 PageResultT使用 Lombok 的 Data 注解简化了 getter、setter、toString 等方法的编写。下面是对该类的解读 PageResult 是一个泛型类使用了 T 来表示泛型类型用于表示分页查询的结果。 list 属性表示分页查询的结果列表其中的泛型 T 表示每个元素的类型。 total 属性表示总记录数即满足查询条件的所有记录的数量。 有多个构造方法 无参构造方法用于创建一个空的 PageResult 对象。带参构造方法ListT list, Long total用于接收查询结果列表和总记录数。带参构造方法Long total用于接收总记录数结果列表初始化为空列表。 静态方法 empty(): 返回一个空的 PageResult总记录数为 0。empty(Long total): 返回一个空的 PageResult可以指定总记录数。
这个类的设计主要是用于封装分页查询的结果提供了一些方便的构造方法和静态方法使得在业务代码中使用起来更加简洁。
BaseMapperX 工具类
在MyBatis Plus 的 BaseMapper 的基础上拓展 import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.github.yulichang.base.MPJBaseMapper;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.page.demo.common.mybatis.core.query.MyBatisUtils;
import com.page.demo.common.pojo.PageParam;
import com.page.demo.common.pojo.PageResult;
import org.apache.ibatis.annotations.Param;import java.util.Collection;
import java.util.List;/*** 在 MyBatis Plus 的 BaseMapper 的基础上拓展提供更多的能力** 1. {link BaseMapper} 为 MyBatis Plus 的基础接口提供基础的 CRUD 能力* 2. {link MPJBaseMapper} 为 MyBatis Plus Join 的基础接口提供连表 Join 能力*/
public interface BaseMapperXT extends MPJBaseMapperT {default PageResultT selectPage(PageParam pageParam, Param(ew) WrapperT queryWrapper) {// 特殊不分页直接查询全部if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageNo())) {ListT list selectList(queryWrapper);return new PageResult(list, (long) list.size());}// MyBatis Plus 查询IPageT mpPage MyBatisUtils.buildPage(pageParam);selectPage(mpPage, queryWrapper);// 转换返回return new PageResult(mpPage.getRecords(), mpPage.getTotal());}default DTO PageResultDTO selectJoinPage(PageParam pageParam, ClassDTO resultTypeClass, MPJBaseJoinT joinQueryWrapper) {IPageDTO mpPage MyBatisUtils.buildPage(pageParam);selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);// 转换返回return new PageResult(mpPage.getRecords(), mpPage.getTotal());}default T selectOne(String field, Object value) {return selectOne(new QueryWrapperT().eq(field, value));}default T selectOne(SFunctionT, ? field, Object value) {return selectOne(new LambdaQueryWrapperT().eq(field, value));}default T selectOne(String field1, Object value1, String field2, Object value2) {return selectOne(new QueryWrapperT().eq(field1, value1).eq(field2, value2));}default T selectOne(SFunctionT, ? field1, Object value1, SFunctionT, ? field2, Object value2) {return selectOne(new LambdaQueryWrapperT().eq(field1, value1).eq(field2, value2));}default T selectOne(SFunctionT, ? field1, Object value1, SFunctionT, ? field2, Object value2,SFunctionT, ? field3, Object value3) {return selectOne(new LambdaQueryWrapperT().eq(field1, value1).eq(field2, value2).eq(field3, value3));}default Long selectCount() {return selectCount(new QueryWrapper());}default Long selectCount(String field, Object value) {return selectCount(new QueryWrapperT().eq(field, value));}default Long selectCount(SFunctionT, ? field, Object value) {return selectCount(new LambdaQueryWrapperT().eq(field, value));}default ListT selectList() {return selectList(new QueryWrapper());}default ListT selectList(String field, Object value) {return selectList(new QueryWrapperT().eq(field, value));}default ListT selectList(SFunctionT, ? field, Object value) {return selectList(new LambdaQueryWrapperT().eq(field, value));}default ListT selectList(String field, Collection? values) {if (CollUtil.isEmpty(values)) {return CollUtil.newArrayList();}return selectList(new QueryWrapperT().in(field, values));}default ListT selectList(SFunctionT, ? field, Collection? values) {if (CollUtil.isEmpty(values)) {return CollUtil.newArrayList();}return selectList(new LambdaQueryWrapperT().in(field, values));}Deprecateddefault ListT selectList(SFunctionT, ? leField, SFunctionT, ? geField, Object value) {return selectList(new LambdaQueryWrapperT().le(leField, value).ge(geField, value));}default ListT selectList(SFunctionT, ? field1, Object value1, SFunctionT, ? field2, Object value2) {return selectList(new LambdaQueryWrapperT().eq(field1, value1).eq(field2, value2));}/*** 批量插入适合大量数据插入** param entities 实体们*/default void insertBatch(CollectionT entities) {Db.saveBatch(entities);}/*** 批量插入适合大量数据插入** param entities 实体们* param size 插入数量 Db.saveBatch 默认为 1000*/default void insertBatch(CollectionT entities, int size) {Db.saveBatch(entities, size);}default void updateBatch(T update) {update(update, new QueryWrapper());}default void updateBatch(CollectionT entities) {Db.updateBatchById(entities);}default void updateBatch(CollectionT entities, int size) {Db.updateBatchById(entities, size);}default void insertOrUpdate(T entity) {Db.saveOrUpdate(entity);}default void insertOrUpdateBatch(CollectionT collection) {Db.saveOrUpdateBatch(collection);}default int delete(String field, String value) {return delete(new QueryWrapperT().eq(field, value));}default int delete(SFunctionT, ? field, Object value) {return delete(new LambdaQueryWrapperT().eq(field, value));}}这是一个自定义的 MyBatis Plus 的 Mapper 接口 BaseMapperXT该接口继承了 MPJBaseMapperT。下面是对该接口的主要内容进行解读 BaseMapperXT 继承了 MPJBaseMapperT这表示该 Mapper 接口扩展了 MyBatis Plus 的基础 Mapper 接口并具有更多的能力。 接口中包含了一系列的默认方法这些方法提供了更方便的数据库操作。以下是其中的几个方法的说明 selectPage: 根据传入的分页参数和查询条件进行分页查询并返回 PageResultT。 selectJoinPage: 进行关联查询支持连表 Join 操作返回 PageResultDTO其中 DTO 是关联查询结果的数据传输对象。 selectOne 系列方法根据传入的条件查询单个对象。 selectCount 系列方法根据条件查询符合条件的记录数量。 selectList 系列方法根据条件查询符合条件的记录列表。 insertBatch 系列方法批量插入数据。 updateBatch 系列方法批量更新数据。 insertOrUpdate 和 insertOrUpdateBatch插入或更新数据。 delete 系列方法根据条件删除数据。 该接口中使用了一些 MyBatis Plus 的条件构造器如 QueryWrapper 和 LambdaQueryWrapper用于构建查询条件。 在一些批量操作方法中使用了 Db 类提供的方法该类提供了一些数据库操作的工具方法例如批量插入、批量更新等。
总体而言BaseMapperXT 接口提供了一组扩展的数据库操作方法使得在使用 MyBatis Plus 进行数据库操作时更加方便和灵活。
LambdaQueryWrapperX 优化构建器
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.springframework.util.StringUtils;import java.util.Collection;/*** 拓展 MyBatis Plus QueryWrapper 类主要增加如下功能* p* 1. 拼接条件的方法增加 xxxIfPresent 方法用于判断值不存在的时候不要拼接到条件中。** param T 数据类型*/
public class LambdaQueryWrapperXT extends LambdaQueryWrapperT {public LambdaQueryWrapperXT likeIfPresent(SFunctionT, ? column, String val) {if (StringUtils.hasText(val)) {return (LambdaQueryWrapperXT) super.like(column, val);}return this;}public LambdaQueryWrapperXT inIfPresent(SFunctionT, ? column, Collection? values) {if (ObjectUtil.isAllNotEmpty(values) !ArrayUtil.isEmpty(values)) {return (LambdaQueryWrapperXT) super.in(column, values);}return this;}public LambdaQueryWrapperXT inIfPresent(SFunctionT, ? column, Object... values) {if (ObjectUtil.isAllNotEmpty(values) !ArrayUtil.isEmpty(values)) {return (LambdaQueryWrapperXT) super.in(column, values);}return this;}public LambdaQueryWrapperXT eqIfPresent(SFunctionT, ? column, Object val) {if (ObjectUtil.isNotEmpty(val)) {return (LambdaQueryWrapperXT) super.eq(column, val);}return this;}public LambdaQueryWrapperXT neIfPresent(SFunctionT, ? column, Object val) {if (ObjectUtil.isNotEmpty(val)) {return (LambdaQueryWrapperXT) super.ne(column, val);}return this;}public LambdaQueryWrapperXT gtIfPresent(SFunctionT, ? column, Object val) {if (val ! null) {return (LambdaQueryWrapperXT) super.gt(column, val);}return this;}public LambdaQueryWrapperXT geIfPresent(SFunctionT, ? column, Object val) {if (val ! null) {return (LambdaQueryWrapperXT) super.ge(column, val);}return this;}public LambdaQueryWrapperXT ltIfPresent(SFunctionT, ? column, Object val) {if (val ! null) {return (LambdaQueryWrapperXT) super.lt(column, val);}return this;}public LambdaQueryWrapperXT leIfPresent(SFunctionT, ? column, Object val) {if (val ! null) {return (LambdaQueryWrapperXT) super.le(column, val);}return this;}public LambdaQueryWrapperXT betweenIfPresent(SFunctionT, ? column, Object val1, Object val2) {if (val1 ! null val2 ! null) {return (LambdaQueryWrapperXT) super.between(column, val1, val2);}if (val1 ! null) {return (LambdaQueryWrapperXT) ge(column, val1);}if (val2 ! null) {return (LambdaQueryWrapperXT) le(column, val2);}return this;}// 重写父类方法方便链式调用 Overridepublic LambdaQueryWrapperXT eq(boolean condition, SFunctionT, ? column, Object val) {super.eq(condition, column, val);return this;}Overridepublic LambdaQueryWrapperXT eq(SFunctionT, ? column, Object val) {super.eq(column, val);return this;}Overridepublic LambdaQueryWrapperXT orderByDesc(SFunctionT, ? column) {super.orderByDesc(true, column);return this;}Overridepublic LambdaQueryWrapperXT last(String lastSql) {super.last(lastSql);return this;}Overridepublic LambdaQueryWrapperXT in(SFunctionT, ? column, Collection? coll) {super.in(column, coll);return this;}}这是一个拓展了 MyBatis Plus 的 LambdaQueryWrapperT 类的 LambdaQueryWrapperXT 类。主要增加了一些方法用于在条件拼接时判断值是否存在从而决定是否拼接到条件中。以下是对该类的解读 LambdaQueryWrapperXT 继承了 LambdaQueryWrapperT表示该类是对 LambdaQueryWrapperT 的拓展。 该类提供了一系列的拓展方法如 likeIfPresent、inIfPresent、eqIfPresent 等这些方法都带有 IfPresent 后缀表示当值存在时才进行条件拼接避免了值为 null 或空时拼接条件。 这些拓展方法在条件拼接时先判断了值的存在性如果值存在才进行条件拼接否则不拼接。 重写了父类的一些方法以方便链式调用例如 eq、orderByDesc、last、in 等。
总体而言该类通过增加带有 IfPresent 后缀的拓展方法使得在使用 LambdaQueryWrapper 进行条件拼接时更加方便减少了空值或 null 值导致的冗余条件拼接。
6.创建实体类
Data
TableName(value test_student)
public class Student {TableIdprivate Long stuId;private String stuName;private Long stuAge;private String className;
}7.创建请求视图对象
Data
EqualsAndHashCode(callSuper true)
public class StudentPageReqVO extends PageParam {private String stuName;private String className;
}在这里有必要做一个解释为什么创建一个请求视图对象
创建请求视图对象Request View Object简称Request VO有几个主要原因尤其在Web开发中 封装请求参数 Request VO 提供了一种将请求参数封装到一个对象中的方式。这样做有助于减少控制器Controller层中的方法签名中的参数数量。在处理复杂的请求特别是包含多个参数的请求时将它们组织成一个对象可以提高代码的清晰度和可读性。 传递前端数据 在Web应用中前端通常以 JSON 或其他数据格式将数据传递给后端。Request VO 用于在前端和后端之间传递数据尤其是在处理复杂的表单提交或查询条件时。通过使用 Request VO可以更方便地将前端的数据映射到后端的处理逻辑中。 解耦前后端 Request VO 有助于解耦前端和后端的实现细节。前端可以更自由地修改请求参数的结构而后端的处理逻辑不会受到太大影响只需保证 Request VO 中的字段与后端期望的数据结构相匹配即可。 提高代码复用性 Request VO 可以作为方法参数提高了代码的复用性。例如多个控制器方法可能需要相似的请求参数通过使用相同的 Request VO可以减少重复的代码。 易于维护 维护 Request VO 可以更方便地处理接口变更。如果请求参数的结构发生变化只需更新 Request VO 中的字段而无需修改控制器方法的签名。
总体而言创建请求视图对象是一种良好的实践有助于组织和管理请求参数提高代码的可读性、可维护性并支持前后端的解耦。
extends PageParam 表示一个类继承了 PageParam这种情况通常发生在使用某个框架或库提供的分页功能时。
8.创建Mapper层
import com.page.demo.common.mybatis.core.query.LambdaQueryWrapperX;
import com.page.demo.common.mybatis.core.query.mapper.BaseMapperX;
import com.page.demo.common.pojo.PageResult;
import com.page.demo.domain.Student;
import com.page.demo.domain.StudentPageReqVO;
import org.apache.ibatis.annotations.Mapper;Mapper
public interface StudentMapper extends BaseMapperXStudent {default PageResultStudent getStudentList(StudentPageReqVO reqVO) {return selectPage(reqVO, new LambdaQueryWrapperXStudent().likeIfPresent(Student::getStuName, reqVO.getStuName()).likeIfPresent(Student::getClassName, reqVO.getClassName()).orderByDesc(Student::getStuId));}
}
在这里我们可以看到我们有三个自定义的基础工具类 com.page.demo.common.mybatis.core.query.LambdaQueryWrapperX;
com.page.demo.common.mybatis.core.query.mapper.BaseMapperX;
com.page.demo.common.pojo.PageResult;就是我们首先创建的工具对象。
这是一个在 StudentMapper 接口中定义的默认方法用于获取学生列表并返回分页结果 PageResultStudent。以下是对该方法的解读 方法签名 default PageResultStudent getStudentList(StudentPageReqVO reqVO)返回类型PageResultStudent表示分页查询的结果其中 Student 是学生实体类。方法名称getStudentList用于获取学生列表。参数StudentPageReqVO reqVO是一个请求视图对象用于传递查询条件。 方法实现 return selectPage(reqVO, new LambdaQueryWrapperXStudent().likeIfPresent(Student::getStuName, reqVO.getStuName()).likeIfPresent(Student::getClassName, reqVO.getClassName()).orderByDesc(Student::getStuId));selectPage 是在 BaseMapperX 接口中定义的方法用于执行分页查询。reqVO 作为查询条件传入。new LambdaQueryWrapperXStudent() 创建了一个带有条件判断的 LambdaQueryWrapper 实例该实例是对 MyBatis Plus 的 LambdaQueryWrapper 进行了扩展使得条件在值存在时才拼接到查询条件中。.likeIfPresent(Student::getStuName, reqVO.getStuName())如果 reqVO.getStuName() 不为空则添加一个类似于 like 的条件即根据学生姓名模糊查询。.likeIfPresent(Student::getClassName, reqVO.getClassName())如果 reqVO.getClassName() 不为空则添加一个类似于 like 的条件即根据班级名称模糊查询。.orderByDesc(Student::getStuId)按照学生编号降序排列结果。 返回结果 返回的是经过分页查询后的学生列表的分页结果封装在 PageResultStudent 中。
总体而言这个方法实现了根据给定的条件从 reqVO 中获取进行学生列表的分页查询使用了 MyBatis Plus 提供的分页查询功能并且在查询条件拼接时使用了自定义的 LambdaQueryWrapperX 类确保只有在条件值存在的情况下才进行条件的拼接。
9.创建服务层接口
import com.baomidou.mybatisplus.extension.service.IService;
import com.page.demo.common.pojo.PageResult;
import com.page.demo.domain.Student;
import com.page.demo.domain.StudentPageReqVO;public interface IStudentService extends IServiceStudent {PageResultStudent getStudentList(StudentPageReqVO reqVO);
}10.创建服务层接口实现类
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.page.demo.common.pojo.PageResult;
import com.page.demo.domain.Student;
import com.page.demo.domain.StudentPageReqVO;
import com.page.demo.mapper.StudentMapper;
import com.page.demo.service.IStudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.annotation.Resource;Service
public class StudentServiceImpl extends ServiceImplStudentMapper, Student implements IStudentService {Resourceprivate StudentMapper studentMapper;Overridepublic PageResultStudent getStudentList(StudentPageReqVO reqVO) {return studentMapper.getStudentList(reqVO);}
}11.创建控制层
import cn.hutool.json.JSONObject;
import com.page.demo.common.pojo.PageResult;
import com.page.demo.domain.Student;
import com.page.demo.domain.StudentPageReqVO;
import com.page.demo.service.IStudentService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;RestController
RequestMapping(/api/stu)
public class StudentController {Resourceprivate IStudentService studentService;GetMapping(/list)public JSONObject getStudentList(StudentPageReqVO reqVO) {PageResultStudent pageResult studentService.getStudentList(reqVO);JSONObject jsonObject new JSONObject();jsonObject.set(data, pageResult);jsonObject.set(status, 200);return jsonObject;}
}12.测试 13.总结
这段代码展示了一个基于Spring Boot和MyBatis Plus的后端服务的典型架构主要涉及到以下方面
1. 项目依赖及配置
使用了Spring Boot框架简化了项目的配置和搭建。数据库连接使用了mysql-connector-j数据源使用了druidMyBatis Plus作为持久层框架。使用了lombok简化实体类的代码。引入了一些辅助工具库如hutool和mybatis-plus-join-core用于增强开发效率和提供一些扩展功能。
2. MyBatis Plus分页实现
配置了MyBatis Plus的分页插件通过PaginationInnerInterceptor实现分页功能。自定义了MybatisPlusConfig类配置了分页插件并将其注入到Spring容器中。
3. 数据库实体和分页请求视图对象
存在Student实体类用于映射数据库中的学生表。定义了PageParam类作为分页查询的请求参数对象包含了页码、每页条数等信息。
4. 数据库操作接口和实现
存在BaseMapperX接口继承了MyBatis Plus的BaseMapper和自定义的MPJBaseMapper提供了一系列对数据库操作的方法包括分页查询、条件查询等。StudentMapper接口继承了BaseMapperX用于学生表的数据库操作。StudentServiceImpl实现了IStudentService接口提供了具体的业务逻辑包括分页查询学生列表。
5. 自定义工具类和扩展
存在LambdaQueryWrapperX类对MyBatis Plus的LambdaQueryWrapper进行了拓展增加了一系列条件拼接的方法根据条件值的存在性来动态拼接查询条件。
6. 分页查询方法
在IStudentService接口中定义了一个默认方法getStudentList接受一个StudentPageReqVO对象作为查询条件通过调用selectPage方法实现学生列表的分页查询。
总体评价
代码结构清晰遵循了一定的分层架构将持久层、业务层和控制层分离。使用了Spring Boot和MyBatis Plus等现代化框架简化了开发流程提高了开发效率。引入了自定义工具类和扩展使得代码更加灵活可扩展性较好。分页查询方法采用了默认方法的方式提高了接口的兼容性。
总体而言这个项目展示了一个典型的后端服务架构具备良好的可读性、可维护性和可扩展性。