mybatis分页设置方法(mybatis-plus分页方法)
sinye56 2024-09-19 02:21 8 浏览 0 评论
分页拦截器PageInterceptor
import org.apache.ibatis.executor.parameter.ParameterHandler; import org.apache.ibatis.executor.statement.RoutingStatementHandler; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.plugin.*; import org.apache.ibatis.scripting.defaults.DefaultParameterHandler; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.Properties; /** * 分页拦截器,用于拦截需要进行分页查询的操作,然后对其进行分页处理 * */ @Intercepts({ @Signature(method = "prepare", type = StatementHandler.class, args = { Connection.class }) }) public class PageInterceptor implements Interceptor { private String databaseType;// 数据库类型,不同的数据库有不同的分页方法 /** * 拦截后要执行的方法 */ public Object intercept(Invocation invocation) throws Throwable { RoutingStatementHandler handler = (RoutingStatementHandler) invocation .getTarget(); StatementHandler delegate = (StatementHandler) ReflectUtil .getFieldValue(handler, "delegate"); BoundSql boundSql = delegate.getBoundSql(); Object paramObj = boundSql.getParameterObject(); // 判断参数里是否有page对象 Pagination page = null; if (paramObj instanceof Pagination) { page = (Pagination) paramObj; } else if (paramObj instanceof Map) { for (Object arg : ((Map) paramObj).values()) { if (arg instanceof Page<?>) { page = (Pagination) arg; break; } } } if (page != null) { MappedStatement mappedStatement = (MappedStatement) ReflectUtil .getFieldValue(delegate, "mappedStatement"); Connection connection = (Connection) invocation.getArgs()[0]; String sql = boundSql.getSql(); if (page.getTotalCount() < 0) { // 如果总数为负数表需要设置 this.setTotalRecord(paramObj, mappedStatement, connection, page); } // 获取分页Sql语句 String pageSql = this.getPageSql(page, sql); // 利用反射设置当前BoundSql对应的sql属性为我们建立好的分页Sql语句 ReflectUtil.setFieldValue(boundSql, "sql", pageSql); } return invocation.proceed(); } /** * 拦截器对应的封装原始对象的方法 */ public Object plugin(Object target) { return Plugin.wrap(target, this); } /** * 设置注册拦截器时设定的属性 */ public void setProperties(Properties properties) { this.databaseType = properties.getProperty("databaseType"); } /** * 根据page对象获取对应的分页查询Sql语句,这里只做了两种数据库类型,Mysql和Oracle 其它的数据库都 没有进行分页 * * @param page * 分页对象 * @param sql * 原sql语句 * @return */ private String getPageSql(Pagination page, String sql) { StringBuffer sqlBuffer = new StringBuffer(sql); if ("mysql".equalsIgnoreCase(databaseType)) { return getMysqlPageSql(page, sqlBuffer); } else if ("oracle".equalsIgnoreCase(databaseType)) { return getOraclePageSql(page, sqlBuffer); } return sqlBuffer.toString(); } /** * 获取Mysql数据库的分页查询语句 * * @param page * 分页对象 * @param sqlBuffer * 包含原sql语句的StringBuffer对象 * @return Mysql数据库分页语句 */ private String getMysqlPageSql(Pagination page, StringBuffer sqlBuffer) { // 计算第一条记录的位置,Mysql中记录的位置是从0开始的。 int offset = (page.getPageNo() - 1) * page.getPageCount(); sqlBuffer.append(" limit ").append(offset).append(",") .append(page.getPageCount()); return sqlBuffer.toString(); } /** * 获取Oracle数据库的分页查询语句 * * @param page * 分页对象 * @param sqlBuffer * 包含原sql语句的StringBuffer对象 * @return Oracle数据库的分页查询语句 */ private String getOraclePageSql(Pagination page, StringBuffer sqlBuffer) { // 计算第一条记录的位置,Oracle分页是通过rownum进行的,而rownum是从1开始的 int offset = (page.getPageNo() - 1) * page.getPageCount() + 1; sqlBuffer.insert(0, "select u.*, rownum _rownum from (") .append(") u where rownum < ") .append(offset + page.getPageCount()); sqlBuffer.insert(0, "select * from (").append(") where _rownum >= ") .append(offset); // 上面的Sql语句拼接之后大概是这个样子: // select * from (select u.*, rownum r from (select * from t_user) u // where rownum < 31) where r >= 16 return sqlBuffer.toString(); } /** * 给当前的参数对象page设置总记录数 * * @param obj * Mapper映射语句对应的参数对象 * @param mappedStatement * Mapper映射语句 * @param connection * 当前的数据库连接 */ private void setTotalRecord(Object obj, MappedStatement mappedStatement, Connection connection, Pagination page) { BoundSql boundSql = mappedStatement.getBoundSql(obj); String sql = boundSql.getSql(); String countSql = this.getCountSql(sql); List<ParameterMapping> parameterMappings = boundSql .getParameterMappings(); BoundSql countBoundSql = new BoundSql( mappedStatement.getConfiguration(), countSql, parameterMappings, obj); ReflectUtil.setFieldValue(countBoundSql, "additionalParameters", ReflectUtil.getFieldValue(boundSql, "additionalParameters")); ReflectUtil.setFieldValue(countBoundSql, "metaParameters", ReflectUtil.getFieldValue(boundSql, "metaParameters")); ParameterHandler parameterHandler = new DefaultParameterHandler( mappedStatement, obj, countBoundSql); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = connection.prepareStatement(countSql); parameterHandler.setParameters(pstmt); rs = pstmt.executeQuery(); if (rs.next()) { int totalRecord = rs.getInt(1); // 给当前的参数page对象设置总记录数 page.setTotalCount(totalRecord); } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (rs != null) rs.close(); if (pstmt != null) pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } /** * 根据原Sql语句获取对应的查询总记录数的Sql语句 * * @param sql * @return */ private String getCountSql(String sql) { return "select count(1) from (" + sql + ") _tmp"; } /** * 利用反射进行操作的一个工具类 * */ private static class ReflectUtil { /** * 利用反射获取指定对象的指定属性 * * @param obj * 目标对象 * @param fieldName * 目标属性 * @return 目标属性的值 */ public static Object getFieldValue(Object obj, String fieldName) { Object result = null; Field field = ReflectUtil.getField(obj, fieldName); if (field != null) { field.setAccessible(true); try { result = field.get(obj); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return result; } /** * 利用反射获取指定对象里面的指定属性 * * @param obj * 目标对象 * @param fieldName * 目标属性 * @return 目标字段 */ private static Field getField(Object obj, String fieldName) { Field field = null; for (Class<?> clazz = obj.getClass(); clazz != Object.class; clazz = clazz .getSuperclass()) { try { field = clazz.getDeclaredField(fieldName); break; } catch (NoSuchFieldException e) { // 这里不用做处理,子类没有该字段可能对应的父类有,都没有就返回null。 } } return field; } /** * 利用反射设置指定对象的指定属性为指定的值 * * @param obj * 目标对象 * @param fieldName * 目标属性 * @param fieldValue * 目标值 */ public static void setFieldValue(Object obj, String fieldName, String fieldValue) { Field field = ReflectUtil.getField(obj, fieldName); if (field != null) { try { field.setAccessible(true); field.set(obj, fieldValue); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 利用反射设置指定对象的指定属性为指定的值 * * @param obj * 目标对象 * @param fieldName * 目标属性 * @param fieldValue * 目标值 */ public static void setFieldValue(Object obj, String fieldName, Object fieldValue) { Field field = ReflectUtil.getField(obj, fieldName); if (field != null) { try { field.setAccessible(true); field.set(obj, fieldValue); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } public String getDatabaseType() { return databaseType; } public void setDatabaseType(String databaseType) { this.databaseType = databaseType; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
配置分页拦截器
import com.yuntu.commons.mybatispage.*; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; /** */ @Configuration @MapperScan("com.yuntu.core.repository") @EnableTransactionManagement public class MybatisConfig { private static final String MYBATIS_CONFIG_FILE = "mybatis-config.xml"; /** * 注册datasource,通过@ConfigurationProperties(prefix="c3p0")将properties文件中c3p0开头的属性map到datasource相应的属性上 * @return */ @Bean @ConfigurationProperties(prefix="c3p0") public ComboPooledDataSource dataSource() { return new ComboPooledDataSource(); } @Bean(name = "sqlSessionFactory") public SqlSessionFactory sqlSessionFactoryBean() throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource()); sqlSessionFactoryBean.setTypeAliasesPackage("com.friday.core.model"); sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(MYBATIS_CONFIG_FILE)); PageInterceptor pageInterceptor = new PageInterceptor(); pageInterceptor.setDatabaseType("mysql"); sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageInterceptor}); return sqlSessionFactoryBean.getObject(); } @Bean public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
其他支持类:
import java.util.List; /** * 分页基本实现 * @param <T> */ public class Page<T> implements Pagination { /** 页码 */ protected int pageNo; /** 每页记录条数 */ protected int pageCount; /** 总页数 */ protected int totalPage; /** 总记录条数 */ protected int totalCount = -1; /** 用于存放查询结果 */ protected List<T> resultList; public Page() {} public Page(Integer pageNo, int pageCount) { if(pageNo==null){ pageNo=1; } if (pageNo <= 0) { pageNo=1; //throw new IllegalArgumentException("pageNo must be greater than 0."); } if (pageCount<=0 && pageCount>50) { pageCount=50; //throw new IllegalArgumentException("pageCount must be greater than 0."); } this.pageNo = pageNo; this.pageCount = pageCount; } public void setPageNo(int pageNo) { this.pageNo = pageNo; } public void setPageCount(int pageCount) { this.pageCount = pageCount; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getPageNo() { return pageNo; } public int getPageCount() { return pageCount; } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; if (totalCount < 0) { // 如果总数为负数, 表未设置 totalPage = 0; } else { // 计算总页数 totalPage = (totalCount / pageCount) + (totalCount % pageCount == 0 ? 0 : 1); } } public List<T> getResultList() { return resultList; } public void setResultList(List<T> resultList) { this.resultList = resultList; } public int getTotalPage() { return totalPage; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 /** * 分页,在分页挡截中使用 * */ public interface Pagination { /** * @return 当前页码 */ int getPageNo(); /** * @return 每页记录数 */ int getPageCount(); /** * @return 总记录数: 负数表尚未设置, 挡截器会使用count语句统计总数; 0或正整数表总数已设置, 挡截器将不会统计总数. */ int getTotalCount(); /** * @param totalCount 设置记录总数 */ void setTotalCount(int totalCount); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
使用:
在mapper接口中:
List<LibraryBookResult> getLibraryStatics(@Param("libraryBooksDto") LibraryBooksCollectDto libraryBooksDto, Pagination pagination); 1 2
在mapper.xml中不用关心分页情况
相关推荐
- 程序员:JDK的安装与配置(完整版)_jdk的安装方法
-
对于Java程序员来说,jdk是必不陌生的一个词。但怎么安装配置jdk,对新手来说确实头疼的一件事情。我这里以jdk10为例,详细的说明讲解了jdk的安装和配置,如果有不明白的小伙伴可以评论区留言哦下...
- Linux中安装jdk并配置环境变量_linux jdk安装教程及环境变量配置
-
一、通过连接工具登录到Linux(我这里使用的Centos7.6版本)服务器连接工具有很多我就不一一介绍了今天使用比较常用的XShell工具登录成功如下:二、上传jdk安装包到Linux服务器jdk...
- 麒麟系统安装JAVA JDK教程_麒麟系统配置jdk
-
检查检查系统是否自带java在麒麟系统桌面空白处,右键“在终端打开”,打开shell对话框输入:java–version查看是否自带java及版本如图所示,系统自带OpenJDK,要先卸载自带JDK...
- 学习笔记-Linux JDK - 安装&配置
-
前提条件#检查是否存在JDKrpm-qa|grepjava#删除现存JDKyum-yremovejava*安装OracleJDK不分系统#进入安装文件目...
- Linux新手入门系列:Linux下jdk安装配置
-
本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...
- 测试员必备:Linux下安装JDK 1.8你必须知道的那些事
-
1.简介在Oracle收购Sun后,Java的一系列产品就被整合到Oracle官网中,打开官网乍眼一看也不知道去哪里下载,还得一个一个的摸索尝试,而且网上大多数都是一些Oracle收购Sun前,或者就...
- Linux 下安装JDK17_linux 安装jdk1.8 yum
-
一、安装环境操作系统:JDK版本:17二、安装步骤第一步:下载安装包下载Linux环境下的jdk1.8,请去官网(https://www.oracle.com/java/technologies/do...
- 在Ubuntu系统中安装JDK 17并配置环境变量教程
-
在Ubuntu系统上安装JDK17并配置环境变量是Java开发环境搭建的重要步骤。JDK17是Oracle提供的长期支持版本,广泛用于开发Java应用程序。以下是详细的步骤,帮助你在Ubuntu系...
- 如何在 Linux 上安装 Java_linux安装java的步骤
-
在桌面上拥抱Java应用程序,然后在所有桌面上运行它们。--SethKenlon(作者)无论你运行的是哪种操作系统,通常都有几种安装应用程序的方法。有时你可能会在应用程序商店中找到一个应用程序...
- Windows和Linux环境下的JDK安装教程
-
JavaDevelopmentKit(简称JDK),是Java开发的核心工具包,提供了Java应用程序的编译、运行和开发所需的各类工具和类库。它包括了JRE(JavaRuntimeEnviro...
- linux安装jdk_linux安装jdk软连接
-
JDK是啥就不用多介绍了哈,外行的人也不会进来看我的博文。依然记得读大学那会,第一次实验课就是在机房安装jdk,编写HelloWorld程序。时光飞逝啊,一下过了十多年了,挣了不少钱,买了跑车,娶了富...
- linux安装jdk,全局配置,不同用户不同jdk
-
jdk1.8安装包链接:https://pan.baidu.com/s/14qBrh6ZpLK04QS8ogCepwg提取码:09zs上传文件解压tar-zxvfjdk-8u152-linux-...
- 运维大神教你在linux下安装jdk8_linux安装jdk1.7
-
1.到官网下载适合自己机器的版本。楼主下载的是jdk-8u66-linux-i586.tar.gzhttp://www.oracle.com/technetwork/java/javase/downl...
- window和linux安装JDK1.8_linux 安装jdk1.8.tar
-
Windows安装JDK1.8的步骤:步骤1:下载JDK打开浏览器,找到JDK下载页面https://d.injdk.cn/download/oraclejdk/8在页面中找到并点击“下载...
- 最全的linux下安装JavaJDK的教程(图文详解)不会安装你来打我?
-
默认已经有了linux服务器,且有root账号首先检查一下是否已经安装过java的jdk任意位置输入命令:whichjava像我这个已经安装过了,就会提示在哪个位置,你的肯定是找不到。一般我们在...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)