0 0

MyBatis怎样实现MySQL动态分页?0

想用MyBatis根据参数运算实现分页:

第一种:Select * from user limit #{p1},#{p2}-1

用这种方式是不行的,因为在MySQL中limit后面是不允许接表达式的;

 

在网上查了下MySQL还有一种动态分页,用MyBatis试了下报语法错误,直接在MySQL中运行是可以的,如下:

<select id="findUsers" resultType="sun.bean.dome.entity.User" statementType="PREPARED">
  PREPARE PAGE FROM 'SELECT * FROM USER LIMIT ?,?';
  SET @START=1;
  SET @SIZE=3+1;
  EXECUTE PAGE USING @START,@SIZE;
 </select>

 

其实只想Limit后面的分页参数,是根据传递过来的参数动态运算出来的,求助~!

(数据库迁移Oracle到MySQL,所需分页参数不同)

 

2013年5月14日 21:16

15个答案 按时间排序 按投票排序

0 0

Select * from user limit ${p1 -1}, ${p2}

2014年6月14日 14:01
0 0

给你推荐个地址:http://zhenghuazhi.iteye.com/blog/1124361看了之后,应该就能明白了

2013年8月30日 08:47
0 0

在后台计算好后,再传到SQL中。

2013年8月26日 11:25
0 0



Oracle分页:

select b.* from

(select a.* ,rownum rnum from (select * from bi_indexmlk) a where rownum<=5)

b where rnum>=3


sql server分页:

--显示第3个至第5个入学的学生信息
select top 3 * from student where sname not in
(select top 2 sname from student order by entertime )
order by entertime


MySQL分页:

Select * from 表名 limit startrow,pagesize

(Pagesize为每页显示的记录条数)

2013年8月09日 21:09
0 0

Mybatis可以直接把参数p1,p2传过来
Select * from user limit #{p1},#{p2}

2013年8月08日 10:30
0 0

你可以参考下我的这篇博客http://leeyee.github.io/blog/2013/05/26/mybatis-simple-pagination/

使用拦截器实现的简单分页,是基于oracle的,你可以将拼凑分页的语句替换成mysql的分页语句。


以上只是一种处理mybatis分页的思路,你可以参考下。

2013年8月05日 20:29
0 0

先计算然后再传入不就行了!

2013年8月02日 12:43
0 0

本人很不喜欢把sql写的很复杂,更不喜欢把业务逻辑写到sql中去,所以能在程序代码解决的就别往sql里塞。当分表分库的时候sql级别基本解决不了什么问题的。所以建议算好再传进去。

2013年7月20日 23:23
0 0

	/**
	 * 模糊查询(分页)
	 * 
	 * @project apqp
	 * @author liud JIRA:APQP-23
	 * @date 2013-04-16
	 * @param flow
	 * @param page
	 *            分页参数包装器
	 * @return pageData<Flow> 分页结果集
	 * @history
	 */
	@Override
	public PageData<Attach> queryFlow(Attach attach, Pagination page) {
		if (page.isReadTotal())
			page.setTotal(this.selectOneByTotalCount("flow.queryList", attach));
		RowBounds rowbounds = new RowBounds(page.getStart(), page.getLimit());
		List<Attach> result = this.sqlSession.selectList("flow.queryList",
				attach, rowbounds);

		PageData<Attach> pageData = new PageData<Attach>();
		pageData.setResult(result);
		pageData.setPagination(page);
		return pageData;
	}


	/**
	 * 获得分页的总条数
	 * 
	 * @author liud
	 * @date 2013-2-18
	 * @param s
	 *            mybatis对应的命名空间
	 * @param obj
	 *            参数
	 * @return
	 */
	protected int selectOneByTotalCount(String s, Object obj) {
		final BaseEntity baseEntity = new BaseEntity();
		RowBounds rowbounds = new RowBounds(-1, -1);
		this.sqlSession.select(s, obj, rowbounds, new ResultHandler() {
			@Override
			public void handleResult(ResultContext context) {
				Object object = context.getResultObject();
				if (object != null) {
					BaseEntity base = (BaseEntity) object;
					baseEntity.setTotal(base.getTotal());
				}
			}
		});
		return baseEntity.getTotal();
	}


