`

springmvc mybatis 分页插件

 
阅读更多

结合Spring的配置


Xml代码 
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="typeAliasesPackage" value="xx.xx.xx.entity" /> 
    <property name="plugins"> 
       <list> 
          <!-- 配置自己实现的分页插件 --> 
          <bean class="xx.xx.xx.mybatis.PagingPlugin"> 
            <property name="dialect" value="mysql"/> 
          </bean> 
        </list> 
    </property> 
</bean> 
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 
    <property name="basePackage" value="xx.xx.xx.dao" /> 
</bean> 
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="typeAliasesPackage" value="xx.xx.xx.entity" />
    <property name="plugins">
       <list>
          <!-- 配置自己实现的分页插件 -->
          <bean class="xx.xx.xx.mybatis.PagingPlugin">
            <property name="dialect" value="mysql"/>
          </bean>
        </list>
    </property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="xx.xx.xx.dao" />
</bean>

●传递多个参数


Java代码 
//使用@Param来注解,例如:  
List queryXX(@Param("arg1") int arg1, @Param("arg2") String arg2); 
//使用@Param来注解,例如:
List queryXX(@Param("arg1") int arg1, @Param("arg2") String arg2);

●分页插件。 有以下缺点:


暂时只实现mysql和oracle
oracle未测试
未考虑取总数的性能
未考虑排序
查找的结果集未能自动放到分页对象(Page)中

Page.java


Java代码 
public class Page{  
    private int limit = 20; //每页显示条数  
    private int start = 0;  //起始行号  
    private long total = -1; //总数  
    private List result = new ArrayList(); //结果集  
    //---- 省略get set ----//  

public class Page{
 private int limit = 20; //每页显示条数
 private int start = 0;  //起始行号
 private long total = -1; //总数
 private List result = new ArrayList(); //结果集
 //---- 省略get set ----//
}
PagingPlugin.java


Java代码 
/** 
 * Mybatis的分页查询插件,通过拦截StatementHandler的prepare方法来实现。 
 * 只有在参数列表中包括Page类型的参数时才进行分页查询。 
 * 在多参数的情况下,只对第一个Page类型的参数生效。 
 * 另外,在参数列表中,Page类型的参数无需用@Param来标注 
 * @author linzongxue 2012-1-16(修改) 
 * 
 */ 
@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class})})   
public class PagingPlugin implements Interceptor {  
    private String dialect;  
 
    @SuppressWarnings("unchecked")  
    @Override 
    public Object intercept(Invocation invocation) throws Throwable {  
        if(!(invocation.getTarget() instanceof RoutingStatementHandler))   
            return invocation.proceed();  
          
        RoutingStatementHandler statementHandler = (RoutingStatementHandler)invocation.getTarget();  
        BoundSql boundSql = statementHandler.getBoundSql();  
        //分析是否含有分页参数,如果没有则不是分页查询  
        //注意:在多参数的情况下,只处理第一个分页参数  
        Page page = null;  
        Object paramObj = boundSql.getParameterObject();  
        if (paramObj instanceof Page){ //只有一个参数的情况  
            page = (Page)paramObj;  
        }  
        else if (paramObj instanceof Map){ //多参数的情况,找到第一个Page的参数  
            for (Map.Entry<String, Object> e : ((Map<String, Object>)paramObj).entrySet()){  
                if (e.getValue() instanceof Page){  
                    page = (Page)e.getValue();  
                    break;  
                }  
            }  
        }  
          
        if (page == null) return invocation.proceed();  
          
        //查找总记录数,并设置Page的相关参数  
        long total = this.getTotal(invocation);  
        page.setTotal(total);  
        //生成分页SQL  
        String pageSql = generatePageSql(boundSql.getSql(), page);  
        //强制修改最终要执行的SQL  
        setFieldValue(boundSql, "sql", pageSql);  
        return invocation.proceed();  
    }  
      
    /** 
     * 获取记录总数 
     */ 
    @SuppressWarnings("unchecked")  
    private long getTotal(Invocation invocation) throws Exception{  
        RoutingStatementHandler statementHandler = (RoutingStatementHandler)invocation.getTarget();  
        BoundSql boundSql = statementHandler.getBoundSql();  
        /* 
         * 为了设置查找总数SQL的参数,必须借助MappedStatement、Configuration等这些类, 
         * 但statementHandler并没有开放相应的API,所以只好用反射来强行获取。 
         */ 
        BaseStatementHandler delegate = (BaseStatementHandler)getFieldValue(statementHandler, "delegate");  
        MappedStatement mappedStatement = (MappedStatement)getFieldValue(delegate, "mappedStatement");  
        Configuration configuration = mappedStatement.getConfiguration();  
        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();  
        Object param = boundSql.getParameterObject();  
        MetaObject metaObject = configuration.newMetaObject(param);  
          
        long total = 0;  
        String sql = boundSql.getSql();  
        String countSql = "select count(1) from (" + sql+ ") as t"; //记录统计  (mysql要求必须添加 最后的as t)  
        try{  
            Connection conn = (Connection)invocation.getArgs()[0];  
            PreparedStatement ps = conn.prepareStatement(countSql);  
            int i = 1;  
            for (ParameterMapping pm : boundSql.getParameterMappings()) {  
                Object value = null;  
                String propertyName = pm.getProperty();  
                PropertyTokenizer prop = new PropertyTokenizer(propertyName);  
                if (typeHandlerRegistry.hasTypeHandler(param.getClass())) {  
                    value = param;    
                }  
                else if (boundSql.hasAdditionalParameter(propertyName)) {  
                    value = boundSql.getAdditionalParameter(propertyName);    
                }  
                else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX)&& boundSql.hasAdditionalParameter(prop.getName())) {    
                    value = boundSql.getAdditionalParameter(prop.getName());  
                    if (value != null) {    
                        value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));    
                    }  
                } else {    
                    value = metaObject.getValue(propertyName);  
                }  
 
                pm.getTypeHandler().setParameter(ps, i++, value, pm.getJdbcType());  
            }  
            ResultSet rs = ps.executeQuery();  
            rs.next();  
            total = rs.getLong(1);  
            rs.close();    
            ps.close();  
        }  
        catch (Exception e){  
            throw new RuntimeException("分页查询无法获取总记录数", e);  
        }  
        return total;  
    }  
      
    /** 
     * 生成分页SQL 
     */ 
    private String generatePageSql(String sql, Page page){  
        StringBuilder pageSql = new StringBuilder();  
        if("mysql".equals(dialect)){  
            pageSql.append(sql);  
            pageSql.append(" limit ").append(page.getStart()).append(",").append(page.getLimit());    
        }  
        else if("oracle".equals(dialect)){  
            pageSql.append("select * from (select t.*, ROWNUM num from (")  
                .append(sql).append(") as t where ROWNUM <= ")  
                .append(page.getStart() + page.getLimit())  
                .append(") where num > ").append(page.getStart());  
        }  
        else{  
            throw new RuntimeException("分页插件还不支持数据库类型:" + dialect);  
        }  
        return pageSql.toString();  
    }  
      
    /** 
     * 用反射取对象的属性值 
     */ 
    private Object getFieldValue(Object obj, String fieldName) throws Exception{          
        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {  
            try{  
                Field field = superClass.getDeclaredField(fieldName);  
                field.setAccessible(true);  
                return field.get(obj);  
            }  
            catch(Exception e){}  
        }  
        return null;  
    }  
 
    /** 
     * 用反射设置对象的属性值 
     */ 
    private void setFieldValue(Object obj, String fieldName, Object fieldValue) throws Exception{  
        Field field = obj.getClass().getDeclaredField(fieldName);  
        field.setAccessible(true);  
        field.set(obj, fieldValue);  
    }  
      
    @Override 
    public Object plugin(Object target) {  
        return Plugin.wrap(target, this);  
    }  
      
    @Override 
    public void setProperties(Properties props) {  
          
    }  
      
    public void setDialect(String dialect){  
        this.dialect = dialect.toLowerCase();  
    }  
      
    public String getDialect(){  
        return this.dialect;  
    }  

 

<tr> 
          <td><%=empno%></td> 
          <td><%=ename%></td> 
          <td><%=job%></td> 
          <td><%=hiredate%></td> 
          <td><%=sal%></td> 
          <td><%=comm%></td> 
      </tr> 
          <% 
      }while(rs.next()); 
      con.close(); 
  } 
  catch(Exception e){ 
       
  } 
 
table> 
 href = "multipage.jsp?curPage=1" >首页</a> 
 href = "multipage.jsp?curPage=<%=curPage-1%>" >上一页</a> 
 href = "multipage.jsp?curPage=<%=curPage+1%>" >下一页</a> 
 href = "multipage.jsp?curPage=<%=pageCount%>" >尾页</a> 
<%=curPage%>页/共<%=pageCount%>页 

分享到:
评论

相关推荐

    javaee-SpringMVC-Mybatis 分页插件

    本项目“javaee-SpringMVC-Mybatis 分页插件”显然是一个结合了这三个框架实现的分页功能示例。下面我们将深入探讨这些技术及其分页插件的应用。 1. **JavaEE**:JavaEE(Java Platform, Enterprise Edition)是...

    springmvc mybatis 分页查询

    总的来说,"springmvc mybatis 分页查询"项目展示了如何整合这两个强大的框架,实现高效的数据库查询。对于初学者,理解这个项目的实现方式有助于提升对Web开发和数据库操作的理解;对于经验丰富的开发者,这也是一...

    spring + springmvc + mybatis 整合 及 mybatis-pagehelper分页

    4. **PageHelper分页插件**:MyBatis-PageHelper是一个强大的分页插件,它可以自动处理分页逻辑,简化开发。在Spring的配置文件中引入PageHelper的配置,包括其初始化参数,如dialect(数据库类型)、reasonable...

    SpringMVC+Mybatis+分页插件的实现

    自己最近搭建的一个SpringMVC+Mybatis的框架 属于无实体类的框架 并实现了Myabtis的自动分页和总数查询 只要传入分页参数便能自动查询总数和分页 总数封装在参数里面执行查询后可以直接从参数中获取

    spring + springmvc + mybatis 整合 demo 及 mybatis-paginator分页 demo

    "mybatis-paginator分页 demo"部分则是关于MyBatis的分页插件Mybatis-Paginator的使用。Mybatis-Paginator是一个轻量级的分页插件,它能在运行时自动添加分页SQL,避免手动编写复杂的分页逻辑。使用这个插件,开发者...

    SpringMVC+MyBatis+EasyUI简单分页Demo

    在本项目"SpringMVC+MyBatis+EasyUI简单分页Demo"中,我们将探讨如何结合这三种技术实现一个具备基本分页功能的Web应用。SpringMVC是Spring框架的一部分,负责处理HTTP请求和响应;MyBatis是一个轻量级的持久层框架...

    springmvc+mybatis+分页查询

    在本项目中,我们主要...综上所述,这个项目展示了如何在Spring MVC和MyBatis框架下实现一个完整的Web应用,通过PageHelper插件轻松实现分页查询功能。理解并掌握这些知识点,对于开发基于Java的Web应用是非常重要的。

    mybatis平台包 集成分页插件

    mybatis集成了分页的插件,采用springmvc+spring+mybatis或者springboot+mybatis的时候可以无缝对接使用

    spring+springmvc+mybatis+jsp分页插件

    本项目"spring+springmvc+mybatis+jsp分页插件"正是为了解决这个问题而设计的。下面我们将详细探讨这个项目的各个组成部分及其工作原理。 首先,Spring是一个开源的Java框架,它提供了全面的编程和配置模型,简化了...

    Java简单实现SpringMVC+MyBatis分页插件

    在这个场景下,我们讨论的是如何在SpringMVC和MyBatis的基础上实现一个无实体类的分页插件。 首先,让我们理解什么是无实体类框架。在传统的MyBatis使用中,通常会为每个数据库表创建对应的Java实体类。然而,在无...

    javaee-ssm-springmvc-mybatis分页实例大全

    本教程“javaee-ssm-springmvc-mybatis分页实例大全”专注于这三个框架的整合以及实现分页功能,这对初学者深入理解SSM框架和掌握分页技术至关重要。 首先,Spring作为基础框架,提供了依赖注入(DI)和面向切面...

    Spring4+SpringMVC+MyBatis完整框架网上商城

    dubbo zookeep redis mongodb Servlet 3.0 Spring4 SpringMVC MyBatis ...MyBatis分页插件PageHelper MyBatis通用Mapper 源码完整+带sql脚本+亲测可以用,而且功能很强大,是一个完善的框架实例。

    mybatis分页插件pageHelper详解及简单实例

    mybatis分页插件pageHelper详解及简单实例 工作的框架spring springmvc mybatis3 首先使用分页插件必须先引入maven依赖,在pom.xml中添加如下 &lt;!-- 分页助手 --&gt; &lt;groupId&gt;com.github.pagehelper&lt;/groupId&gt; ...

    013-MyBatis分页插件-PageHelper1

    【MyBatis分页插件PageHelper详解】 PageHelper是针对MyBatis的开源分页插件,可以在不改变原有代码的基础上实现高效的分页效果。它通过GitHub进行维护,地址为:https://github.com/pagehelper/Mybatis-PageHelper...

    springmvc+mybatis+easyUI分页后台代码

    本项目是基于SpringMVC、MyBatis和EasyUI这三大框架实现的后台分页功能,旨在提供一个高效、易用的解决方案。下面将详细介绍这三个技术以及它们如何协同工作来实现前端页面的分页。 首先,SpringMVC是Spring框架的...

    springmvc+mybatis+分页整合

    1. **配置环境**:首先,确保Eclipse已安装Maven插件,导入相关依赖到pom.xml文件中,包括SpringMVC、MyBatis和分页插件的依赖。 2. **配置SpringMVC**:创建SpringMVC的配置文件(如:servlet-context.xml),配置...

    Spring+SpringMVC+MyBatis+Mysql 使用PageHelper 实现分页

    5. **PageHelper插件**:PageHelper是MyBatis的优秀扩展,专门用于实现分页功能。它提供了一种简单的方式来实现高效的分页查询,只需要在Mapper接口的方法上添加注解,即可自动完成分页相关的SQL生成和结果封装。 6...

    基于SSM的学生信息管理系统(选课)SpringMVC+MyBatis实现-软件工程课程设计

    由SpringMVC+MyBatis为主要框架,mysql8.0配置主从复制实现读写分离,主机丛机分别为腾讯云的服务器,而项目部署在阿里云上。...后端:maven、SpringMVC、MyBatis、ajax、mysql读写分离、mybatis分页

    springMVC+mybatis实现分页、登录、增删改查

    在Service层,我们可以利用MyBatis的分页插件,如PageHelper,自动实现SQL的分页查询。返回结果后,Controller将分页信息和数据传递给视图,如Bootstrap模板,展示分页效果。 权限设置则是为了确保不同用户只能访问...

    sping+ springMVC+mybatis分页,定时任务

    在SpringMVC中,可以自定义一个分页拦截器或者使用PageHelper等第三方插件来简化分页操作。 至于定时任务,Spring框架提供了Spring Task(也称为Spring Jobs)来处理定时任务。开发者可以使用@Scheduled注解来标记...

Global site tag (gtag.js) - Google Analytics