`
zgax
  • 浏览: 20851 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

重写SQLServer2005Dialect,使Hibernate支持真正分页

阅读更多
最近项目要用到sqlserver数据库的数据,之前基本上没有真正用到sqlserver数据库做实际开发,因此碰到了不少的问题,下面的是我在分页方面遇到的问题,记录下来

  

     org.hibernate.dialect.SQLServerDialect类里面的方法

   

       public String getLimitString(String querySelect, int offset, int limit) {
               if (offset > 0)
                     throw new UnsupportedOperationException("sql server has no offset");

                     return new StringBuffer(querySelect.length() + 8).append(querySelect).insert(getAfterSelectInsertPoint(querySelect), " top " + limit).toString();
 

 }

可以看出,hibernate对其分页是采用的top......  分页的,数据量很大的时候,速度 .性能可想而知,sql2005出现了ROW_NUMBER()函数,大大提高的查询速度.
以下继承该Dialect,重写该方法:

import java.sql.Types;

import org.hibernate.dialect.SQLServerDialect;

/**
 * Author: Wesley Wu / Jo�o Vasconcellos
 * wesley@buysou.com / jnbv@hotmail.com
 * Date: 2006-4-29 / 2008-02-12
 * Time: 14:24:03 / 18:11:00
 */
public class SQLServer2005Dialect extends SQLServerDialect {
	public SQLServer2005Dialect() {
		super();

		registerColumnType(Types.VARCHAR, 1073741823, "NVARCHAR(MAX)");
		registerColumnType(Types.VARCHAR, 2147483647, "VARCHAR(MAX)");
		registerColumnType(Types.VARBINARY, 2147483647, "VARBINARY(MAX)");
	}

	/**
	 * Add a LIMIT clause to the given SQL SELECT
	 *
	 * The LIMIT SQL will look like:
	 *
	 * WITH query AS
	 * (SELECT TOP 100 percent ROW_NUMBER() OVER (ORDER BY orderby) as __hibernate_row_nr__, ... original_query)
	 * SELECT *
	 * FROM query
	 * WHERE __hibernate_row_nr__ > offset
	 * ORDER BY __hibernate_row_nr__
	 *
	 * @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 last           Maximum number of rows to be returned by the query
	 * @return A new SQL statement with the LIMIT clause applied.
	 */
	@Override
	public String getLimitString(String querySqlString, int offset, int last) {
		/*
				 * WITH query AS
				 *     (SELECT TOP 100 percent ROW_NUMBER() OVER (ORDER BY orderby) as __hibernate_row_nr__, ... original_query)
				 * SELECT *
				 * FROM query
				 * WHERE __hibernate_row_nr__ > offset
				 * ORDER BY __hibernate_row_nr__
				 */
		StringBuffer pagingBuilder = new StringBuffer();
		String orderby = getOrderByPart(querySqlString);
		String distinctStr = "";

		String loweredString = querySqlString.toLowerCase();
		String sqlPartString = querySqlString;
		if (loweredString.trim().startsWith("select")) {
			int index = 6;
			if (loweredString.startsWith("select distinct")) {
				distinctStr = "DISTINCT ";
				index = 15;
			}
			sqlPartString = sqlPartString.substring(index);
		}
		pagingBuilder.append(sqlPartString);

		// if no ORDER BY is specified use fake ORDER BY field to avoid errors
		if (orderby == null || orderby.length() == 0) {
			orderby = "ORDER BY CURRENT_TIMESTAMP";
		}

		StringBuffer result = new StringBuffer();
		result.append("WITH query AS (SELECT ")
				.append(distinctStr)
				.append("TOP 100 PERCENT ")
				.append(" ROW_NUMBER() OVER (")
				.append(orderby)
				.append(") as __hibernate_row_nr__, ")
				.append(pagingBuilder)
				.append(") SELECT * FROM query WHERE __hibernate_row_nr__ > ")
				.append(offset)
				.append(" ORDER BY __hibernate_row_nr__");

		return result.toString();
	}

	@Override
	public boolean supportsLimit() {
		return true;
	}

	@Override
	public boolean supportsLimitOffset() {
		return true;
	}

	@Override
	public boolean useMaxForLimit() {
		return false;
	}

	static String getOrderByPart(String sql) {
		String loweredString = sql.toLowerCase();
		int orderByIndex = loweredString.indexOf("order by");
		if (orderByIndex != -1) {
			// if we find a new "order by" then we need to ignore
			// the previous one since it was probably used for a subquery
			return sql.substring(orderByIndex);
		} else {
			return "";
		}
	}
}


以上内容均来自互连网,今天测试可用.具体内容未解,欢迎一起探讨.
分享到:
评论

相关推荐

    hibernate SQLServer2008Dialect

    SQLServer2008Dialect 优化了原来的分页查询数据方法以及在生成SQL时表后增加了with(nolock)

    SQLServer2008Dialect

    SQLServer2008Dialect 优化了原来的分页查询数据方法以及在生成SQL时表后增加了with(nolock)

    使用hibernate对sqlserver 2005进行增删改查

    在这个场景中,我们将探讨如何使用Hibernate与SQL Server 2005数据库进行基本的CRUD(Create、Read、Update、Delete)操作。 首先,我们需要确保引入了Hibernate的依赖库。从描述中的“Hibernate 所需要的 jar 包”...

    hibernate 连接sqlserver2000

    标题 "Hibernate 连接 SQL Server 2000" 涉及到的是在Java开发中使用Hibernate ORM框架与较旧版本的SQL Server数据库(即SQL Server 2000)进行交互的知识点。以下是对这个主题的详细阐述: Hibernate是Java领域中...

    mybatis-sql-dialect

    MyBatis-SQL-Dialect是MyBatis框架的一个扩展,主要目的是为了支持不同数据库系统之间的SQL方言差异。MyBatis是一个流行的Java持久层框架,它允许开发者将SQL语句直接集成到XML或Java代码中,提供了灵活的数据访问层...

    使用Hibernate访问sqlserver数据库

    **使用Hibernate访问SQL Server数据库** Hibernate是一个开源的对象关系映射(ORM)框架,它为Java开发者提供了一种在关系数据库和面向对象编程之间架起桥梁的方式。通过使用Hibernate,我们可以避免编写大量的SQL...

    Spring集成Hibernate写SQLServer

    <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2012Dialect <prop key="hibernate.show_sql">true <value>com/yourpackage/YourEntity.hbm.xml</value> ``` 接下来,我们需要创建...

    sqlserver数据库SSH配置1

    SQLServer 数据库 SSH 配置详解 SQLServer 数据库 SSH 配置是将 SQLServer 数据库与 Secure Shell(SSH)协议集成,以实现加密的数据传输和身份验证。本文将详细介绍 SQLServer 数据库 SSH 配置的实现步骤和相关...

    sqlserver以及mysql hibernate xml映射语句

    - **`hibernate.dialect`**:指定数据库方言,对于SQL Server,该值通常为`org.hibernate.dialect.SQLServerDialect`。 - **`mapping`**:指定Hibernate映射文件的位置,例如`<mapping resource="com/hibernate/User...

    hibernate3连接sql server的例子

    **hibernate3连接sql server的例子** 在Java开发中,Hibernate是一个非常流行的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以用Java对象来操作数据库,而无需直接编写SQL语句。本例将详细介绍如何...

    Hibernate+c3p0连接池SQLServer 2000

    ### Hibernate + c3p0 连接池与 SQL Server 2000 的配置与问题解决 #### 一、背景介绍 在Java开发环境中,Hibernate作为一款流行的ORM框架,能够提供一套强大的对象-关系映射机制,使得开发者可以更加便捷地进行...

    hibernate3.6.0dialect.jar

    hibernate3.6.0dialect.jar

    Hibernate中的query 分页.doc

    Hibernate会根据设定的数据库方言(dialect)自动将这些调用转换为对应的SQL语句。例如,对于MySQL,它会生成`LIMIT`子句;而对于Oracle和SQL Server,可能会生成`TOP`子句。数据库层面的分页通常更快且更节省内存,...

    Hibernate4.0以上 SQLiteDialect.java

    hibernate 4以上Hibernate.INTEGER之类的不能使用了,之前使用的SQLiteDialect.java编译不过去了,这个可以。

    JBuilder+SQL Server开发hibernate

    在本文中,我们将探讨如何使用JBuilder结合SQL Server来开发Hibernate应用。首先,确保你的开发环境已经准备就绪,包括JBuilderX作为集成开发环境,以及MS SQL Server 2000作为数据库,同时使用JSQL Driver作为JDBC ...

    hibernate中所有数据库方言

    - **SQL Server2005 Dialect**:针对SQL Server 2005版本的优化。 - **SQL Server2008 Dialect**:包含对SQL Server 2008特性的支持。 #### SAP DB - **SAPDB Dialect**:为SAP DB数据库提供方言支持。 #### ...

    Hibernate分页查询原理解读

    对于支持LIMIT关键字的数据库(例如MySQL),Hibernate会通过特定的方言(Dialect)来生成包含LIMIT关键字的SQL语句。具体实现如下: ```java Query q = session.createQuery("from Cataname"); q.setFirstResult...

    Hibernate不同数据库的连接及SQL方言

    在上面的配置中,我们使用了org.hibernate.dialect.SQLServerDialect SQL方言来生成适合SQL Server数据库的SQL语句。 下面是Hibernate支持的不同数据库的SQL方言: * DB2:org.hibernate.dialect.DB2Dialect * DB2...

    完整Struts2 HIBERNATE实现分页

    根据提供的标题、描述以及部分内文,我们可以梳理出关于如何使用Struts2与Hibernate实现分页功能的关键知识点。 ### Struts2与Hibernate简介 - **Struts2**:这是一个基于MVC架构的开源Web框架,它能帮助开发者...

Global site tag (gtag.js) - Google Analytics