zoukankan      html  css  js  c++  java
  • 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 ,下面是两种实现. 大约的感觉,如果你在意性能的话,第一种会快些

     1         /// <summary>
     2         /// 查询返回DatatTable
     3         /// </summary>
     4         /// <param name="statementName"></param>
     5         /// <param name="parameterObject"></param>
     6         /// <returns></returns>
     7         public DataTable QueryForDataTable(string statementName, object parameterObject)
     8         {
     9             bool isSessionLocal = false;
    10             ISqlMapSession session = SqlMap.LocalSession;
    11             DataTable dataTable = null;
    12             if (session == null)
    13             {
    14                 session = SqlMap.CreateSqlMapSession();
    15                 isSessionLocal = true;
    16             }
    17             try
    18             {
    19                 IMappedStatement statement = SqlMap.GetMappedStatement(statementName);
    20                 dataTable = new DataTable(statementName);
    21                 RequestScope request = statement.Statement.Sql.GetRequestScope(statement, parameterObject, session);
    22                 statement.PreparedCommand.Create(request, session, statement.Statement, parameterObject);
    23                 using (request.IDbCommand)
    24                 {
    25                     dataTable.Load(request.IDbCommand.ExecuteReader());
    26                 }
    27             }
    28             catch
    29             {
    30                 throw;
    31             }
    32             finally
    33             {
    34                 if (isSessionLocal)
    35                 {
    36                     session.CloseConnection();
    37                 }
    38             }
    39             return dataTable;
    40         }
    查询返回DatatTable
     1 /// <summary>
     2         /// iBatisNet 1.6版本 返回DataSet
     3         /// </summary>
     4         /// <param name="statementName"></param>
     5         /// <param name="paramObject"></param>
     6         /// <returns></returns>
     7         public DataSet QueryForDataSet(string statementName, object paramObject)
     8         {
     9             DataSet ds = new DataSet();
    10             ISqlMapper mapper = Mapper.Instance();
    11             IMappedStatement statement = mapper.GetMappedStatement(statementName);
    12             if (!mapper.IsSessionStarted)
    13             {
    14                 mapper.OpenConnection();
    15             }
    16             RequestScope scope = statement.Statement.Sql.GetRequestScope(statement, paramObject, mapper.LocalSession);
    17             statement.PreparedCommand.Create(scope, mapper.LocalSession, statement.Statement, paramObject);
    18             IDbCommand command = mapper.LocalSession.CreateCommand(CommandType.Text);
    19             command.CommandText = scope.IDbCommand.CommandText;
    20             foreach (IDataParameter pa in scope.IDbCommand.Parameters)
    21             {
    22                 command.Parameters.Add(new SqlParameter(pa.ParameterName, pa.Value));
    23             }
    24             mapper.LocalSession.CreateDataAdapter(command).Fill(ds);
    25             return ds;
    26         }
    iBatisNet 1.6版本 返回DataSet
     1 public DataSet QueryForDataSet2(string statementName, object parameterObject)
     2         {
     3             bool isSessionLocal = false;
     4             ISqlMapSession session = _sessionStore.LocalSession;
     5             DataSet ds = new DataSet(statementName);
     6             if (session == null)
     7             {
     8                 session = CreateSqlMapSession();
     9                 isSessionLocal = true;
    10             }
    11             try
    12             {
    13                 IMappedStatement statement = GetMappedStatement(statementName);
    14                 RequestScope request = statement.Statement.Sql.GetRequestScope(statement, parameterObject, session);
    15                 statement.PreparedCommand.Create(request, session, statement.Statement, parameterObject);
    16                 FieldInfo info = request.IDbCommand.GetType().GetField("_innerDbCommand", BindingFlags.NonPublic | BindingFlags.Instance);
    17                 using (IDbCommand cmd = (IDbCommand)info.GetValue(request.IDbCommand))
    18                 {
    19                     session.CreateDataAdapter(cmd).Fill(ds);
    20                 }
    21  
    22             }
    23             catch
    24             {
    25                 throw;
    26             }
    27             finally
    28             {
    29                 if (isSessionLocal)
    30                 {
    31                     session.CloseConnection();
    32                 }
    33             }
    34             return ds;
    35         }
    利用反射返回DataSet

    以下是1.6.1版本之前返回DataTable的方法。

     1 private IDbCommand GetDbCommand(string statementName, object paramObject)
     2         {
     3             IStatement statement = sqlMap.GetMappedStatement(statementName).Statement;
     4 
     5             IMappedStatement mapStatement = sqlMap.GetMappedStatement(statementName);
     6 
     7             IDalSession session = new SqlMapSession(sqlMap);
     8 
     9             if (sqlMap.LocalSession != null)
    10             {
    11                 session = sqlMap.LocalSession;
    12             }
    13             else
    14             {
    15                 session = sqlMap.OpenConnection();
    16             }
    17 
    18             RequestScope request = statement.Sql.GetRequestScope(mapStatement, paramObject, session);
    19 
    20             mapStatement.PreparedCommand.Create(request, session, statement, paramObject);
    21 
    22             return request.IDbCommand;
    23 
    24         }
    获取DbCommand

    这种返回DataTable的方式,容易引起Sql注入,因为xml文件中,sql语句需要使用$作为占位符。

     1         /// <summary>
     2         /// 通用的以DataTable的方式得到Select的结果(xml文件中参数要使用$标记的占位参数)
     3         /// </summary>
     4         /// <param name="statementName">语句ID</param>
     5         /// <param name="paramObject">语句所需要的参数</param>
     6         /// <returns>得到的DataTable</returns>
     7         protected DataTable ExecuteQueryForDataTable(string statementName, object paramObject)
     8         {
     9             DataSet ds = new DataSet();
    10             bool isSessionLocal = false;
    11             IDalSession session = sqlMap.LocalSession;
    12             if (session == null)
    13             {
    14                 session = new SqlMapSession(sqlMap);
    15                 session.OpenConnection();
    16                 isSessionLocal = true;
    17             }
    18 
    19             IDbCommand cmd = GetDbCommand(statementName, paramObject);
    20 
    21             try
    22             {
    23                 cmd.Connection = session.Connection;
    24                 IDbDataAdapter adapter = session.CreateDataAdapter(cmd);
    25                 adapter.Fill(ds);
    26             }
    27             finally
    28             {
    29                 if (isSessionLocal)
    30                 {
    31                     session.CloseConnection();
    32                 }
    33             }
    34 
    35             return ds.Tables[0];
    36 
    37         }
    返回DataTable

    如果参数中,包含有output参数,则使用下面的方法

     1 /// <summary>
     2         /// 通用的以DataTable的方式得到Select的结果(xml文件中参数要使用$标记的占位参数)
     3         /// </summary>
     4         /// <param name="statementName">语句ID</param>
     5         /// <param name="paramObject">语句所需要的参数</param>
     6     /// <param name="htOutPutParameter)">Output参数值哈希表</param>
     7         /// <returns>得到的DataTable</returns>
     8         protected DataTable ExecuteQueryForDataTable(string statementName, object paramObject, out Hashtable htOutPutParameter)
     9         {
    10             DataSet ds = new DataSet();
    11             bool isSessionLocal = false;
    12             IDalSession session = sqlMap.LocalSession;
    13             if (session == null)
    14             {
    15                 session = new SqlMapSession(sqlMap);
    16                 session.OpenConnection();
    17                 isSessionLocal = true;
    18             }
    19 
    20             IDbCommand cmd = GetDbCommand(statementName, paramObject);
    21 
    22             try
    23             {
    24                 cmd.Connection = session.Connection;
    25                 IDbDataAdapter adapter = session.CreateDataAdapter(cmd);
    26                 adapter.Fill(ds);
    27             }
    28             finally
    29             {
    30                 if (isSessionLocal)
    31                 {
    32                     session.CloseConnection();
    33                 }
    34             }
    35 
    36             foreach (IDataParameter parameter in cmd.Parameters)
    37             {
    38                 if (parameter.Direction == ParameterDirection.Output)
    39                 {
    40                     htOutPutParameter[parameter.ParameterName] = parameter.Value;
    41                 }
    42             }
    43 
    44             return ds.Tables[0];
    45 
    46         }
    返回DataTable,包含output参数

    参考链接:

    原文地址:ibatis 返回DataTable和DataSet作者:happytor

    原文地址:[IBatisNet]关于返回DataTable的一点问题 作者:Daniel Pang

    感谢您的认真阅读,更多内容请查看:
    出处:http://www.cnblogs.com/weiqinl
    个人主页http://weiqinl.com
    github: weiqinl
    简书:weiqinl
    您的留言讨论是对博主最大的支持!
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Mac开发者常用的工具
    10个常见的缓存使用误区
    果壳摘选
    WPF 无缝图片滚动
    WinForm 子线程修改主线程(UI线程)
    如何在WinForm中发送HTTP请求
    新闻接口调用之新浪滚动新闻
    使用json-lib进行Java和JSON之间的转换
    转载 一位程序员的妻子讲述她老公教给她了什么
    sae 上传文件 java实现
  • 原文地址:https://www.cnblogs.com/weiqinl/p/4936110.html
Copyright © 2011-2022 走看看