• mybatis四种分页方式


    dao层是mybatis

    不考虑前端分页的情况

    二 数组分页

    直接java代码

    public List<User> queryByArray(int currPage, int pageSize) {
            //查询数据
            List<User> list= mapper.query();
            //从第几条数据开始
            int firstIndex = (currPage - 1) * pageSize;
            //到第几条数据结束
            int lastIndex = currPage * pageSize;
            //直接在list中截取
            return list.subList(firstIndex, lastIndex); 
        }    

    三 sql分页

    xml添加

    <select id="queryBySql" parameterType="map" resultMap="usermapper">
            select * from user limit #{currIndex} , #{pageSize}
    </select>

    java代码

    public List<User> queryBySql(int currPage, int pageSize) {
            Map<String, Object> data = new HashedMap();
            data.put("currIndex", (currPage-1)*pageSize);
            data.put("pageSize", pageSize);
            return mapper.queryBySql(data);
        }

    四 拦截器分页

    创建拦截器,拦截mybatis接口方法id以ByPage结束的语句

    package com.autumn.interceptor;
    
    import org.apache.ibatis.executor.Executor;
    import org.apache.ibatis.executor.parameter.ParameterHandler;
    import org.apache.ibatis.executor.resultset.ResultSetHandler;
    import org.apache.ibatis.executor.statement.StatementHandler;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.plugin.*;
    import org.apache.ibatis.reflection.MetaObject;
    import org.apache.ibatis.reflection.SystemMetaObject;
    
    import java.sql.Connection;
    import java.util.Map;
    import java.util.Properties;
    
    /**
     * @Intercepts 说明是一个拦截器
     * @Signature 拦截器的签名
     * type 拦截的类型 四大对象之一( Executor,ResultSetHandler,ParameterHandler,StatementHandler)
     * method 拦截的方法
     * args 参数,高版本需要加个Integer.class参数,不然会报错
     */
    @Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
    public class MyPageInterceptor implements Interceptor {
    
        //每页显示的条目数
        private int pageSize;
        //当前现实的页数
        private int currPage;
        //数据库类型
        private String dbType;
    
    
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            //获取StatementHandler,默认是RoutingStatementHandler
            StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
            //获取statementHandler包装类
            MetaObject MetaObjectHandler = SystemMetaObject.forObject(statementHandler);
    
            //分离代理对象链
            while (MetaObjectHandler.hasGetter("h")) {
                Object obj = MetaObjectHandler.getValue("h");
                MetaObjectHandler = SystemMetaObject.forObject(obj);
            }
    
            while (MetaObjectHandler.hasGetter("target")) {
                Object obj = MetaObjectHandler.getValue("target");
                MetaObjectHandler = SystemMetaObject.forObject(obj);
            }
    
            //获取连接对象
            //Connection connection = (Connection) invocation.getArgs()[0];
    
    
            //object.getValue("delegate");  获取StatementHandler的实现类
    
            //获取查询接口映射的相关信息
            MappedStatement mappedStatement = (MappedStatement) MetaObjectHandler.getValue("delegate.mappedStatement");
            String mapId = mappedStatement.getId();
    
            //statementHandler.getBoundSql().getParameterObject();
    
            //拦截以.ByPage结尾的请求,分页功能的统一实现
            if (mapId.matches(".+ByPage$")) {
                //获取进行数据库操作时管理参数的handler
                ParameterHandler parameterHandler = (ParameterHandler) MetaObjectHandler.getValue("delegate.parameterHandler");
                //获取请求时的参数
                Map<String, Object> paraObject = (Map<String, Object>) parameterHandler.getParameterObject();
                //也可以这样获取
                //paraObject = (Map<String, Object>) statementHandler.getBoundSql().getParameterObject();
    
                //参数名称和在service中设置到map中的名称一致
                currPage = (int) paraObject.get("currPage");
                pageSize = (int) paraObject.get("pageSize");
    
                String sql = (String) MetaObjectHandler.getValue("delegate.boundSql.sql");
                //也可以通过statementHandler直接获取
                //sql = statementHandler.getBoundSql().getSql();
    
                //构建分页功能的sql语句
                String limitSql;
                sql = sql.trim();
                limitSql = sql + " limit " + (currPage - 1) * pageSize + "," + pageSize;
    
                //将构建完成的分页sql语句赋值个体'delegate.boundSql.sql',偷天换日
                MetaObjectHandler.setValue("delegate.boundSql.sql", limitSql);
            }
            //调用原对象的方法,进入责任链的下一级
            return invocation.proceed();
        }
    
    
        //获取代理对象
        @Override
        public Object plugin(Object o) {
            //生成object对象的动态代理对象
            return Plugin.wrap(o, this);
        }
    
        //设置代理对象的参数
        @Override
        public void setProperties(Properties properties) {
            //如果项目中分页的pageSize是统一的,也可以在这里统一配置和获取,这样就不用每次请求都传递pageSize参数了。参数是在配置拦截器时配置的。
            String limit1 = properties.getProperty("limit", "10");
            this.pageSize = Integer.valueOf(limit1);
            this.dbType = properties.getProperty("dbType", "mysql");
        }
    }

    大部分框架都是用这种实现方法,建议直接看框架的代码实现,此处做了解即可

    四 RowBounds分页

    mybatis接口加入RowBounds参数 ,在数据量小时,RowBounds不失为一种好办法。但是数据量大时,实现拦截器就很有必要了。

        public List<User> queryByRowBounds( int start, int limit) {
            return mapper.query(new RowBounds(start, limit));
        }

    五 扯开了说

    分页不应该一次查一页,最后就是一次查多几页,我的老大是这么要求的

    也就是说上述查一页的方法有点落后了,不过改起来也简单

    但是我和他说,连百度都是一页一页的查...

    我和他都沉默了

  • 相关阅读:
    页面内容[置顶] 采用Div+Css布局——牛腩
    区域函数[置顶] linux 3.4.10 内核内存管理源代码分析5:伙伴系统初始化
    安装应用android批量安装APK
    选择版本Win7系统VS2010下搭建qt开发环境
    字体格式The format of Oracle tnsnames.ora file
    程序执行vhdl中延时器的编写
    概率链接nbu 2416 奇怪的散步
    中国主题ASP.Net课堂实验4
    要求终点HDU1010:Tempter of the Bone
    解决方案编程苦B和二B程序员别忘了养生
  • 原文地址:https://www.cnblogs.com/ydymz/p/14225869.html
Copyright © 2020-2023  润新知