news 2026/4/16 18:19:05

Mybatis Plus扩展方法——PageHelper分页扩展排序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mybatis Plus扩展方法——PageHelper分页扩展排序

1. NeedPage 注解修改

java

package com.xx.page.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Author: xueqimiao * @Date: 2023/11/8 15:54 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface NeedPage { /** * orderByOnly: 是否仅排序模式 * true: 仅排序不分页 * false: 正常分页+排序(默认) */ boolean orderByOnly() default false; }

2. PageDataUtil 工具类修改

java

package com.xx.utils; /** * @Author: xueqimiao * @Date: 2023/11/8 16:06 */ public class PageDataUtil { /** * 当前页码 */ public static final String PAGE_CURRENT_PAGE_NO_STR = "pageNo"; /** * 每页条数 */ public static final String PAGE_SIZE_STR = "pageSize"; /** * 是否统计总条数标识 * 1: 统计 * 0: 不统计 */ public static final String COUNT_FLAG = "countFlag"; /** * 排序字段 */ public static final String ORDER_BY = "orderBy"; /** * 是否仅排序不分页 * 1: 仅排序 * 0: 排序加分页(默认) */ public static final String ORDER_BY_ONLY = "orderByOnly"; }

3. 完整的 PageDataInterceptor 拦截器

java

