欲练此功,必先自宫。
欲分页,必先获取记录数。
IBatis简单却又强大,然而用过IBatis的人都之道,在IBatis里想通过查询列表的SQL去获取记录数却不是件容易的事情,我在网上搜了N次没有搜到。
思路:
要想获取记录数(不特意写SQL),必须先获取到所执行的最终的SQL语句,并在外面包一层 select count(*) from (原始sql) 来做;
研究了一下SDK,发现获取最终执行的SQL语句是不可能的,但可以从里面得到 IDbCommand 和 IDb Connection, IDbCommand 的参数都已经准备好,我们只要串改一下CommandText,就豁然开朗了:
希望对大家有用。
欲分页,必先获取记录数。
IBatis简单却又强大,然而用过IBatis的人都之道,在IBatis里想通过查询列表的SQL去获取记录数却不是件容易的事情,我在网上搜了N次没有搜到。
思路:
要想获取记录数(不特意写SQL),必须先获取到所执行的最终的SQL语句,并在外面包一层 select count(*) from (原始sql) 来做;
研究了一下SDK,发现获取最终执行的SQL语句是不可能的,但可以从里面得到 IDbCommand 和 IDb Connection, IDbCommand 的参数都已经准备好,我们只要串改一下CommandText,就豁然开朗了:
public
static
int
QueryForCount(
string
statementName,
object
paramObject)
{
ISqlMapper mapper = Mapper.Instance();
IMappedStatement statement = mapper.GetMappedStatement(statementName);
IDbCommand cmd = null;
try {
if (!mapper.IsSessionStarted) {
mapper.OpenConnection();
}
RequestScope scope = statement.Statement.Sql.GetRequestScope(statement, paramObject, mapper.LocalSession);
statement.PreparedCommand.Create(scope, mapper.LocalSession, statement.Statement, paramObject);
cmd = scope.IDbCommand;
cmd.Connection = scope.Session.Connection;
cmd.CommandText = string.Format("select count(*) c from ({0}) t ", cmd.CommandText);
using (IDataReader dr = cmd.ExecuteReader()) {
dr.Read();
return dr.GetInt32(0);
}
} finally {
if( cmd != null && cmd.Connection != null && cmd.Connection.State != ConnectionState.Closed)
cmd.Connection.Close();
}
}
ISqlMapper mapper = Mapper.Instance();
IMappedStatement statement = mapper.GetMappedStatement(statementName);
IDbCommand cmd = null;
try {
if (!mapper.IsSessionStarted) {
mapper.OpenConnection();
}
RequestScope scope = statement.Statement.Sql.GetRequestScope(statement, paramObject, mapper.LocalSession);
statement.PreparedCommand.Create(scope, mapper.LocalSession, statement.Statement, paramObject);
cmd = scope.IDbCommand;
cmd.Connection = scope.Session.Connection;
cmd.CommandText = string.Format("select count(*) c from ({0}) t ", cmd.CommandText);
using (IDataReader dr = cmd.ExecuteReader()) {
dr.Read();
return dr.GetInt32(0);
}
} finally {
if( cmd != null && cmd.Connection != null && cmd.Connection.State != ConnectionState.Closed)
cmd.Connection.Close();
}
}
希望对大家有用。
posted on 2008-05-22 23:05 quitgame 阅读(598) 评论(4) 编辑 收藏 网摘 所属分类: ASP.NET/WEB
评论
#2楼 [楼主] 2008-05-23 12:28 quitgame
@无常
今天我又用同样的伎俩实现了高性能分页
IBatis 的QueryForList(....skipNumber...)
用的是 while(i<skipNumber)DataReader.read() 这样低效的方式
我封装的接口里面直接用 SQL Server 的 row_number() over 的方式,效率惊人,百万级数据都是0 S。
今天我又用同样的伎俩实现了高性能分页
IBatis 的QueryForList(....skipNumber...)
用的是 while(i<skipNumber)DataReader.read() 这样低效的方式
我封装的接口里面直接用 SQL Server 的 row_number() over 的方式,效率惊人,百万级数据都是0 S。
#4楼 2008-07-31 00:21 fredlau
我是在ibatis.net里面用存储过程来进行分页