mybatisplus分页mybatis-plus自带xml写法以及注解写法分页插件

日常开发中,部分sql mybatis-plus 自带Mapper无法实现,需要手写,此时需要分页的话,用mybatis-plus 自带分页最方便了,简单介绍下。

Mapper 特殊的地方就是再参数那里加入com.baomidou.mybatisplus.core.metadata包下的IPage 类


public interface UserMapper{
    public MyPage<User> getUserList(
            IPage pageQuery,
            @Param("parma") param
    );
}

然后就正常在xml写sql,User类无特殊之处,就正常属性字段,加上@Data注解(或get set方法即可)
自定义MyPage类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonView;
import io.swagger.annotations.ApiModelProperty;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import project.jtjr.financialtrade.LabelJsonViewBase;
import springfox.documentation.annotations.ApiIgnore;

@JsonIgnoreProperties(
    value = {"orders", "hitCount", "pages", "searchCount"},
    ignoreUnknown = true
)
public class MyPage<T> implements IPage<T> {
    @JsonView({LabelJsonViewBase.class})
    @ApiModelProperty("当前分页记录集")
    private List<T> records;
    @JsonView({LabelJsonViewBase.class})
    @ApiModelProperty("总数据条数")
    private long total;
    @JsonView({LabelJsonViewBase.class})
    @ApiModelProperty("每页显示条数")
    private long size;
    @JsonView({LabelJsonViewBase.class})
    @ApiModelProperty("当前页")
    private long current;
    @ApiModelProperty(
        hidden = true
    )
    private List<OrderItem> orders;
    @ApiModelProperty(
        hidden = true
    )
    private boolean optimizeCountSql;
    @ApiModelProperty(
        hidden = true
    )
    private boolean isSearchCount;
    @ApiModelProperty(
        hidden = true
    )
    private boolean hitCount;

    public MyPage() {
        this.records = new ArrayList();
        this.total = 0L;
        this.size = 9223372036854775807L;
        this.current = 1L;
        this.orders = new ArrayList();
        this.optimizeCountSql = true;
        this.isSearchCount = true;
        this.hitCount = false;
    }

    public MyPage(long current, long size) {
        this(current, size, 0L);
    }

    public MyPage(long current, long size, long total) {
        this(current, size, total, true);
    }

    public MyPage(long current, long size, boolean isSearchCount) {
        this(current, size, 0L, isSearchCount);
    }

    public MyPage(long current, long size, long total, boolean isSearchCount) {
        this.records = new ArrayList();
        this.total = 0L;
        this.size = 9223372036854775807L;
        this.current = 1L;
        this.orders = new ArrayList();
        this.optimizeCountSql = true;
        this.isSearchCount = true;
        this.hitCount = false;
        if (current > 1L) {
            this.current = current;
        }

        this.size = size;
        this.total = total;
        this.isSearchCount = isSearchCount;
    }

    @JsonView({LabelJsonViewBase.class})
    @ApiModelProperty("是否存在上一页")
    public boolean hasPrevious() {
        return this.current > 1L;
    }

    @JsonView({LabelJsonViewBase.class})
    @ApiModelProperty("是否存在下一页")
    public boolean hasNext() {
        return this.current < this.getPages();
    }

    public List<T> getRecords() {
        return this.records;
    }

    public <A> Map<A, T> getRecords(String key) {
        try {
            Map<A, T> map = new HashMap();
            Iterator var3 = this.records.iterator();

            while(var3.hasNext()) {
                T t = var3.next();
                Object value = getValueByFieldName(t, key);
                map.put(value, t);
            }

            return map;
        } catch (Throwable var6) {
            throw var6;
        }
    }

    public <A, B> Map<A, B> getRecords(String key, Class<B> tClass) {
        try {
            Map<A, B> map = new HashMap();
            Iterator var4 = this.records.iterator();

            while(var4.hasNext()) {
                T t = var4.next();
                Object value = getValueByFieldName(t, key);
                B b = JSONObject.parseObject(JSONObject.toJSONString(t), tClass);
                map.put(value, b);
            }

            return map;
        } catch (Throwable var8) {
            throw var8;
        }
    }

    private static Object getValueByFieldName(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        Class<?> clazz = object.getClass();
        Field field = null;

        while(clazz != null && field == null) {
            try {
                field = clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException var5) {
                clazz = clazz.getSuperclass();
            }
        }

        if (field == null) {
            throw new NoSuchFieldException("无法找到指定的字段:" + fieldName);
        } else {
            field.setAccessible(true);
            return field.get(object);
        }
    }

    public MyPage<T> setRecords(List<T> records) {
        this.records = records;
        return this;
    }

    public long getTotal() {
        return this.total;
    }

    public MyPage<T> setTotal(long total) {
        this.total = total;
        return this;
    }

    public long getSize() {
        return this.size;
    }

    public MyPage<T> setSize(long size) {
        this.size = size;
        return this;
    }

