实现IBatisNet的Dialect分页
Hibernate有其独有的Dialect,对不同的数据库实现sql的分页。
用过MyBatis for Java,它可以拦截SQL语句,通过Interceptor对原始的sql语句进行修改,也就是可以实现自定义Dialect,实现与Hibernate相同效果的分页Dialect。
可是最近搞了个IBatisNet+Spring.Net的框架,IBatisNet是ibatis for Java版本转移过来的。
它没有MyBatis新版本所增加的功能,而IBatisNet自带的分页是通过IDataReader实现的逻辑分页,虽说在局域网环境上,对内存和带宽的影响不是很大,但个人习惯上还是看着很恶心。
上网找了很多天的资料,并没有发现有相当的资料,也似乎没有人这样做过(或许是做了没有共享出来)。
但无意中发现有代码是可以获取到运行时的sql语句的,于是把IBatisNet源码中的实现重新搬出来,修改了一下,算是也能实现Dialect的效果。
主要代码如下:
public static IList QueryPageList(ISqlMapper sqlMap, String statementName, Object parameter, int offset, int limit)
{
IMappedStatement statement = sqlMap.GetMappedStatement(statementName);
if(!sqlMap.IsSessionStarted)
{
sqlMap.OpenConnection();
}
RequestScope request = statement.Statement.Sql.GetRequestScope(statement, parameter, sqlMap.LocalSession);
request.PreparedStatement.PreparedSql = dialect.GetLimitString(request.PreparedStatement.PreparedSql, offset, limit);
statement.PreparedCommand.Create(request, sqlMap.LocalSession, statement.Statement, parameter);
return RunQueryForList(request, sqlMap.LocalSession, parameter, statement.Statement);
} public static IList<T> QueryPageList<T>(ISqlMapper sqlMap, String statementName, Object parameter, int offset, int limit)
{
IMappedStatement statement = sqlMap.GetMappedStatement(statementName);
if(!sqlMap.IsSessionStarted)
{
sqlMap.OpenConnection();
}
RequestScope request = statement.Statement.Sql.GetRequestScope(statement, new Hashtable(), sqlMap.LocalSession);
request.PreparedStatement.PreparedSql = dialect.GetLimitString(request.PreparedStatement.PreparedSql, offset, limit);
statement.PreparedCommand.Create(request, sqlMap.LocalSession, statement.Statement, parameter);
return (List<T>)RunQueryForList<T>(request, sqlMap.LocalSession, parameter, statement.Statement);
} private static IList RunQueryForList(RequestScope request, ISqlMapSession session, object parameterObject, IStatement _statement)
{
IList list = null;
using(IDbCommand command = request.IDbCommand)
{
list = (_statement.ListClass == null)? (new ArrayList()):(_statement.CreateInstanceOfListClass());
IDataReader reader = command.ExecuteReader();
try
{
while(reader.Read())
{
object obj = ResultStrategyFactory.Get(_statement).Process(request, ref reader, null);
if(obj != BaseStrategy.SKIP)
{
list.Add(obj);
}
}
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
RetrieveOutputParameters(request, session, command, parameterObject);
}
return list;
} private static IList<T> RunQueryForList<T>(RequestScope request, ISqlMapSession session, object parameterObject, IStatement _statement)
{
IList<T> list = new List<T>();
using(IDbCommand command = request.IDbCommand)
{
list = (_statement.ListClass == null) ? (new List<T>()) : (_statement.CreateInstanceOfGenericListClass<T>());
IDataReader reader = command.ExecuteReader();
try
{
while(reader.Read())
{
object obj = ResultStrategyFactory.Get(_statement).Process(request, ref reader, null);
if(obj != BaseStrategy.SKIP)
{
list.Add((T)obj);
}
}
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
RetrieveOutputParameters(request, session, command, parameterObject);
}
return list;
} private static void ExecutePostSelect(RequestScope request)
{
while(request.QueueSelect.Count > )
{
PostBindind postSelect = request.QueueSelect.Dequeue() as PostBindind;
PostSelectStrategyFactory.Get(postSelect.Method).Execute(postSelect, request);
}
} private static void RetrieveOutputParameters(RequestScope request, ISqlMapSession session, IDbCommand command, object result)
{
if(request.ParameterMap != null)
{
int count = request.ParameterMap.PropertiesList.Count;
for(int i = ; i < count; i++)
{
IBatisNet.DataMapper.Configuration.ParameterMapping.ParameterProperty mapping = request.ParameterMap.GetProperty(i);
if(mapping.Direction == ParameterDirection.Output ||
mapping.Direction == ParameterDirection.InputOutput)
{
string parameterName = string.Empty;
if(session.DataSource.DbProvider.UseParameterPrefixInParameter == false)
{
parameterName = mapping.ColumnName;
}
else
{
parameterName = session.DataSource.DbProvider.ParameterPrefix +
mapping.ColumnName;
} if(mapping.TypeHandler == null) // Find the TypeHandler
{
lock(mapping)
{
if(mapping.TypeHandler == null)
{
Type propertyType = ObjectProbe.GetMemberTypeForGetter(result, mapping.PropertyName); mapping.TypeHandler = request.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(propertyType);
}
}
} // Fix IBATISNET-239
//"Normalize" System.DBNull parameters
IDataParameter dataParameter = (IDataParameter)command.Parameters[parameterName];
object dbValue = dataParameter.Value; object value = null; bool wasNull = (dbValue == DBNull.Value);
if(wasNull)
{
if(mapping.HasNullValue)
{
value = mapping.TypeHandler.ValueOf(mapping.GetAccessor.MemberType, mapping.NullValue);
}
else
{
value = mapping.TypeHandler.NullValue;
}
}
else
{
value = mapping.TypeHandler.GetDataBaseValue(dataParameter.Value, result.GetType());
} request.IsRowDataFound = request.IsRowDataFound || (value != null); request.ParameterMap.SetOutputParameter(ref result, mapping, value);
}
}
}
}
其中的dialect.GetLimitString(),你们可以用接口的方式,定义针对不同数据库的分页sql,拼接为分页sql即可。
而ExecutePostSelect和RetrieveOutputParameters方法,则是从按源实现代码来调用的,因为无法调用其原始代码,所以自己重新实现了一部分。
最近有人说,这东西具体怎么用其实看不懂,或者直接获取例子中的svn吧,里面集成的是spring.net+ibatis.net
svn://svn.code.sf.net/p/dswork/code/DsWorkNet
项目中引用的dll位于:svn://svn.code.sf.net/p/dswork/code/LibNet
也有集成了基于.net framework 4.0的MVC4的demo
svn://svn.code.sf.net/p/dswork/code/DsDemo/DemoNet
这个项目的运行还需要同时运行web项目:svn://svn.code.sf.net/p/dswork/code/web
即同时运行两个项目,web和DemoNet,否则样式和js等会找不到路径,在IIS Express中配置一下即可,DemoNet中有说明文件
以上所有的项目,获取到本地路径后,建议全部置于同一目录下。否则自己更改dll的引用路径
实现IBatisNet的Dialect分页的更多相关文章
- boot集成mybatis分页插件pagehelper
导入依赖 <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter ...
- Spring Boot 2.x(十三):你不知道的PageHelper
PageHelper 说起PageHelper,使用过Mybatis的朋友可能不是很陌生,作为一款国人开发的分页插件,它基本上满足了我们的日常需求.但是,我想去官方文档看看这个东西配合Spring B ...
- SpringBoot项目集成PageHelper使用
SpringBoot项目集成PageHelper使用 一.开始 地址:https://github.com/pagehelper/Mybatis-PageHelper 在spring boot ...
- Hibernate全套增删改查+分页
1.创建一个web工程 2.导入jar包 3.创建Student表 4.创建实体类 package com.entity; public class Student { private Integer ...
- struts2+spring+hibernate 实现分页
在这里要感谢下这位博友发表的博文 http://www.blogjava.net/rongxh7/archive/2008/11/29/243456.html 通过对他代码的阅读,从而自己实现了网页分 ...
- mybatis实战教程(mybatis in action)之七:实现mybatis分页
上一篇文章里已经讲到了mybatis与spring MVC的集成,并且做了一个列表展示,显示出所有article 列表,但没有用到分页,在实际的项目中,分页是肯定需要的.而且是物理分页,不是内存分页. ...
- 【SSM 5】Mybatis分页插件的使用
一.添加maven依赖项 <span style="font-family:KaiTi_GB2312;font-size:18px;"><dependency&g ...
- Mybatis + SpringMVC + Maven实现分页查询
使用Mybatis + Maven + SpringMVC 运行时,突然被需要分页查询的功能给难住了 这里推荐采用的插件是PageHelper这个插件,使用起来十分方便.该插件支持以下数据库: Ora ...
- mybatis的分页插件使用方法
1.下载所需要的jar包,如果使用maven可以在maven中添加依赖: 插件的实现原理: 如果你想使用本项目的jar包而不是直接引入类,你可以在这里下载各个版本的jar包(点击Download下的j ...
随机推荐
- WCF use ProtoBuf
ProtoBuf, 比起xml和json, 传输的数据里面没有自描述标签, 而且是基于二进制的, 所以有着超高的传输效率, 据牛人张善友的描述, 可以替代WCF的自带的编码方案, 效率有极大的提升. ...
- 使用jekyll在GitHub Pages上搭建个人博客【转】
网上有不少资源,但大多是“授人以鱼”,文中一步一步的告诉你怎么做,却没有解释为什么,以及他是如何知道的.他们默认着你知道种种专业名词的含义,默认着你掌握着特定技能.你折腾半天,查资料,看教程,一步步下 ...
- ServiceStack.OrmLite中的一些"陷阱"(3)
前文说到如果使用多数据库(不同SQL方言)时要如何开发?其实前文(第二篇)也有“透露”到.就是直接使用库提供的OrmLiteConnection 及OrmLiteConnectionFactory(I ...
- hdoj 2022 海选女主角
Problem Description potato老师虽然很喜欢教书,但是迫于生活压力,不得不想办法在业余时间挣点外快以养家糊口.“做什么比较挣钱呢?筛沙子没力气,看大门又不够帅...”potato ...
- CAD 二次开发----- 块(一)
1.块定义与块参照两个概念 块定义类似于模具,而块参照类似于模具浇筑出来的模型,在图形中只需用块定义来保存块的实际几何组成,而仅用插入点和比例因子来存储块定义,因为块参照的几何形状与快参照完全一样,仅 ...
- UIScrollView
1.PPT介绍什么是UIScrollView 2.新建项目“大图片展示” * 尽量用storyboard,减少代码 * 设置contentSize属性 * 取消autolayout * 说明frame ...
- 五步搞定Android开发环境部署
引言 在windows安装Android的开发环境不简单也说不上算复杂,本文写给第一次想在自己Windows上建立Android开发环境投入 Android浪潮的朋友们,为了确保大家能顺利完成开发 ...
- java读取properties配置文件总结
java读取properties配置文件总结 在日常项目开发和学习中,我们不免会经常用到.propeties配置文件,例如数据库c3p0连接池的配置等.而我们经常读取配置文件的方法有以下两种: (1) ...
- Win7 64位 VS2013环境编译Squirrel 3.0.7
Squirrel是一个类似Lua,但是更面向对象的脚本语言. 国内这个介绍很少,环境配置更是没有任何文章提到,花了点时间搞定了,备忘记录下过程. 首先是下载,写本文时Squirrel最新版本为3.0. ...
- 丙申年把真假美猴王囚禁在容器中跑 ASP.NET Core 1.0
var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...