package com.xx.page.interceptor; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.xx.page.annotation.NeedPage; import com.xx.page.context.PageData; import com.xx.result.Result; import com.xx.utils.PageDataUtil; import com.xx.utils.ServletUtil; import com.xx.utils.ValidationUtil; import jakarta.servlet.http.HttpServletRequest; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.util.List; /** * @Author: xueqimiao * @Date: 2023/11/8 15:58 */ @Component @Aspect public class PageDataInterceptor { public Logger log = LoggerFactory.getLogger(PageDataInterceptor.class); // 切入点 @Pointcut("@annotation(com.xx.page.annotation.NeedPage)") public void controllerAspect() { } @Around("controllerAspect()") public Result controllerAround(ProceedingJoinPoint proJoinPoint) throws Throwable { log.info("==========> 开始执行PageHelper"); // 1、获取请求参数 int currentPage = ServletUtil.getParameterToInt(PageDataUtil.PAGE_CURRENT_PAGE_NO_STR, 1); int pageSize = ServletUtil.getParameterToInt(PageDataUtil.PAGE_SIZE_STR, 10); // 是否进行count查询 int count = ServletUtil.getParameterToInt(PageDataUtil.COUNT_FLAG, 1); // 排序字段 String orderBy = ServletUtil.getParameter(PageDataUtil.ORDER_BY); // 是否仅排序不分页 int orderByOnly = ServletUtil.getParameterToInt(PageDataUtil.ORDER_BY_ONLY, 0); // 2、创建Page对象 Page<Object> page = PageHelper.startPage(currentPage, pageSize, count == 1); // 3、获取方法注解配置 Method method = ((MethodSignature) proJoinPoint.getSignature()).getMethod(); boolean annotationOrderByOnly = false; if (method.isAnnotationPresent(NeedPage.class)) { annotationOrderByOnly = method.getAnnotation(NeedPage.class).orderByOnly(); page.setOrderByOnly(annotationOrderByOnly); } // 4、设置排序参数 if (!ValidationUtil.isEmpty(orderBy)) { // 如果注解指定了orderByOnly,以注解配置为准 // 否则以前端参数为准 if (annotationOrderByOnly) { // 注解指定了仅排序,使用注解配置 page.setOrderBy(orderBy); } else { // 注解未指定,以前端参数为准 page.setOrderByOnly(orderByOnly == 1); page.setOrderBy(orderBy); } } try { return handlePage(proJoinPoint, page); } finally { PageHelper.clearPage(); // 清除分页信息 } } private Result handlePage(ProceedingJoinPoint proJoinPoint, Page<Object> page) throws Throwable { Object retVal = proJoinPoint.proceed(); if (retVal == null || !(retVal instanceof Result) || !((Result) retVal).isSuccess()) { return Result.ok(retVal); } Result returnResult = (Result) retVal; if (!(returnResult.getResult() instanceof List)) { return returnResult; } PageData pageData = new PageData(); Object result = returnResult.getResult(); pageData.setRecords(result); // 如果仅排序不分页,不返回分页信息 if (!page.isOrderByOnly()) { PageInfo pageInfo = new PageInfo<>(page); pageData.setSize(pageInfo.getPageSize()); pageData.setTotal(pageInfo.getTotal()); pageData.setPages(pageInfo.getPages()); pageData.setCurrent(pageInfo.getPageNum()); } returnResult.setResult(pageData); return returnResult; } private static int getParameterToInt(HttpServletRequest request, String paramName, Integer defaultVal) { String paramValue = request.getParameter(paramName); if (ValidationUtil.isEmpty(paramValue)) { return defaultVal; } return Integer.parseInt(paramValue); } }

4. 前端调用示例

java

// 是否仅排序 默认为0 orderByOnly=0或者1 // 一个字段排序 orderBy=id asc // 多个字段排序 orderBy=create_time asc,id desc // 分页+排序(默认) pageNo=1&pageSize=10&orderBy=create_time desc // 仅排序不分页 orderByOnly=1&orderBy=create_time desc

5. 使用示例

java

// Controller 示例 @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; // 默认分页+排序 @NeedPage @GetMapping("/list") public Result listUsers() { List<User> users = userService.listUsers(); return Result.ok(users); } // 仅排序不分页 @NeedPage(orderByOnly = true) @GetMapping("/list-all") public Result listAllUsers() { List<User> users = userService.listAllUsers(); return Result.ok(users); } }

核心逻辑说明:

  1. 优先级规则

    • 如果注解配置了orderByOnly,以注解配置为准

    • 如果注解未配置,以前端参数为准

  2. 处理流程

    • 创建 Page 对象

    • 读取注解配置

    • 读取前端参数

    • 根据优先级设置排序和分页模式

    • 执行 SQL

    • 包装返回结果

  3. 返回结果

    • 仅排序模式:只返回数据列表,不包含分页信息

    • 分页+排序模式:返回数据列表和完整的分页信息

扩展补充后。一起排版

完整的分页排序拦截器解决方案

1. NeedPage 注解(扩展版)

java

package com.xx.page.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 分页排序注解 * @Author: xueqimiao * @Date: 2023/11/8 15:54 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface NeedPage { /** * 是否仅排序模式 * true: 仅排序不分页 * false: 分页+排序(默认) */ boolean orderByOnly() default false; /** * 默认排序字段 * 格式: "字段名 排序方式,字段名 排序方式" * 示例: "create_time desc,id asc" */ String defaultOrderBy() default ""; /** * 默认每页条数 * 当 orderByOnly=false 时生效 */ int defaultPageSize() default 10; /** * 默认页码 * 当 orderByOnly=false 时生效 */ int defaultPageNo() default 1; /** * 是否默认进行count查询 * 当 orderByOnly=false 时生效 */ boolean defaultCountFlag() default true; }

2. PageDataUtil 工具类(扩展版)

java

package com.xx.utils; /** * 分页数据工具类 * @Author: xueqimiao * @Date: 2023/11/8 16:06 */ public class PageDataUtil { /** * 当前页码参数名 */ public static final String PAGE_CURRENT_PAGE_NO_STR = "pageNo"; /** * 每页条数参数名 */ public static final String PAGE_SIZE_STR = "pageSize"; /** * 是否统计总条数标识 * 1: 统计,0: 不统计 */ public static final String COUNT_FLAG = "countFlag"; /** * 排序字段参数名 */ public static final String ORDER_BY = "orderBy"; /** * 是否仅排序不分页参数名 * 1: 仅排序,0: 排序加分页(默认) */ public static final String ORDER_BY_ONLY = "orderByOnly"; /** * 最大每页条数限制 */ public static final int MAX_PAGE_SIZE = 1000; /** * 默认每页条数 */ public static final int DEFAULT_PAGE_SIZE = 10; /** * 默认页码 */ public static final int DEFAULT_PAGE_NO = 1; /** * 默认是否进行count查询 */ public static final int DEFAULT_COUNT_FLAG = 1; /** * 默认是否仅排序 */ public static final int DEFAULT_ORDER_BY_ONLY = 0; }

3. PageData 分页数据模型(新增)

java

package com.xx.page.context; import java.util.List; /** * 分页数据封装类 */ public class PageData<T> { /** * 数据列表 */ private List<T> records; /** * 当前页码 */ private int current; /** * 每页条数 */ private int size; /** * 总条数 */ private long total; /** * 总页数 */ private int pages; /** * 排序信息 */ private String orderBy; /** * 是否仅排序 */ private boolean orderByOnly; // 构造函数 public PageData() { } public PageData(List<T> records, int current, int size, long total) { this.records = records; this.current = current; this.size = size; this.total = total; this.pages = (int) Math.ceil((double) total / size); } // Getter和Setter方法 public List<T> getRecords() { return records; } public void setRecords(List<T> records) { this.records = records; } public int getCurrent() { return current; } public void setCurrent(int current) { this.current = current; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public long getTotal() { return total; } public void setTotal(long total) { this.total = total; if (size > 0) { this.pages = (int) Math.ceil((double) total / size); } } public int getPages() { return pages; } public void setPages(int pages) { this.pages = pages; } public String getOrderBy() { return orderBy; } public void setOrderBy(String orderBy) { this.orderBy = orderBy; } public boolean isOrderByOnly() { return orderByOnly; } public void setOrderByOnly(boolean orderByOnly) { this.orderByOnly = orderByOnly; } /** * 是否还有上一页 */ public boolean hasPrevious() { return current > 1; } /** * 是否还有下一页 */ public boolean hasNext() { return current < pages; } @Override public String toString() { return "PageData{" + "current=" + current + ", size=" + size + ", total=" + total + ", pages=" + pages + ", orderBy='" + orderBy + '\'' + ", orderByOnly=" + orderByOnly + ", recordsSize=" + (records != null ? records.size() : 0) + '}'; } }

4. 完整的 PageDataInterceptor 拦截器(增强版)

java

package com.xx.page.interceptor; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.xx.page.annotation.NeedPage; import com.xx.page.context.PageData; import com.xx.result.Result; import com.xx.utils.PageDataUtil; import com.xx.utils.ServletUtil; import com.xx.utils.ValidationUtil; import jakarta.servlet.http.HttpServletRequest; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import java.lang.reflect.Method; import java.util.List; /** * 分页排序拦截器 * @Author: xueqimiao * @Date: 2023/11/8 15:58 */ @Component @Aspect public class PageDataInterceptor { private static final Logger log = LoggerFactory.getLogger(PageDataInterceptor.class); // 切入点 @Pointcut("@annotation(com.xx.page.annotation.NeedPage)") public void controllerAspect() { } @Around("controllerAspect()") public Result controllerAround(ProceedingJoinPoint proJoinPoint) throws Throwable { log.debug("==========> 开始执行PageHelper分页拦截器"); try { // 1. 获取方法注解配置 Method method = ((MethodSignature) proJoinPoint.getSignature()).getMethod(); NeedPage needPage = method.getAnnotation(NeedPage.class); // 2. 获取请求参数(优先使用注解默认值) int currentPage = getCurrentPage(needPage); int pageSize = getPageSize(needPage); boolean countFlag = getCountFlag(needPage); // 3. 获取排序相关参数 String orderBy = getOrderBy(needPage); boolean orderByOnly = getOrderByOnly(needPage); // 4. 创建Page对象并配置 Page<Object> page = PageHelper.startPage(currentPage, pageSize, countFlag); page.setOrderByOnly(orderByOnly); // 5. 设置排序字段(如果有) if (StringUtils.hasText(orderBy)) { page.setOrderBy(orderBy); } // 6. 执行目标方法并处理结果 return handlePageResult(proJoinPoint, page, orderByOnly); } catch (Exception e) { log.error("分页拦截器执行异常", e); throw e; } finally { PageHelper.clearPage(); // 清除分页信息,防止内存泄漏 } } /** * 获取当前页码 */ private int getCurrentPage(NeedPage needPage) { int currentPage = ServletUtil.getParameterToInt(PageDataUtil.PAGE_CURRENT_PAGE_NO_STR, needPage.defaultPageNo()); return Math.max(currentPage, 1); // 页码最小为1 } /** * 获取每页条数 */ private int getPageSize(NeedPage needPage) { int pageSize = ServletUtil.getParameterToInt(PageDataUtil.PAGE_SIZE_STR, needPage.defaultPageSize()); // 限制最大页数,防止恶意查询 return Math.min(Math.max(pageSize, 1), PageDataUtil.MAX_PAGE_SIZE); } /** * 获取是否进行count查询 */ private boolean getCountFlag(NeedPage needPage) { int count = ServletUtil.getParameterToInt(PageDataUtil.COUNT_FLAG, needPage.defaultCountFlag() ? 1 : 0); return count == 1; } /** * 获取排序字段(优先级:前端参数 > 注解默认值) */ private String getOrderBy(NeedPage needPage) { // 优先使用前端传递的排序字段 String orderBy = ServletUtil.getParameter(PageDataUtil.ORDER_BY); if (!ValidationUtil.isEmpty(orderBy)) { return orderBy; } // 使用注解默认排序字段 if (StringUtils.hasText(needPage.defaultOrderBy())) { return needPage.defaultOrderBy(); } return null; } /** * 获取是否仅排序(优先级:注解配置 > 前端参数) */ private boolean getOrderByOnly(NeedPage needPage) { // 注解配置优先 if (needPage.orderByOnly()) { return true; } // 检查前端参数 int orderByOnly = ServletUtil.getParameterToInt(PageDataUtil.ORDER_BY_ONLY, PageDataUtil.DEFAULT_ORDER_BY_ONLY); return orderByOnly == 1; } /** * 处理分页结果 */ @SuppressWarnings("unchecked") private Result handlePageResult(ProceedingJoinPoint proJoinPoint, Page<Object> page, boolean orderByOnly) throws Throwable { // 执行目标方法 Object retVal = proJoinPoint.proceed(); // 如果不是Result类型或执行失败,直接返回 if (!(retVal instanceof Result)) { log.warn("方法返回值不是Result类型,无法进行分页包装"); return Result.ok(retVal); } Result returnResult = (Result) retVal; if (!returnResult.isSuccess()) { return returnResult; } Object resultData = returnResult.getResult(); // 如果返回结果不是List,直接返回 if (!(resultData instanceof List)) { log.debug("返回结果不是List类型,无需分页包装"); return returnResult; } List<Object> resultList = (List<Object>) resultData; // 创建PageData对象 PageData<Object> pageData = new PageData<>(); pageData.setRecords(resultList); pageData.setOrderBy(page.getOrderBy()); pageData.setOrderByOnly(orderByOnly); // 如果是分页模式,设置分页信息 if (!orderByOnly) { PageInfo<Object> pageInfo = new PageInfo<>(page); pageData.setCurrent(pageInfo.getPageNum()); pageData.setSize(pageInfo.getPageSize()); pageData.setTotal(pageInfo.getTotal()); pageData.setPages(pageInfo.getPages()); log.debug("分页查询完成: {}", pageData); } else { // 仅排序模式,设置虚拟分页信息 pageData.setCurrent(1); pageData.setSize(resultList.size()); pageData.setTotal(resultList.size()); pageData.setPages(1); log.debug("仅排序查询完成,返回记录数: {}", resultList.size()); } returnResult.setResult(pageData); return returnResult; } }

5. ValidationUtil 工具类(补充)

java

package com.xx.utils; import org.springframework.util.StringUtils; import java.util.Collection; import java.util.Map; /** * 验证工具类 */ public class ValidationUtil { /** * 判断对象是否为空 */ public static boolean isEmpty(Object obj) { if (obj == null) { return true; } if (obj instanceof String) { return !StringUtils.hasText((String) obj); } if (obj instanceof Collection) { return ((Collection<?>) obj).isEmpty(); } if (obj instanceof Map) { return ((Map<?, ?>) obj).isEmpty(); } if (obj instanceof Object[]) { return ((Object[]) obj).length == 0; } return false; } /** * 判断对象是否非空 */ public static boolean isNotEmpty(Object obj) { return !isEmpty(obj); } /** * 验证字符串是否有效 */ public static boolean isValidString(String str) { return str != null && !str.trim().isEmpty(); } }

6. ServletUtil 工具类(补充)

java

package com.xx.utils; import jakarta.servlet.http.HttpServletRequest; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; /** * Servlet工具类 */ public class ServletUtil { /** * 获取当前请求对象 */ public static HttpServletRequest getRequest() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes != null) { return attributes.getRequest(); } return null; } /** * 获取请求参数(字符串) */ public static String getParameter(String name) { HttpServletRequest request = getRequest(); if (request != null) { return request.getParameter(name); } return null; } /** * 获取请求参数(整数,带默认值) */ public static int getParameterToInt(String name, int defaultValue) { String value = getParameter(name); if (ValidationUtil.isValidString(value)) { try { return Integer.parseInt(value.trim()); } catch (NumberFormatException e) { return defaultValue; } } return defaultValue; } /** * 获取请求参数(长整数,带默认值) */ public static long getParameterToLong(String name, long defaultValue) { String value = getParameter(name); if (ValidationUtil.isValidString(value)) { try { return Long.parseLong(value.trim()); } catch (NumberFormatException e) { return defaultValue; } } return defaultValue; } /** * 获取请求参数(布尔值) */ public static boolean getParameterToBoolean(String name, boolean defaultValue) { String value = getParameter(name); if (ValidationUtil.isValidString(value)) { return "true".equalsIgnoreCase(value) || "1".equals(value); } return defaultValue; } }

7. 使用示例

Controller 使用示例

java

package com.xx.controller; import com.xx.page.annotation.NeedPage; import com.xx.result.Result; import com.xx.service.UserService; import com.xx.vo.UserVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; /** * 默认分页+排序 * 前端可以传: pageNo, pageSize, orderBy, orderByOnly, countFlag */ @NeedPage @GetMapping("/list") public Result listUsers() { List<UserVO> users = userService.listUsers(); return Result.ok(users); } /** * 仅排序不分页 * 前端可以传: orderBy (orderByOnly参数会被忽略,因为注解强制为true) */ @NeedPage(orderByOnly = true) @GetMapping("/list-all") public Result listAllUsers() { List<UserVO> users = userService.listAllUsers(); return Result.ok(users); } /** * 自定义默认值 * 默认每页20条,按创建时间倒序,不进行count查询 */ @NeedPage( defaultPageSize = 20, defaultOrderBy = "create_time desc", defaultCountFlag = false ) @GetMapping("/list-custom") public Result listUsersCustom() { List<UserVO> users = userService.listUsers(); return Result.ok(users); } /** * 大列表查询(提高最大返回条数) */ @NeedPage(defaultPageSize = 200) @GetMapping("/list-large") public Result listLargeUsers() { List<UserVO> users = userService.listLargeUsers(); return Result.ok(users); } }