    public long getCurrent() {
        return this.current;
    }

    public MyPage<T> setCurrent(long current) {
        this.current = current;
        return this;
    }

    /** @deprecated */
    @Nullable
    @Deprecated
    public String[] ascs() {
        return CollectionUtils.isNotEmpty(this.orders) ? this.mapOrderToArray(OrderItem::isAsc) : null;
    }

    private String[] mapOrderToArray(Predicate<OrderItem> filter) {
        List<String> columns = new ArrayList(this.orders.size());
        this.orders.forEach((i) -> {
            if (filter.test(i)) {
                columns.add(i.getColumn());
            }

        });
        return (String[])columns.toArray(new String[0]);
    }

    private void removeOrder(Predicate<OrderItem> filter) {
        for(int i = this.orders.size() - 1; i >= 0; --i) {
            if (filter.test(this.orders.get(i))) {
                this.orders.remove(i);
            }
        }

    }

    public MyPage<T> addOrder(OrderItem... items) {
        this.orders.addAll(Arrays.asList(items));
        return this;
    }

    public MyPage<T> addOrder(List<OrderItem> items) {
        this.orders.addAll(items);
        return this;
    }

    /** @deprecated */
    @Deprecated
    public MyPage<T> setAscs(List<String> ascs) {
        return CollectionUtils.isNotEmpty(ascs) ? this.setAsc((String[])ascs.toArray(new String[0])) : this;
    }

    /** @deprecated */
    @Deprecated
    public MyPage<T> setAsc(String... ascs) {
        this.removeOrder(OrderItem::isAsc);
        String[] var2 = ascs;
        int var3 = ascs.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            String s = var2[var4];
            this.addOrder(OrderItem.asc(s));
        }

        return this;
    }

    /** @deprecated */
    @Deprecated
    public String[] descs() {
        return this.mapOrderToArray((i) -> {
            return !i.isAsc();
        });
    }

    /** @deprecated */
    @Deprecated
    public MyPage<T> setDescs(List<String> descs) {
        if (CollectionUtils.isNotEmpty(descs)) {
            this.removeOrder((item) -> {
                return !item.isAsc();
            });
            Iterator var2 = descs.iterator();

            while(var2.hasNext()) {
                String s = (String)var2.next();
                this.addOrder(OrderItem.desc(s));
            }
        }

        return this;
    }

    /** @deprecated */
    @Deprecated
    public MyPage<T> setDesc(String... descs) {
        this.setDescs(Arrays.asList(descs));
        return this;
    }

    public List<OrderItem> orders() {
        return this.getOrders();
    }

    @ApiIgnore
    public List<OrderItem> getOrders() {
        return this.orders;
    }

    public void setOrders(List<OrderItem> orders) {
        this.orders = orders;
    }

    public boolean optimizeCountSql() {
        return this.optimizeCountSql;
    }

    @ApiModelProperty(
        hidden = true
    )
    public boolean isSearchCount() {
        return this.total < 0L ? false : this.isSearchCount;
    }

    public MyPage<T> setSearchCount(boolean isSearchCount) {
        this.isSearchCount = isSearchCount;
        return this;
    }

    public MyPage<T> setOptimizeCountSql(boolean optimizeCountSql) {
        this.optimizeCountSql = optimizeCountSql;
        return this;
    }

    public void hitCount(boolean hit) {
        this.hitCount = hit;
    }

    public boolean isHitCount() {
        return this.hitCount;
    }

    @ApiModelProperty(
        hidden = true
    )
    public long getPages() {
        if (this.getSize() == 0L) {
            return 0L;
        } else {
            long pages = this.getTotal() / this.getSize();
            if (this.getTotal() % this.getSize() != 0L) {
                ++pages;
            }

            return pages;
        }
    }

    public <A> void clone(MyPage<A> target, Class targetClass) {
        target.setRecords(JSON.parseArray(JSON.toJSONString(this.getRecords()), targetClass));
        target.setTotal(this.getTotal());
        target.setSize(this.getSize());
        target.setCurrent(this.getCurrent());
        target.setOrders(this.orders());
        target.setOptimizeCountSql(this.optimizeCountSql());
        target.setSearchCount(this.isSearchCount());
        target.hitCount(this.isHitCount());
    }
}

userService调用mapper

MyPage<User> myPage = new MyPage<User>(pageNum,pageSize);//也可加入sort等属性,具体用法阅读源码
MyPage<User> page = userMapper.getUserList(myPage,条件);

此时得到的page,里面已包含分页查询相关返回内容

在这里插入图片描述

注解的方式,跟xml区别不大

