【Mybatis】Mybatis常见的分页实现方法

引言

后台查询数据的时如果数据量较多需要对数据进行分页处理,Mybatis有多种方法能够实现数据分页, 最简单的就是利用原生的sql关键字limit来实现分页,也可以利用interceptor来拼接sql实现分页功能,还可以利用PageHelper开源框架来实现分页。

关键字limit实现分页

首先创建一个Mybatis工程 【Spring】Spring整合Mybatis案例
工程结构如下:
在这里插入图片描述

第一步:增加分页实体类

public class Pager<T> {
    
    
    private int page;//分页起始页
    private int size;//每页记录数
    private List<T> data;//返回的记录集合
    private long total;//总记录条数

    public int getPage() {
    
    
        return page;
    }

    public void setPage(int page) {
    
    
        this.page = page;
    }

    public int getSize() {
    
    
        return size;
    }

    public void setSize(int size) {
    
    
        this.size = size;
    }

    public List<T> getData() {
    
    
        return data;
    }

    public void setData(List<T> data) {
    
    
        this.data = data;
    }

    public long getTotal() {
    
    
        return total;
    }

    public void setTotal(long total) {
    
    
        this.total = total;
    }

    @Override
    public String toString() {
    
    
        return "Pager{" +
                "page=" + page +
                ", size=" + size +
                ", data=" + data +
                ", total=" + total +
                '}';
    }
}

第二步:增加分页方法

UserMapper中添加两个方法

@Repository("userMapper")
@Mapper
public interface UserMapper {
    
    
    List<User> findUserByPage(Map<String, Object> map);
    long findUserCount();
}

UserControl

@Controller("userControl")
public class UserControl {
    
    
    @Autowired
    UserMapper userMapper;

    public Pager<User> findByUserPager(int page, int size){
    
    
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("page", (page-1)*size);
        params.put("size", size);
        List<User> list = userMapper.findUserByPage(params);
        Pager<User> pager = new Pager<User>();
        pager.setData(list);
        pager.setTotal(userMapper.findUserCount());
        return pager;
    }
}

UserMapper.xml

<?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.lucas.mybatis.mapper.UserMapper">
    <select id="findUserByPage" resultType="com.lucas.mybatis.model.User" >
        select  * from user  limit #{page},#{size}
    </select>
    <select id="findUserCount" resultType="long">
    select count(1) from user
    </select>
</mapper>

第三步:测试代码

public class App {
    
    
    public static void main(String[] args) {
    
    
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserControl userControl = (UserControl) applicationContext.getBean("userControl");
        Pager<User> userPager = userControl.findByUserPager(1,10);
        userPager.setPage(1);
        userPager.setSize(10);
        System.out.println(userPager);
    }
}

结果如下:
在这里插入图片描述

Interceptor Plugin实现分页

首先定一个拦截器,拦截器会拦截所有以ByPage结尾的方法,然后拼接sql 语句的limit关键字实现分页

@Intercepts({
    
    @Signature(type = StatementHandler.class, method = "prepare", args = {
    
    Connection.class, Integer.class})})
public class MyPageInterceptor implements Interceptor {
    
    

    private int page;
    private int size;
    @SuppressWarnings("unused")
    private String dbType;

    @SuppressWarnings("unchecked")
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
    
    
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
        while (metaObject.hasGetter("h")) {
    
    
            Object object = metaObject.getValue("h");
            metaObject = SystemMetaObject.forObject(object);
        }
        while (metaObject.hasGetter("target")) {
    
    
            Object object = metaObject.getValue("target");
            metaObject = SystemMetaObject.forObject(object);
        }
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        String mapId = mappedStatement.getId();
        if (mapId.matches(".+ByPage$")) {
    
    
            ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
            Map<String, Object> params = (Map<String, Object>) parameterHandler.getParameterObject();
            page = (int) params.get("page");
            size = (int) params.get("size");
            String sql = (String) metaObject.getValue("delegate.boundSql.sql");
            sql += " limit " + (page - 1) * size + "," + size;
            metaObject.setValue("delegate.boundSql.sql", sql);
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
    
    
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    
    
        String limit = properties.getProperty("limit", "10");
        this.page = Integer.parseInt(limit);
        this.dbType = properties.getProperty("dbType", "mysql");
    }

}

修改controller的findByUserPager方法,拦截器已经自动帮我们算好了page和size的值

    public Pager<User> findByUserPager(int page, int size){
    
    
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("page", page);
        params.put("size", size);
        List<User> list = userMapper.findUserByPage(params);
        Pager<User> pager = new Pager<User>();
        pager.setData(list);
        pager.setTotal(userMapper.findUserCount());
        return pager;
    }

UserMapper.xml

<?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.lucas.mybatis.mapper.UserMapper">
    <select id="findUserByPage" resultType="com.lucas.mybatis.model.User" >
        select  * from user
    </select>
    <select id="findUserCount" resultType="long">
    select count(1) from user
    </select>
</mapper>

Spring配置文件中添加拦截器

  <bean id="myPageInterceptor" class="com.lucas.mybatis.MyPageInterceptor"/>
    <!-- 配置Mybatis工厂,指定数据源,SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <!-- 配置mapper.xml文件 -->
        <property name="configLocation" value="mybatis-config.xml"></property>
        <property name="plugins" ref="myPageInterceptor"/>
    </bean>

运行结果同上

PageHelper实现分页

还可以利用知名的Mybatis开源分页框架 PageHelper来实现分页,该方法无须自己实现拦截器
官网:https://github.com/pagehelper/Mybatis-PageHelper
首先pom.xml文件中引入依赖

    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.2.0</version>
    </dependency>

修改Spring配置文件

 <!-- 配置Mybatis工厂,指定数据源,SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <!-- 配置mapper.xml文件 -->
        <property name="configLocation" value="mybatis-config.xml"></property>
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <!--使用下面的方式配置参数,一行配置一个 -->
                        <value>
                            params=value1
                        </value>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

修改UserControlfindByUserPager方法

@Controller("userControl")
public class UserControl {
    
    
    @Autowired
    UserMapper userMapper;

    public Pager<User> findByUserPager(int page, int size){
    
    

        PageHelper.startPage(page,size);
        List<User> list = userMapper.findUserByPage();
        Pager<User> pager = new Pager<User>();
        pager.setData(list);
        pager.setTotal(userMapper.findUserCount());
        return pager;
    }
}

运行结果同上

猜你喜欢

转载自blog.csdn.net/huweiliyi/article/details/107910959