Service 层示例

java

package com.xx.service; import com.xx.mapper.UserMapper; import com.xx.vo.UserVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService { @Autowired private UserMapper userMapper; /** * 普通查询,会被拦截器自动分页 */ public List<UserVO> listUsers() { return userMapper.selectUserList(); } /** * 大列表查询 */ public List<UserVO> listLargeUsers() { return userMapper.selectLargeUserList(); } /** * 获取所有用户(不分页) */ public List<UserVO> listAllUsers() { return userMapper.selectAllUsers(); } }

Mapper 层示例

java

package com.xx.mapper; import com.xx.vo.UserVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; @Mapper public interface UserMapper { /** * 普通用户列表查询 * 不需要在SQL中写limit,PageHelper会自动处理 */ @Select("SELECT id, username, email, create_time FROM sys_user WHERE status = 1") List<UserVO> selectUserList(); /** * 大列表查询 */ @Select("SELECT id, username, email, create_time FROM sys_user") List<UserVO> selectLargeUserList(); /** * 查询所有用户 */ @Select("SELECT id, username, email FROM sys_user ORDER BY create_time DESC") List<UserVO> selectAllUsers(); }

8. 前端调用示例

javascript

// 1. 普通分页+排序 fetch('/user/list?pageNo=1&pageSize=10&orderBy=create_time desc') // 2. 仅排序不分页 fetch('/user/list-all?orderBy=id asc') // 3. 多字段排序 fetch('/user/list?orderBy=create_time asc,id desc') // 4. 不进行count查询(提高性能) fetch('/user/list?countFlag=0&pageNo=1&pageSize=50') // 5. 仅排序模式(前端控制) fetch('/user/list?orderByOnly=1&orderBy=username asc') // 6. 使用注解默认值 fetch('/user/list-custom') // 7. 大列表查询 fetch('/user/list-large?pageSize=200')

