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. ...
随机推荐
- Github代理设置
启用代理 git config --global http.proxy http://proxyuser:proxypwd@proxy.server.com:8080 git config --glo ...
- 放下恩怨,曝小米中兴投关键性一票让华为顺利取得5G短码控制权
如果说最近国内科技公司最牛逼最令人振奋的新闻是啥,显然,就是两天前在3GPP RAN1 87次会议的5G短码方案讨论中,华为顺利碾压高通,战胜列强,拿下了5G的控制编码方案的标准. 虽然说,目前,华为 ...
- hdu5468 Puzzled Elena
hdu5468 Puzzled Elena 题意 求一棵子树内与它互质的点个数 解法 容斥 我们先求出与它不互质的数的个数,再用总数减去就好. #include <cstdio> #inc ...
- Nessus的安装/激活/更新
0x1,安装 百度:Nessus,随意下载一个就好了. 0x2,激活 开启代理,获取register code,如图: 获取到register code,填写,进行激活,意外报错: NOTICE: A ...
- 2015.4.21 实现一般免登陆,微博QQ分享,字体自适应等
1.实现一般的登录验证和免登陆: 解决方法:node方法代码,nodeJS实现的session模块,不完整,但能用,仅供参考. 语言无所谓,session的机制都是一样的,实现不一样而已,: 2. ...
- Unity3D 之脚本架构,优雅地管理你的代码
本文参考雨松MOMO大神的帖子: 图片全部来自他的帖子(请允许我偷懒下) --------------------------------------------------------------- ...
- NoClassDefFoundError vs ClassNotFoundException
我们先来认识一下Error 和Exception, 两个都是Throwable类的直接子类. Javadoc 很好的说明了Error类: An Error is a subclass of Thro ...
- tyvj1089 smrtfun
背景 广东汕头聿怀初中 Train#2 Problem3 描述 现有N个物品,第i个物品有两个属性A_i和B_i.在其中选取若干个物品,使得sum{A_i + B_i}最大,同时sum{A_i},s ...
- LYDSY模拟赛day2 Dash Speed
/* 弃坑 */ #include<cstdio> #include<algorithm> using namespace std; ,M=N*; ],nxt[N<< ...
- toolkit --------chart属性
Data Visualization类组件以直观的图表方式显示数据的分布,能够让我们更好地分析各数据的内在联系.本文主要向大家介绍该类组件的基本特性以及使用实例. 一.基本特性介绍 1.chart组件 ...