public interface UserMapper{
	@select(select * from user where gender = #{param})
    public MyPage<User> getUserList(
            IPage pageQuery,
            @Param("parma") param
    );
}
<think>嗯,用户问的是MyBatis-Plus自定义Mapper如何分页。我需要先回忆一下MyBatis-Plus分页机制。记得MyBatis-Plus有一个分页插件,通过配置后,可以使用其内置的Page对象来实现分页查询。但用户提到的是自定义Mapper的情况,可能需要结合XML或者注解方式写的SQL。 首先,用户可能已经知道MyBatis-Plus的常规分页方法,比如使用selectPage方法,但现在他们需要在自己的Mapper里写自定义SQL,这时候分页该怎么处理呢? 步骤大概是这样的:首先确保分页插件已经正确配置。然后,在自定义的Mapper方法中,参数需要传入Page对象,并且SQL里不需要写LIMIT,因为分页插件会自动处理。同时,返回类型应该是Page,这样结果会被封装到Page对象里。 不过,可能用户会遇到的问题是,如何在XML中编写对应的SQL,并且确保分页插件生效。比如,在XML中,方法参数是Page,并且SQL正确的话,插件会自动添加分页语句。但需要确认是否在配置类中添加了分页拦截器,否则可能不生效。 另外,用户可能想知道返回的Page对象里有哪些有用的信息,比如总记录数、当前页数据等。或者是否有其他方式,比如使用IPage接口,或者自己手动处理分页参数。 还有可能用户在使用过程中,自定义的SQL比较复杂,比如多表联查,这时候分页插件是否能正确拦截,并改写SQL。可能需要提醒用户,如果SQL写法特殊,可能需要验证生成的SQL是否正确,是否有正确添加LIMIT和COUNT语句。 也有可能用户想了解,如果不想返回Page对象,而是返回普通的List,但同时又需要分页效果,这时候应该怎么处理。不过通常建议返回Page,以便获取分页信息。 总结下来,回答应该包括以下几个步骤:配置分页插件,自定义Mapper方法参数和返回类型,编写XML中的SQL,以及调用方法的方式。同时,要提醒常见的注意事项,比如插件配置是否正确,SQL是否正确,避免手动添加LIMIT等。</think>MyBatis-Plus 的自定义 Mapper 实现分页功能,需要结合其内置的分页插件和 `Page` 对象。以下是具体步骤和示例: --- ### 1. **配置分页插件** 在 Spring Boot 的配置类中添加分页插件拦截器(若未配置): ```java @Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 根据数据库类型选择 return interceptor; } } ``` --- ### 2. **自定义 Mapper 方法** 在自定义的 Mapper 接口中定义分页查询方法,参数为 `Page` 对象,返回值为 `IPage<T>`: ```java public interface UserMapper extends BaseMapper<User> { // 自定义分页查询 IPage<User> selectUserPage(Page<User> page, @Param("state") Integer state); } ``` --- ### 3. **编写 XML/SQL** 在对应的 XML 文件中编写 SQL,**无需手动添加 `LIMIT`**,分页插件会自动处理: ```xml <!-- UserMapper.xml --> <select id="selectUserPage" resultType="User"> SELECT * FROM user WHERE state = #{state} </select> ``` --- ### 4. **调用分页方法** 在 Service 或 Controller 中调用分页查询: ```java // 创建分页对象,参数:当前页、每页大小 Page<User> page = new Page<>(1, 10); // 调用自定义方法(假设查询 state=1 的用户) IPage<User> userPage = userMapper.selectUserPage(page, 1); // 获取分页数据 List<User> users = userPage.getRecords(); // 当前页数据 long total = userPage.getTotal(); // 总记录数 long pages = userPage.getPages(); // 总页数 ``` --- ### 关键点说明 1. **自动分页** 分页插件会拦截 SQL 并自动追加数据库方言的 `LIMIT` 语句(如 MySQL 的 `LIMIT ?,?`),同时自动执行 `COUNT` 查询总记录数。 2. **复杂 SQL 支持** 即使你的 SQL 包含多表关联或复杂条件,分页插件依然可以正确分页。 3. **返回结果** `IPage<T>` 对象包含分页数据(`records`)、总记录数(`total`)、每页大小(`size`)等所有分页信息。 --- ### 常见问题 - **SQL分页?** 检查是否漏了配置分页插件,或 XML 中的方法参数未使用 `Page` 对象。 - **手动编写 `LIMIT`** 如果 SQL 中手动添加了 `LIMIT`,分页插件会失效,需依赖插件自动追加。 - **自定义 `COUNT` 语句** 若自动生成的 `COUNT` 语句效率低,可在 XML 中通过 `@Select` 注解XML 的 `<select>` 标签指定自定义 `COUNT` 语句: ```xml <select id="selectUserPage" resultType="User"> SELECT * FROM user WHERE state = #{state} </select> <!-- 指定自定义 COUNT 语句的 ID --> <select id="selectUserPage_COUNT" resultType="java.lang.Long"> SELECT COUNT(*) FROM user WHERE state = #{state} </select> ``` --- 通过以上步骤,即可在 MyBatis-Plus 的自定义 Mapper 中实现灵活的分页查询。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值