9. 返回结果示例

分页模式返回结果

json

{ "code": 200, "message": "成功", "success": true, "result": { "records": [ { "id": 1, "username": "张三", "email": "zhangsan@example.com", "createTime": "2023-01-01 10:00:00" }, { "id": 2, "username": "李四", "email": "lisi@example.com", "createTime": "2023-01-02 10:00:00" } ], "current": 1, "size": 10, "total": 100, "pages": 10, "orderBy": "create_time desc", "orderByOnly": false } }

仅排序模式返回结果

json

{ "code": 200, "message": "成功", "success": true, "result": { "records": [ { "id": 1, "username": "张三", "email": "zhangsan@example.com" }, { "id": 2, "username": "李四", "email": "lisi@example.com" } ], "current": 1, "size": 2, "total": 2, "pages": 1, "orderBy": "id asc", "orderByOnly": true } }

10. 配置说明

在 application.yml 中添加配置

yaml

# PageHelper 配置 pagehelper: helper-dialect: mysql # 数据库方言 reasonable: true # 分页参数合理化 support-methods-arguments: true params: count=countSql auto-runtime-dialect: true # 应用配置 app: page: max-page-size: 1000 # 最大每页条数限制

11. 注意事项

  1. 性能优化

    • 对于大数据量的表,建议使用countFlag=0禁用 count 查询

    • 合理设置max-page-size防止恶意查询

  2. 使用规范

    • 所有需要分页的方法必须添加@NeedPage注解

    • Service 层方法直接返回 List,不要处理分页逻辑

    • 复杂查询建议使用 PageHelper 的 lambda 表达式

  3. 安全考虑

    • SQL 注入防护:PageHelper 会自动处理排序字段的安全性问题

    • 内存保护:通过max-page-size限制单次查询数据量

  4. 兼容性

    • 支持传统的 XML 配置方式

    • 支持 MyBatis-Plus 共存使用

    • 支持多数据源分页