-- mybatis.xml flow.queryList
	<select id="queryList" resultType="com.eman.flow.entity.Attach"
		parameterType="com.eman.flow.entity.Attach">
		SELECT f1.fileID
		, f1.fileName
		, f1.fileType
		, f1.fileSize
		, f1.uploadUser
		, f1.uploadTime
		, f2.userName uploadUserName
		FROM
		t_attachmentOfAPQPFlowPhase p INNER
		JOIN t_attachment f1
		ON p.fileID =
		f1.fileID
		INNER JOIN t_user f2 ON f1.uploadUser =
		f2.userID
		WHERE
		p.phaseID = #{phaseID}
		order by f1.uploadTime desc
	</select>


-- mybatis.config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD  Config 3.0//EN"               
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

	<properties resource="sysconfig.properties" />
	
	<plugins>
		<plugin interceptor="com.eman.core.interceptor.PaginationInterceptor" />
	</plugins>
</configuration>


package com.eman.core.interceptor;

import java.sql.Connection;
import java.util.Properties;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.eman.core.dialect.Dialect;
import com.eman.core.dialect.SQLServer2005Dialect;
import com.eman.core.dialect.SQLServer2008Dialect;

/**
 * 拦截mybatis执行sql,以用于转换分页sql
 * 
 * @author liud
 * 
 */
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PaginationInterceptor implements Interceptor {
	private static final Logger log = LoggerFactory.getLogger("controller");

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		StatementHandler sh = (StatementHandler) invocation.getTarget();
		MetaObject mo = MetaObject.forObject(sh);
		RowBounds rb = (RowBounds) mo.getValue("delegate.rowBounds");
		if (rb == RowBounds.DEFAULT
				|| (rb.getLimit() <= 0 && rb.getLimit() != -1)
				|| rb.getLimit() > RowBounds.NO_ROW_LIMIT)
			return invocation.proceed();

		Configuration conf = (Configuration) mo
				.getValue("delegate.configuration");
		Dialect dialect = this.invokeDialect(conf.getVariables()
				.getProperty("jdbc.db.type").toUpperCase());
		if (dialect == null)
			return invocation.proceed();

		String bSql = (String) mo.getValue("delegate.boundSql.sql");
		if (rb.getLimit() == -1 && rb.getOffset() == -1)
			bSql = dialect.getTotalString(bSql);
		else
			bSql = dialect.getLimitString(bSql, rb.getOffset(), rb.getLimit());
		mo.setValue("delegate.boundSql.sql", bSql);
		mo.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
		mo.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
		return invocation.proceed();
	}

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

	@Override
	public void setProperties(Properties properties) {
	}

	/**
	 * 通过配置获得sql数据库对象
	 * 
	 * @author liud
	 * @date 2013-2-18
	 * @param param
	 * @return
	 */
	private Dialect invokeDialect(String param) {
		Dialect.Type type = null;
		try {
			type = Dialect.Type.valueOf(param);
		} catch (Exception e) {
			log.debug(
					"the value of the dialect property in mybatis-config.xml is not defined:{}",
					param);
		}

		Dialect dialect = null;
		switch (type) {
		case SQLSERVER:
			break;
		case SQLSERVER2005:
			dialect = new SQLServer2005Dialect();
			break;
		case SQLSERVER2008:
			dialect = new SQLServer2008Dialect();
			break;
		case ORACLE9I:
			break;
		case ORACLE10G:
			break;
		case ORACLE11G:
			break;
		case MYSQL5:
			break;
		}
		return dialect;
	}
}



package com.eman.core.dialect;

/**
 * sql2008数据库的实现
 * 
 * @author liud
 * 
 */
public class SQLServer2008Dialect implements Dialect {
	private static final String SELECT = "select";
	private static final String FROM = "from";
	private static final String DISTINCT = "distinct";

