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(网上例子的集合)的更多相关文章

  1. iBatis.Net实现返回DataTable和DataSet对象

    如题.要返回一个ADO.NET对象好像没有使用ORM的必要,而且从编程的角度看这样的实现一点也不OO,但是实际的开发场景中还是会碰到这种需求的.下面我就借鉴前人的经验,结合实际的示例,再总结一下.如果 ...

  2. 二、Ajax请求MVC中数据查询表返回datatable

    一.Ajax请求MVC中数据查询表返回datatable 解决方式 返回list

  3. WebService返回DataTable

    http://blog.csdn.net/wxnjob/article/details/8638420 webservice返回datatable时报序列化错误 以下三种方案的实质应该都是序列化的,有 ...

  4. LINQ查询返回DataTable类型

    个人感觉Linq实用灵活性很大,参考一篇大牛的文章LINQ查询返回DataTable类型 http://xuzhihong1987.blog.163.com/blog/static/267315872 ...

  5. Entity Framework执行Sql语句返回DataTable

    Entity Framework中对外开放了数据库连接字符串,使用的时候可以直接得到这个连接字符串,然后进行相关的操作.如果在使用的过程中,发现Entity Framework中有一些满足不了的需求的 ...

  6. 在DataTable中执行DataTable.Select("条件")返回DataTable;

    转:http://blog.csdn.net/hcf_force/article/details/7779062 1.在DataTable中执行DataTable.Select("条件&qu ...

  7. 转:LINQ查询返回DataTable类型

    动态绑定ReportViewer虽然之前实现过,但现在弄起来还是有点晕,主要是过去没有使用Linq,数据的操作经常用到DataTable,可以直接拿来使用,现在用Linq更方便,也懒得再用之前的数据库 ...

  8. C#读取txt文件返回DATATABLE

    //1.打开资源管理器 OpenFileDialog open = new OpenFileDialog(); if (open.ShowDialog() == DialogResult.OK) { ...

  9. WebService返回DataTable问题

    今天做项目时,想在WebService中返回DataTable,在单位没成功,看网上有人说datable在.net1.1中是没有序列化的,不能直接在webservice中返回,可以返回dataset. ...

随机推荐

  1. jsp中的<%%>和<!%%>的区别

    jsp 都是解析成.java文件` 具体代码请看 如果你写 <%int a=1;%> 生成的代码是 public class xxx_jsp { public void doProcess ...

  2. MapReduce实现手机上网流量分析(业务逻辑)

    一.问题背景 现在的移动刚一通话就可以在网站上看自己的通话记录,以前是本月只能看上一个月.不过流量仍然是只能看上一月的. 目的就是找到用户在一段时间内的上网流量. 本文并没有对时间分组.下一节进行分区 ...

  3. BUAA_OVERWATCH第一次行动前战略部署

    这太IMBA了! 需求调研问卷的反馈 #define A 调查问卷 A设计背景 随着各种新兴手游的兴起,以及各大直播间内Lying Man的火热,以及各种娱乐方式的发展,传统桌游很好地移植到app上的 ...

  4. jsContext全局函数调用与对象函数调用、evaluateScript

    evaluateScript:兼具js加载(生成具体的上下文)(函数与通用变量的加载),与函数执行的功能: 函数调用的方式有两种: 1)获取函数(对象),然后执行调用: [context[@" ...

  5. 11月7日上午PHP会话控制(session和cookie)、跨页面传值

    1.session  登录上一个页面以后,长时间没有操作,刷新页面以后需要重新登录. 特点:(1)session是存储在服务器:   (2)session每个人(登陆者)存一份: (3)session ...

  6. OC JS交互(通常情况下,如果网页写得正规的话,是可以正常交互的,之前就遇到后台写h5始终拿不到事件,元素也拿不到,更别说交互了,真是奇了怪了)

    自动填充表单 @"document.getElementById('loginid').value = '这里填入你的用户名';document.getElementById('userpa ...

  7. Solr学习总结(四)Solr查询参数

    今天还是不会涉及到.Net和数据库操作,主要还是总结Solr 的查询参数,还是那句话,只有先明白了solr的基础内容和查询语法,后续学习solr 的C#和数据库操作,都是水到渠成的事.这里先列出sol ...

  8. 使用Xcode HeaderDoc和Doxygen文档化你的Objective-C和Swift代码

    在一个应用的整个开发过程中涉及到了无数的步骤.其中一些是应用的说明,图片的创作,应用的实现,和实现过后的测试阶段.写代码可能组成了这个过程的绝大部分,因为正是它给了应用生命,但是这样还不够,与它同等重 ...

  9. Spring实战 (第3版)——AOP

    在软件开发中,分布于应用中多处的功能被称为横切关注点.通常,这些横切关注点从概念上是与应用的 业务逻辑相分离的(但是往往直接嵌入到应用的业务逻辑之中).将这些横切关注点与业务逻辑相分离正是 面向切面编 ...

  10. Windows群集安装

    一.安装前准备 1.安装dotnet 3.5 框架功能 2.安装starwind,并创建虚拟磁盘http://www.cnblogs.com/chhuang/p/3623305.html 3.使用iS ...