zoukankan      html  css  js  c++  java
  • mybatis框架下物理分页的实现(整个工程采用的是springmvc、spring、mybatis框架,数据库是mysql数据库)

    (一)关于分页拦截器的简单理解

        首先,要开发MyBatis的插件需要实现org.apache.ibatis.plugin.Interceptor接口,这个接口将会要求实现几个方法:intercept()、plugin()及setProperties(),intercept方法是开发人员所要执行的操作,plugin是将你插件放入到MyBatis的插件集合中去,而setProperties这是在你配置你插件的时候将plugins/plugin/properties的值设置到该插件中。
        该方法的第一句话就是获得Intercepts注解,接下来将获得在Intercepts里面的参数@Signature注解内容,在该注解中包含三个参数,分别是type,method,args。Type指定要拦截的类对象,method是指明要拦截该类的哪个方法,第三个是指明要拦截的方法参数集合。在Intercepts中可以配置多个@Signature。那么便对这写值进行遍历,已获得对应的type、method以及args。最终是获得一个HashMap对象,这些对象里面的键是类对象,而值是指定的类中方法对象。执行该端程序之后,更具target的classLoader和接口,来创建一个代理,并且,InvocationHandler是创建一个新的Plugin对象,同时将target,interceptor以及signatureMap传递给Plugin对象,当然,这里的Plugin也实现了Invocation接口。那么target对象所有的方法调用都会触发Plugin中的invoke方法,那么这里将执行开发者所有插入的操作。

        另外对拦截器类里面几个关键的类做出解释:

    (1)BoundSql类 ,封装mybatis最终产生sql的类,包括sql语句,参数,参数源数据等。
    (2)MappedStatement类,MappedStatement类在Mybatis框架中用于表示XML文件中一个sql语句节点,即一个<select />、<update />或者<insert />标签。Mybatis框架在初始化阶段会对XML配置文件进行读取,将其中的sql语句节点对象化为一个个MappedStatement对象。

       总结,本拦截器实现的目标就是在进行数据库查询操作之前,从配置文件读出相应的sql语句,将相应的参数拼接到其中,然后再进行查询。当然在拼接sql语句之前,先查询了一下数据库中相应记录的总数

    (二)拦截器类PageIntercepter.java:

    [java] view plain copy
     
    1. package cn.zyy.paging.intercepter;  
    2.   
    3. import java.sql.Connection;  
    4. import java.sql.PreparedStatement;  
    5. import java.sql.ResultSet;  
    6. import java.sql.SQLException;  
    7. import java.util.List;  
    8. import java.util.Properties;  
    9.   
    10. import org.apache.ibatis.mapping.BoundSql;  
    11. import org.apache.ibatis.mapping.MappedStatement;  
    12. import org.apache.ibatis.mapping.ParameterMapping;  
    13. import org.apache.ibatis.mapping.ParameterMode;  
    14. import org.apache.ibatis.mapping.SqlSource;  
    15. import org.apache.ibatis.plugin.Interceptor;  
    16. import org.apache.ibatis.plugin.Intercepts;  
    17. import org.apache.ibatis.plugin.Invocation;  
    18. import org.apache.ibatis.plugin.Plugin;  
    19. import org.apache.ibatis.reflection.MetaObject;  
    20. import org.apache.ibatis.session.Configuration;  
    21. import org.apache.ibatis.session.RowBounds;  
    22. import org.apache.ibatis.type.TypeHandler;  
    23. import org.apache.ibatis.type.TypeHandlerRegistry;   
    24. import cn.zyy.paging.vo.PageObject;  
    25. @Intercepts({@org.apache.ibatis.plugin.Signature(method="query", type=org.apache.ibatis.executor.Executor.class, args={MappedStatement.class, Object.class, RowBounds.class, org.apache.ibatis.session.ResultHandler.class})})  
    26. public class PageIntercepter implements Interceptor{  
    27.     @Override  
    28.     public Object intercept(Invocation invocation) throws Throwable {  
    29.         MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];  
    30.         Object object = invocation.getArgs()[1];  
    31.         if(object instanceof PageObject){  
    32.               
    33.             PageObject pageObject = (PageObject) object;  
    34.             BoundSql boundSql = mappedStatement.getBoundSql(object);  
    35.             String sql = boundSql.getSql();  
    36.               
    37.             int count = getCount(mappedStatement,boundSql);  
    38.             pageObject.setCount(count);  
    39.             int pages = (pageObject.getCount()+pageObject.getNumber()-1)/pageObject.getNumber();  
    40.             pageObject.setPages(pages>0?pages:1);  
    41.               
    42.             int offset = (pageObject.getPage() - 1) * pageObject.getNumber();  
    43.             int limit = pageObject.getNumber();  
    44.             String pageSql = pageSql(sql, offset, limit);  
    45.             BoundSql pageBoundSql = new BoundSql(mappedStatement.getConfiguration(), pageSql, boundSql.getParameterMappings(), boundSql.getParameterObject());  
    46.             MappedStatement pageMappedStatement = pageMappedStatement(mappedStatement, new PageSqlSource(pageBoundSql));  
    47.             invocation.getArgs()[0] = pageMappedStatement;  
    48.             invocation.getArgs()[2] = RowBounds.DEFAULT;  
    49.         }  
    50.         return invocation.proceed();  
    51.     }  
    52.   
    53.     @Override  
    54.     public Object plugin(Object object) {  
    55.         // TODO Auto-generated method stub  
    56.         return Plugin.wrap(object, this);  
    57.     }  
    58.   
    59.     @Override  
    60.     public void setProperties(Properties properties) {  
    61.         // TODO Auto-generated method stub  
    62.           
    63.     }  
    64.   
    65.     private int getCount(MappedStatement mappedStatement, BoundSql boundSql) throws SQLException {  
    66.           
    67.         Connection connection = null;  
    68.         PreparedStatement ps = null;  
    69.         ResultSet rs = null;  
    70.           
    71.         try {  
    72.             String countSql = countSql(boundSql.getSql());  
    73.             connection = mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection();  
    74.             ps = connection.prepareStatement(countSql);  
    75.             BoundSql countBoundSql = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), boundSql.getParameterObject());  
    76.             setCountParameters(ps, mappedStatement, countBoundSql);  
    77.             rs = ps.executeQuery();  
    78.             int count = 0;  
    79.              if (rs.next())  
    80.               {  
    81.                 count = rs.getInt(1);  
    82.               }  
    83.             return count;  
    84.         } catch (Exception e) {  
    85.             return 1000;  
    86.         }finally{  
    87.              try {  
    88.                 rs.close();  
    89.               } catch (Exception localException4) {  
    90.               }  
    91.               try {  
    92.                 ps.close();  
    93.               } catch (Exception localException5) {  
    94.               }  
    95.               try {  
    96.                 connection.close();  
    97.               }  
    98.               catch (Exception localException6) {  
    99.               }  
    100.         }  
    101.     }  
    102.       
    103.     private static String countSql(String sql){  
    104.         sql = sql.toUpperCase();  
    105.         StringBuffer countSql = new StringBuffer();  
    106.         countSql.append("SELECT COUNT(1) FROM (");  
    107.         countSql.append(sql.substring(0, sql.indexOf("ORDER BY")==-1?sql.length():sql.indexOf("ORDER BY")-1));  
    108.         countSql.append(") PAY_PAGE_T");  
    109.         return countSql.toString();  
    110.     }  
    111.       
    112.     private static void setCountParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql) throws SQLException {  
    113.         List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();  
    114.         if (parameterMappingList != null)  
    115.         {  
    116.           Configuration configuration = mappedStatement.getConfiguration();  
    117.           TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();  
    118.           Object parameterObject = boundSql.getParameterObject();  
    119.           MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);  
    120.   
    121.           int n = 1;  
    122.           for (ParameterMapping parameterMapping : parameterMappingList)  
    123.           {  
    124.             if ((parameterMapping.getMode() == ParameterMode.IN) || (parameterMapping.getMode() == ParameterMode.INOUT))  
    125.             {  
    126.               String property = parameterMapping.getProperty();  
    127.               Object value = null;  
    128.               if (parameterObject != null)  
    129.               {  
    130.                 if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))  
    131.                 {  
    132.                   value = parameterObject;  
    133.                 }  
    134.                 else  
    135.                 {  
    136.                   value = metaObject == null ? null : metaObject.getValue(property);  
    137.                 }  
    138.               }  
    139.   
    140.               TypeHandler typeHandler = parameterMapping.getTypeHandler();  
    141.               typeHandler.setParameter(ps, n, value, parameterMapping.getJdbcType());  
    142.             }  
    143.   
    144.             n++;  
    145.           }  
    146.         }  
    147.     }  
    148.       
    149.     private String pageSql(String sql, int offset, int limit) {  
    150.         sql = sql.toUpperCase();  
    151.         StringBuffer pageSql = new StringBuffer();  
    152.         pageSql.append(sql);  
    153.         pageSql.append(" LIMIT ");  
    154.         pageSql.append(offset);  
    155.         pageSql.append(", ");  
    156.         pageSql.append(limit);  
    157.         return pageSql.toString();  
    158.       }  
    159.       
    160.     private MappedStatement pageMappedStatement(MappedStatement mappedStatement, SqlSource sqlSource)  
    161.       {  
    162.         MappedStatement.Builder builder = new MappedStatement.Builder(  
    163.           mappedStatement.getConfiguration(),   
    164.           mappedStatement.getId(),   
    165.           sqlSource,   
    166.           mappedStatement.getSqlCommandType());  
    167.   
    168.         builder.resource(mappedStatement.getResource());  
    169.         builder.fetchSize(mappedStatement.getFetchSize());  
    170.         builder.statementType(mappedStatement.getStatementType());  
    171.         builder.keyGenerator(mappedStatement.getKeyGenerator());  
    172.         builder.timeout(mappedStatement.getTimeout());  
    173.         builder.parameterMap(mappedStatement.getParameterMap());  
    174.         builder.resultMaps(mappedStatement.getResultMaps());  
    175.         builder.cache(mappedStatement.getCache());  
    176.         builder.resultSetType(mappedStatement.getResultSetType());  
    177.         builder.flushCacheRequired(mappedStatement.isFlushCacheRequired());  
    178.         builder.useCache(mappedStatement.isUseCache());  
    179.         builder.resultOrdered(mappedStatement.isResultOrdered());  
    180.         builder.databaseId(mappedStatement.getDatabaseId());  
    181.         builder.lang(mappedStatement.getLang());  
    182.         if (mappedStatement.getKeyProperties() != null)  
    183.         {  
    184.           for (String keyProperty : mappedStatement.getKeyProperties())  
    185.           {  
    186.             builder.keyProperty(keyProperty);  
    187.           }  
    188.         }  
    189.         if (mappedStatement.getKeyColumns() != null)  
    190.         {  
    191.           for (String keyColumn : mappedStatement.getKeyColumns())  
    192.           {  
    193.             builder.keyColumn(keyColumn);  
    194.           }  
    195.         }  
    196.   
    197.         return builder.build();  
    198.       }  
    199.       
    200.      public static class PageSqlSource implements SqlSource {  
    201.         private BoundSql boundSql;  
    202.   
    203.         public PageSqlSource(BoundSql boundSql) {  
    204.           this.boundSql = boundSql;  
    205.         }  
    206.   
    207.         public BoundSql getBoundSql(Object parameterObject)  
    208.         {  
    209.           return this.boundSql;  
    210.         }  
    211.       }  
    212.   
    213. }  

    (三)spring配置文件和mybatis配置文件

    mybatis配置文件中主要是配置相关的vo类和拦截器

     [html] view plain copy

     

    spring的配置文件中主要就是实现mybatis和spring框架的整合

    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
    4.     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"  
    5.     xmlns:aop="http://www.springframework.org/schema/aop"  
    6.     xsi:schemaLocation="  
    7.         http://www.springframework.org/schema/aop   
    8.         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
    9.         http://www.springframework.org/schema/mvc   
    10.         http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
    11.         http://www.springframework.org/schema/beans   
    12.         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    13.         http://www.springframework.org/schema/tx   
    14.         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
    15.         http://www.springframework.org/schema/context   
    16.         http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
    17.           
    18.         <!-- 读取属性文件 -->  
    19.         <bean class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
    20.             <property name = "location" value = "classpath:db.properties"></property>  
    21.         </bean>  
    22.         <!-- 配置数据源 -->  
    23.         <bean id = "dataSource" class = "org.springframework.jdbc.datasource.DriverManagerDataSource">  
    24.             <property name = "driverClassName" value = "${driverClass}"></property>  
    25.             <property name = "url" value = "${url}"></property>  
    26.             <property name = "username" value = "${username}"></property>  
    27.             <property name = "password" value = "${password}"></property>  
    28.         </bean>  
    29.         <!-- 配置 sqlSessionFactory,实现spring和mybatis框架的整合-->  
    30.         <bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean">  
    31.             <property name = "dataSource" ref = "dataSource"></property>  
    32.             <property name = "configLocation" value = "classpath:mybatis-config.xml"></property>  
    33.             <property name = "mapperLocations" value = "classpath:cn/zyy/paging/xml/*.xml"></property>  
    34.             <property name = "typeAliasesPackage" value = "cn.zyy.paging.vo"></property>  
    35.         </bean>  
    36.         <!-- 配置 MapperScannerConfigurer:将Mapper接口生成代理注入到Spring -->  
    37.         <bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer">  
    38.             <property name = "sqlSessionFactoryBeanName" value = "sqlSessionFactory"></property>  
    39.             <property name = "basePackage" value = "cn.zyy.paging.dao"></property>  
    40.         </bean>  
    41.           
    42.         <!-- 配置事务管理器 -->  
    43.         <bean id = "txManage" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">  
    44.             <property name = "dataSource" ref = "dataSource"></property>  
    45.         </bean>  
    46.           
    47.         <!-- 配置事务传播机制 -->  
    48.         <tx:advice id = "txAdvice" transaction-manager="txManage">  
    49.             <tx:attributes>  
    50.                 <tx:method name="*" propagation="REQUIRED"/>  
    51.             </tx:attributes>  
    52.         </tx:advice>  
    53.         <!-- 利用aop实现动态代理 -->  
    54.         <aop:config>  
    55.             <aop:pointcut expression="execution(* cn.zyy.paging.service.*.*(..))" id="pointcut"/>  
    56.             <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>  
    57.         </aop:config>  
    58.         <!-- 扫描springmvc不能扫描的service类 -->  
    59.         <context:component-scan base-package="cn.zyy.paging.service"></context:component-scan>  
    60. </beans>  
  • 相关阅读:
    thinkphp6查询表达式使用between问题
    机器学习纸质作业1
    磁盘挂载
    SQL Server开启READ_COMMITTED_SNAPSHOT
    视觉开发-相机镜头选型
    使用logstash出现报错com.mysql.jdbc.Driver not loaded. Are you sure you've included the correct jdbc driver in :jdbc_driver_library
    linux安装tomcat(转自https://blog.csdn.net/fukai8350/article/details/80467224)
    linux 安装java(转自https://www.cnblogs.com/wjup/p/11041274.html)
    如何统计自动化测试用例的ROI 【投入产出比/投资回报率】
    老男孩老师的博客地址
  • 原文地址:https://www.cnblogs.com/cmfwm/p/8026589.html
Copyright © 2011-2022 走看看