IBatis.Net使用总结(二)-- IBatis返回DataTable/DataSet(网上例子的集合)
IBatis返回DataTable,DataSet
ibatis.net QueryForDataTable
完整的为ibatis.net 引入datatable支持要改动很多地方,所以描述的是最小化的改动.不过我们可以大概了解一下比较完整的集成要做那些事情.
ibatis.net 的基本运行原理就是获得一个reader后,然后进行循环,对每条记录使用ResultStrategy中的对应实现进行处理,然后返回到结果集.因此,首先,需要实现一个DataTableStrategy 用来为每条记录产生一个新DataRow. 大家可以看到,下面的实现已经绕开了ibatis.net的处理逻辑.
你可以在网上google到一些ibatis返回dataset的代码,可在最新的版本1.6 ibatis.net 这些代码都无法工作,这是因为RequestScope.IDbCommand现在返回的是一个DbCommandDecorator对象实例(一个实现IDbCommand接口并代理一个具体的IDbCommand实现的对象),而DataAdapter的实现,需要对应的idbcommand实现,如 SqlDataAdapter需要SqlCommand.因此,如下代码会导致cast错误
Mapper.LocalSession.CreateDataAdapter(scope.IDbCommand).Fill(dataTable);
这里有两种解法,一是使用datatable.Load方法来装载IDbCommand.ExecuteReader的返回结果,这是可行的
其次是利用反射,实际的idbcommand在DbCommandDecorator中被保存为_innerDbCommand field ,下面是两种实现. 大约的感觉,如果你在意性能的话,第一种会快些
/// <summary> /// 查询返回DatatTable /// </summary> /// <param name="statementName"></param> /// <param name="parameterObject"></param> /// <returns></returns> public DataTable QueryForDataTable(string statementName, object parameterObject) { bool isSessionLocal = false; ISqlMapSession session = SqlMap.LocalSession; DataTable dataTable = null; if (session == null) { session = SqlMap.CreateSqlMapSession(); isSessionLocal = true; } try { IMappedStatement statement = SqlMap.GetMappedStatement(statementName); dataTable = new DataTable(statementName); RequestScope request = statement.Statement.Sql.GetRequestScope(statement, parameterObject, session); statement.PreparedCommand.Create(request, session, statement.Statement, parameterObject); using (request.IDbCommand) { dataTable.Load(request.IDbCommand.ExecuteReader()); } } catch { throw; } finally { if (isSessionLocal) { session.CloseConnection(); } } return dataTable; }
查询返回DatatTable
/// <summary> /// iBatisNet 1.6版本 返回DataSet /// </summary> /// <param name="statementName"></param> /// <param name="paramObject"></param> /// <returns></returns> public DataSet QueryForDataSet(string statementName, object paramObject) { DataSet ds = new DataSet(); ISqlMapper mapper = Mapper.Instance(); IMappedStatement statement = mapper.GetMappedStatement(statementName); if (!mapper.IsSessionStarted) { mapper.OpenConnection(); } RequestScope scope = statement.Statement.Sql.GetRequestScope(statement, paramObject, mapper.LocalSession); statement.PreparedCommand.Create(scope, mapper.LocalSession, statement.Statement, paramObject); IDbCommand command = mapper.LocalSession.CreateCommand(CommandType.Text); command.CommandText = scope.IDbCommand.CommandText; foreach (IDataParameter pa in scope.IDbCommand.Parameters) { command.Parameters.Add(new SqlParameter(pa.ParameterName, pa.Value)); } mapper.LocalSession.CreateDataAdapter(command).Fill(ds); return ds; }
iBatisNet 1.6版本 返回DataSet
public DataSet QueryForDataSet2(string statementName, object parameterObject) { bool isSessionLocal = false; ISqlMapSession session = _sessionStore.LocalSession; DataSet ds = new DataSet(statementName); if (session == null) { session = CreateSqlMapSession(); isSessionLocal = true; } try { IMappedStatement statement = GetMappedStatement(statementName); RequestScope request = statement.Statement.Sql.GetRequestScope(statement, parameterObject, session); statement.PreparedCommand.Create(request, session, statement.Statement, parameterObject); FieldInfo info = request.IDbCommand.GetType().GetField("_innerDbCommand", BindingFlags.NonPublic | BindingFlags.Instance); using (IDbCommand cmd = (IDbCommand)info.GetValue(request.IDbCommand)) { session.CreateDataAdapter(cmd).Fill(ds); } } catch { throw; } finally { if (isSessionLocal) { session.CloseConnection(); } } return ds; }
利用反射返回DataSet
以下是1.6.1版本之前返回DataTable的方法。
private IDbCommand GetDbCommand(string statementName, object paramObject) { IStatement statement = sqlMap.GetMappedStatement(statementName).Statement; IMappedStatement mapStatement = sqlMap.GetMappedStatement(statementName); IDalSession session = new SqlMapSession(sqlMap); if (sqlMap.LocalSession != null) { session = sqlMap.LocalSession; } else { session = sqlMap.OpenConnection(); } RequestScope request = statement.Sql.GetRequestScope(mapStatement, paramObject, session); mapStatement.PreparedCommand.Create(request, session, statement, paramObject); return request.IDbCommand; }
获取DbCommand
这种返回DataTable的方式,容易引起Sql注入,因为xml文件中,sql语句需要使用$作为占位符。
/// <summary> /// 通用的以DataTable的方式得到Select的结果(xml文件中参数要使用$标记的占位参数) /// </summary> /// <param name="statementName">语句ID</param> /// <param name="paramObject">语句所需要的参数</param> /// <returns>得到的DataTable</returns> protected DataTable ExecuteQueryForDataTable(string statementName, object paramObject) { DataSet ds = new DataSet(); bool isSessionLocal = false; IDalSession session = sqlMap.LocalSession; if (session == null) { session = new SqlMapSession(sqlMap); session.OpenConnection(); isSessionLocal = true; } IDbCommand cmd = GetDbCommand(statementName, paramObject); try { cmd.Connection = session.Connection; IDbDataAdapter adapter = session.CreateDataAdapter(cmd); adapter.Fill(ds); } finally { if (isSessionLocal) { session.CloseConnection(); } } ]; }
返回DataTable
如果参数中,包含有output参数,则使用下面的方法
/// <summary> /// 通用的以DataTable的方式得到Select的结果(xml文件中参数要使用$标记的占位参数) /// </summary> /// <param name="statementName">语句ID</param> /// <param name="paramObject">语句所需要的参数</param> /// <param name="htOutPutParameter)">Output参数值哈希表</param> /// <returns>得到的DataTable</returns> protected DataTable ExecuteQueryForDataTable(string statementName, object paramObject, out Hashtable htOutPutParameter) { DataSet ds = new DataSet(); bool isSessionLocal = false; IDalSession session = sqlMap.LocalSession; if (session == null) { session = new SqlMapSession(sqlMap); session.OpenConnection(); isSessionLocal = true; } IDbCommand cmd = GetDbCommand(statementName, paramObject); try { cmd.Connection = session.Connection; IDbDataAdapter adapter = session.CreateDataAdapter(cmd); adapter.Fill(ds); } finally { if (isSessionLocal) { session.CloseConnection(); } } foreach (IDataParameter parameter in cmd.Parameters) { if (parameter.Direction == ParameterDirection.Output) { htOutPutParameter[parameter.ParameterName] = parameter.Value; } } ]; }
返回DataTable,包含output参数
参考链接:
原文地址:ibatis 返回DataTable和DataSet作者:happytor
原文地址:[IBatisNet]关于返回DataTable的一点问题 作者:Daniel Pang
IBatis.Net使用总结(二)-- IBatis返回DataTable/DataSet(网上例子的集合)的更多相关文章
- iBatis.Net实现返回DataTable和DataSet对象
如题.要返回一个ADO.NET对象好像没有使用ORM的必要,而且从编程的角度看这样的实现一点也不OO,但是实际的开发场景中还是会碰到这种需求的.下面我就借鉴前人的经验,结合实际的示例,再总结一下.如果 ...
- 二、Ajax请求MVC中数据查询表返回datatable
一.Ajax请求MVC中数据查询表返回datatable 解决方式 返回list
- WebService返回DataTable
http://blog.csdn.net/wxnjob/article/details/8638420 webservice返回datatable时报序列化错误 以下三种方案的实质应该都是序列化的,有 ...
- LINQ查询返回DataTable类型
个人感觉Linq实用灵活性很大,参考一篇大牛的文章LINQ查询返回DataTable类型 http://xuzhihong1987.blog.163.com/blog/static/267315872 ...
- Entity Framework执行Sql语句返回DataTable
Entity Framework中对外开放了数据库连接字符串,使用的时候可以直接得到这个连接字符串,然后进行相关的操作.如果在使用的过程中,发现Entity Framework中有一些满足不了的需求的 ...
- 在DataTable中执行DataTable.Select("条件")返回DataTable;
转:http://blog.csdn.net/hcf_force/article/details/7779062 1.在DataTable中执行DataTable.Select("条件&qu ...
- 转:LINQ查询返回DataTable类型
动态绑定ReportViewer虽然之前实现过,但现在弄起来还是有点晕,主要是过去没有使用Linq,数据的操作经常用到DataTable,可以直接拿来使用,现在用Linq更方便,也懒得再用之前的数据库 ...
- C#读取txt文件返回DATATABLE
//1.打开资源管理器 OpenFileDialog open = new OpenFileDialog(); if (open.ShowDialog() == DialogResult.OK) { ...
- WebService返回DataTable问题
今天做项目时,想在WebService中返回DataTable,在单位没成功,看网上有人说datable在.net1.1中是没有序列化的,不能直接在webservice中返回,可以返回dataset. ...
随机推荐
- Html页面禁止鼠标左键复制
<body leftmargin=0 topmargin=0 oncontextmenu='return false' ondragstart='return false' onselectst ...
- Java,来源于大神
也许你学习了那么久的Java了,但如果有人问你什么是JavaEE?你会怎么回答他呢?在此我来谈谈关于JavaEE的相关技术.(仅是个人见解) 在谈JavaEE时,我们首先来了解一下Java平台.目前, ...
- .NET 微信Token验证和消息接收和回复
public class wxXmlModel { public string ToUserName { get; set; } public string FromUserName { get; s ...
- Html定位精要
Html定位基础 Html的布局是文档流模型,块元素独占一行,内联元素并列一行. 相对定位 position: relative 相对于自己定位 不脱离文档流,元素原有位置被保留 绝对定位 posit ...
- 做参数可以读取参数 保存参数 用xml文件的方式
做参数可以读取参数 保存参数 用xml文件的方式 好处:供不同用户保存适合自己使用的参数
- 动手实验iptables的NAT功能实现流量穿透
1.NAT和iptables理论见: http://lustlost.blog.51cto.com/2600869/943110 2.引子 近期,有同事抱怨说数据入库时,由于数据库所在的服务器只有内网 ...
- 树莓派2系统DietPi简单安装配置使用介绍
DietPi在Raspberrypi.org上的原帖:http://dwz.cn/HSrmY 版本发布很频繁,给原作者们点个赞.功能会越来越多,而且作者的定制观点很明确,适合树莓派的使用. 之前关于D ...
- win10 64位安装memcache扩展和开启redis扩展
前面有关于win10下搭建wamp环境的介绍,在此不在赘述,php操作memcache有memcache库和memcached库,其中memcache是php内置的扩展库,支持面向对象和面向过程两种操 ...
- ASP.NET中使用JqGrid完整实现
文章提纲 介绍 & 使用场景 JqGrid的一些说明 JqGrid和ASP.NET整合详细步骤 前置准备 框架搭建 数据填充 数据增/删/改 其他 介绍&使用场景 JqGrid不是一个 ...
- asp rs开启关闭问题
使用rs.close关闭后,可以直接用rs.open来打开数据表:如果用了set rs = nothing 从内存中清除rs对象,再次加载rs对象就需要使用set rs=server.createob ...