12. 高级特性

动态条件查询示例

java

@NeedPage @GetMapping("/search") public Result searchUsers( @RequestParam(required = false) String keyword, @RequestParam(required = false) Integer status) { // 使用PageHelper的lambda表达式 PageHelper.startPage(1, 10).setOrderBy("create_time desc"); // 构建查询条件 Example example = new Example(User.class); if (StringUtils.hasText(keyword)) { example.createCriteria() .andLike("username", "%" + keyword + "%") .orLike("email", "%" + keyword + "%"); } if (status != null) { example.createCriteria().andEqualTo("status", status); } List<User> users = userMapper.selectByExample(example); return Result.ok(users); }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 11:08:04

告别环境噩梦:预配置镜像带你轻松玩转AI识图

告别环境噩梦&#xff1a;预配置镜像带你轻松玩转AI识图 你是否也像独立开发者小王一样&#xff0c;曾经花费数个周末在本地机器上折腾各种依赖和版本冲突&#xff0c;只为跑通一个开源AI识图项目&#xff1f;现在&#xff0c;预配置镜像的出现让这一切变得简单。本文将带你了解…

作者头像 李华
网站建设 2026/4/16 12:20:51

5个IDEA插件在真实项目中的妙用案例

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个案例展示应用&#xff0c;包含5个真实项目场景&#xff08;如电商系统、微服务架构等&#xff09;&#xff0c;每个场景演示2-3个IDEA插件的具体使用方法和效果对比。要求…

作者头像 李华
网站建设 2026/4/12 10:04:24

谷歌镜像无法加载?离线部署万物识别保障业务连续性

谷歌镜像无法加载&#xff1f;离线部署万物识别保障业务连续性 引言&#xff1a;当云端服务不可靠时&#xff0c;本地化推理是唯一出路 在AI应用日益普及的今天&#xff0c;图像识别能力已成为许多业务系统的标配功能。然而&#xff0c;依赖公网调用的云服务&#xff08;如谷…

作者头像 李华
网站建设 2026/4/16 11:13:29

万物识别+知识图谱:快速构建语义理解系统

万物识别知识图谱&#xff1a;快速构建语义理解系统 作为一名知识图谱工程师&#xff0c;我经常遇到这样的需求&#xff1a;如何让系统不仅能处理结构化文本数据&#xff0c;还能理解图像中的丰富信息&#xff1f;传统方法需要分别部署视觉识别模型和图谱系统&#xff0c;再手动…

作者头像 李华
网站建设 2026/4/16 16:24:40

UNI.PREVIEWIMAGE在电商App中的实际应用案例

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个电商商品详情页&#xff0c;集成UNI.PREVIEWIMAGE实现商品图片的预览功能。要求支持左右滑动切换图片&#xff0c;双击放大缩小&#xff0c;长按保存图片。同时&#xff0…

作者头像 李华
网站建设 2026/4/16 9:21:42

揭秘MCP AI Copilot核心能力:如何在生产环境高效落地AI运维?

第一章&#xff1a;MCP AI Copilot核心能力概览MCP AI Copilot 是一款面向企业级开发与运维场景的智能助手&#xff0c;深度融合人工智能与自动化技术&#xff0c;旨在提升软件交付效率、优化系统稳定性并降低人为操作风险。其核心能力覆盖代码生成、故障诊断、配置建议、安全合…

作者头像 李华