	@Override
	public String getTotalString(String sql) {
		StringBuilder sb = new StringBuilder(sql.trim().toLowerCase());
		int orderbyIndex = sb.indexOf("order by");
		if (orderbyIndex != -1) {
			sb.delete(orderbyIndex, sb.length());
		}
		sb.insert(0, "WITH query AS (").append(
				") SELECT count(*) total FROM query ");
		return sb.toString();
	}

	@Override
	public String getLimitString(String sql, int offset, int limit) {
		if (offset > 1 || limit > 1)
			return getLimitString(sql, offset, limit, true);
		return sql;
	}

	/**
	 * Add a LIMIT clause to the given SQL SELECT (HHH-2655: ROW_NUMBER for
	 * Paging)
	 * 
	 * The LIMIT SQL will look like:
	 * 
	 * <pre>
	 * WITH query AS (
	 *   SELECT ROW_NUMBER() OVER (ORDER BY orderby) as __liud_row_nr__, 
	 *   original_query_without_orderby
	 * )
	 * SELECT * FROM query WHERE __liud_row_nr__ BEETWIN offset AND offset + last
	 * </pre>
	 * 
	 * 
	 * @param querySqlString
	 *            The SQL statement to base the limit query off of.
	 * @param offset
	 *            Offset of the first row to be returned by the query
	 *            (zero-based)
	 * @param limit
	 *            Maximum number of rows to be returned by the query
	 * 
	 * @return A new SQL statement with the LIMIT clause applied.
	 */
	private String getLimitString(String querySqlString, int offset, int limit,
			boolean hasOffset) {
		StringBuilder sb = new StringBuilder(querySqlString.trim()
				.toLowerCase());

		int orderByIndex = sb.indexOf("order by");
		CharSequence orderby = orderByIndex > 0 ? sb.subSequence(orderByIndex,
				sb.length()) : "ORDER BY CURRENT_TIMESTAMP";

		// Delete the order by clause at the end of the query
		if (orderByIndex > 0) {
			sb.delete(orderByIndex, orderByIndex + orderby.length());
		}

		// HHH-5715 bug fix
		replaceDistinctWithGroupBy(sb);

		insertRowNumberFunction(sb, orderby);

		// Wrap the query within a with statement:
		sb.insert(0, "WITH query AS (").append(") SELECT * FROM query ");
		sb.append("WHERE __liud_row_nr__ BETWEEN ").append(offset + 1)
				.append(" AND ").append(offset + limit);
		return sb.toString();
	}

	/**
	 * Right after the select statement of a given query we must place the
	 * row_number function
	 * 
	 * @param sql
	 *            the initial sql query without the order by clause
	 * @param orderby
	 *            the order by clause of the query
	 */
	protected static void insertRowNumberFunction(StringBuilder sql,
			CharSequence orderby) {
		// Find the end of the select statement
		int selectEndIndex = sql.indexOf(SELECT) + SELECT.length();

		// Insert after the select statement the row_number() function:
		sql.insert(selectEndIndex, " ROW_NUMBER() OVER (" + orderby
				+ ") as __liud_row_nr__,");
	}

	/**
	 * Utility method that checks if the given sql query is a select distinct
	 * one and if so replaces the distinct select with an equivalent simple
	 * select with a group by clause. See
	 * {@link SQLServer2005DialectTestCase#testReplaceDistinctWithGroupBy()}
	 * 
	 * @param sql
	 *            an sql query
	 */
	protected static void replaceDistinctWithGroupBy(StringBuilder sql) {
		int distinctIndex = sql.indexOf(DISTINCT);
		if (distinctIndex > 0) {
			sql.delete(distinctIndex, distinctIndex + DISTINCT.length() + 1);
			sql.append(" group by").append(getSelectFieldsWithoutAliases(sql));
		}
	}

	/**
	 * This utility method searches the given sql query for the fields of the
	 * select statement and returns them without the aliases. See
	 * {@link SQLServer2005DialectTestCase#testGetSelectFieldsWithoutAliases()}
	 * 
	 * @param an
	 *            sql query
	 * @return the fields of the select statement without their alias
	 */
	protected static CharSequence getSelectFieldsWithoutAliases(
			StringBuilder sql) {
		String select = sql.substring(sql.indexOf(SELECT) + SELECT.length(),
				sql.indexOf(FROM));

		// Strip the as clauses
		return stripAliases(select);
	}

	/**
	 * Utility method that strips the aliases. See
	 * {@link SQLServer2005DialectTestCase#testStripAliases()}
	 * 
	 * @param a
	 *            string to replace the as statements
	 * @return a string without the as statements
	 */
	protected static String stripAliases(String str) {
		return str.replaceAll("\\sas[^,]+(,?)", "$1");
	}
}




以上是集成了mybatis的分页功能,只需要调用第一方法即可以实现。实现方式采用了hibernate分页方式。

2013年6月09日 14:57
0 0

把#改成$, mybatis会把#{}的变量变成PreparedStatement的参数, 而${}是字符串替换

Select * from user limit ${p1},${p2}-1

2013年5月22日 12:48
0 0

不让使用表达式,就将#{p2}-1这样的值计算出来之后,再传入就可以了

2013年5月15日 14:21
0 0

你可以修改下源码,或者 添加 plugin

2013年5月15日 13:51
0 0

mybatis可以直接把参数传递到xml里面去的,跟你对其他字段条件赋值是一样的

2013年5月15日 09:55
0 0

Mybatis可以直接把参数p1,p2传过来
Select * from user limit #{p1},#{p2}
想的那么麻烦干嘛

2013年5月15日 09:24
0 0

可以把select语句写到存储过程里,然后把p1,p2-1作为存储过程的参数。
或者你可以先把p2-1先算出来,再传给limit后面

2013年5月14日 21:57

相关推荐

    mybatis mysql分页实例(不能用找我)

    本实例将详细介绍如何在MyBatis中实现MySQL的分页查询,帮助开发者提高应用性能,提升用户浏览数据的体验。 首先,我们要理解分页的基本概念。分页是将大量数据分成多个小部分,每次只加载一部分到内存中,这样可以...

    spring+spring mvc+mybatis+mysql实现的分页源码

    但是,在参考写的同时也发现有很多地方都不解不能直接用的问题,导致实际使用的过程中经常会出错,参考原来做的项目,以及网上的资料,整理了一个比较简单的自己理解的spring+spring mvc+mybatis+mysql实现的分页的...

    基于mysql的数据库mybatis 分页插件

    mybatis 分页 mybatis-generate Mysql数据库 大家知道mybatis自动生成代码是没有分页功能的 我在网上找了很久 有很多内容 但正真可以使用的少之又少 本人整合了网上的资源 整理了基于Mysql数据库的mybatis插件 经...

    SpringBoot整合mybatis-plus实现多数据源的动态切换且支持分页查询.pdf

    在SpringBoot项目中,整合Mybatis-Plus并实现多数据源的动态切换,同时支持分页查询是一项常见的需求。以下将详细阐述这个过程中的关键步骤和技术要点。 首先,我们需要引入必要的Maven依赖。这里提到了四个关键...

    ajax+jso+mybatis+mysql模仿百度简单分页案例

    在本案例中,我们主要探讨如何使用Ajax、JSON、MyBatis和MySQL来实现一个类似于百度的简单分页功能。这个教程特别适合那些希望提升自己技能的程序员,通过阅读源代码和注释,你可以深入理解这些技术的结合使用。下面...

    mybatis分页插件代码

    MyBatis的分页插件主要有PageHelper和MyBatis-Plus两种常见的实现方式。 1. **PageHelper插件**:PageHelper是基于MyBatis的分页插件,它可以自动进行结果集的分页处理。其核心功能包括: - **智能分页**:根据...

    mybatis支持MYSQL分页

    mybatis支持MYSQL分页 暂只支持MYSQL且不适用与MYBATIS-SPRING一起使用 调用方法 List selectList(String statement, int start ,int end) 与 List selectList(String statement, Object parameter, int start ,int ...

    Spring MVC+MyBatis+MySQL实现分页功能实例

    总的来说,实现Spring MVC、MyBatis和MySQL的分页功能,主要涉及后端分页逻辑的实现和前端的交互。理解分页的基本原理和组件之间的协作,能够帮助开发者高效地构建出符合需求的分页功能。在实际开发中,还可以结合...

    基于SpringMVC Mybatis框架实现分页

    在本项目中,我们主要探讨如何在SpringMVC和Mybatis框架中实现分页功能,同时结合RESTful API设计原则来构建一个高效、易用的Web应用。分页是大型Web应用不可或缺的一部分,它能够有效地管理和展示大量数据,提高...

    MyBatis分页

    MyBatis的分页机制主要依赖于SQL语句的构造,通过在动态SQL中添加LIMIT和OFFSET关键字来实现。例如,在MySQL数据库中,分页查询的基本形式为: ```sql SELECT * FROM table LIMIT offset, limit; ``` 这里的`...

    基于Springboot+MyBatis+MySQL实现多功能个人博客系统+本科毕业设计+课程设计

    基于Springboot+MyBatis+MySQL实现多功能个人博客系统 项目经过严格测试,确保可以运行! 功能点: 用户注册登录功能 Markdown文章发布功能 文章分页显示 文章分类 文章标签/标签云 文章点击量 阅读排行 赞...

    Jsp+Servlet+MyBatis完成分页查询

    在本文中,我们将深入探讨如何使用JSP、Servlet和MyBatis这三种技术来实现一个分页查询的功能。这是一个常见的需求,在许多Web应用程序中,为了提高用户体验,通常需要将大量数据分批次展示,而不是一次性加载所有...

    mybatis 分页代码

    总结,MyBatis中的分页实现主要是通过应用层的逻辑和动态SQL来完成。尽管基于内存的分页方法在小型项目中足够用,但对于大型项目,推荐使用数据库原生的分页功能以提高性能。在实际开发中,应根据项目需求和数据规模...

    mybatis,mybatis+mysql

    5. **分页查询**:在MyBatis中实现分页查询,你可以使用`&lt;foreach&gt;`标签配合LIMIT和OFFSET子句,或者使用MyBatis的PageHelper插件,它提供更方便的分页API。 6. **事务管理**:MyBatis的事务管理可以手动或自动进行...

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

    在这个项目中,开发者使用了这些框架以及MySQL数据库来实现分页功能,借助PageHelper插件。下面将详细阐述这个项目中的核心技术和知识点。 1. **Spring框架**:Spring作为基础容器,负责管理应用对象(如Service、...

    利用Spring MVC+Mybatis实现Mysql分页数据查询的过程详解

    在本文中,我们将深入探讨如何使用Spring MVC和MyBatis框架来实现MySQL数据库的分页数据查询。首先,我们需要理解分页在Web开发中的重要性,尤其是在处理大量数据时,它可以提高应用程序的性能并提供更好的用户体验...

    MyBatis 最简单的分页+原理解析

    总结,MyBatis通过动态SQL和参数传递实现了最简单的分页查询,而分页的实现原理主要是通过SQL的`LIMIT`子句。在实际应用中,结合最佳实践和第三方插件,可以进一步提升分页功能的效率和灵活性。同时,针对不同的场景...

    Mybatis分页拦截器

    Mybatis分页拦截器的核心工作原理是:在执行SQL查询时,拦截SQL语句,动态添加分页相关的SQL片段,如LIMIT或OFFSET等,然后执行改写后的SQL,从而实现分页效果。这种方式的好处在于保持了SQL的简洁性和可读性,同时...

    利用Mybatis的动态SQL实现物理分页.pdf

    总结起来,本文介绍了如何利用Mybatis的动态SQL功能实现MySQL的物理分页,这种方法对于处理大数据量的查询非常有效,可以防止内存溢出并提高应用的性能。在实际开发中,理解和掌握这一技巧对于优化数据库操作和提升...

    mybatis自动生成代码分页功能 mysql 数据库

    本篇将聚焦于MyBatis的代码自动生成和分页功能,特别是在MySQL数据库中的应用。 一、MyBatis代码生成器(MyBatis Generator) MyBatis Generator(MBG)是MyBatis官方提供的一个工具,可以自动生成Java模型类、...

Global site tag (gtag.js) - Google Analytics