zoukankan      html  css  js  c++  java
  • IBatis.Net获取执行的Sql语句

    前言

    IBatis.Net中Sql语句是些在配置文件中的,而且配置文件是在程序启动时读取的(我们开发的时候需要将其设置成较新复制或者是始终复制),而不是程序将其包含在其中(例如NHibernate的映射文件则是设成了嵌入式资源)。很多时候我想获取程序执行了那些sql,当程序显示错误时,我们想跟踪sql,或者是查看sql是否正确,难道要我们去查看程序在跟踪到映射的配置文件查看吗。可以通过两种方式实现:

    一、通过配置文件配置

    为程序的配置文件(App.config或者web.config)文件中添加如下配置

    <configSections>
        <!-- 输出IBatis.net执行的SQL语句到控制台 -->
        <sectionGroup name="iBATIS">
          <section name="logging" type="IBatisNet.Common.Logging.ConfigurationSectionHandler, IBatisNet.Common" />
        </sectionGroup>
      </configSections>
      <iBATIS>
        <logging>
          <logFactoryAdapter type="IBatisNet.Common.Logging.Impl.TraceLoggerFA, IBatisNet.Common">
            <arg key="showLogName" value="true" />
            <arg key="showDataTime" value="true" />
            <arg key="level" value="ALL" />
            <arg key="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:SSS" />
          </logFactoryAdapter>
        </logging>
      </iBATIS>

    这样就可以在输出控制台查看执行的sql了。例如查询语句执行时输出的sql语句

    ...好像哪里不对,输出了所有的sql!但我们需要的只是执行的sql。其IBatis.Net在启动时,也就是SqlMapper创建时会去统一一次性将所有的映射文件准备到程序中,也就是读取sql,所以第一次查询的时候显示准备类所有的sql,当再次执行其他sql是则会只显示执行的sql了。

    当然IBatis.Net支持log4Net的配置将sql输出到文件中的。因为对log4Net不感冒,更多倾向NLog,所以此处略过。

    二、在程序调用时代码输出

       protected virtual IDbCommand GetDbCommand(ISqlMapper sqlMapper, string statementName, object paramObject)
            {
                IStatement statement = sqlMapper.GetMappedStatement(statementName).Statement;
                IMappedStatement mapStatement = sqlMapper.GetMappedStatement(statementName);
                ISqlMapSession session = new SqlMapSession(sqlMapper);
    
                if (sqlMapper.LocalSession != null)
                {
                    session = sqlMapper.LocalSession;
                }
                else
                {
                    session = sqlMapper.OpenConnection();
                }
    
                RequestScope request = statement.Sql.GetRequestScope(mapStatement, paramObject, session);
                mapStatement.PreparedCommand.Create(request, session as ISqlMapSession, statement, paramObject);
                IDbCommand cmd = session.CreateCommand(CommandType.Text);
                cmd.CommandText = request.IDbCommand.CommandText;
                //return request.IDbCommand;
                return cmd;
            }

    通过上面这个方法得到执行的sql执行命令即可得到命令的sql了。

    或者

     public string GetSql(ISqlMapper sqlMapper, string tag, object paramObject)
            {
                IStatement statement = sqlMapper.GetMappedStatement(tag).Statement;
                IMappedStatement mapStatement = sqlMapper.GetMappedStatement(tag);
                ISqlMapSession session = new SqlMapSession(sqlMapper);
    
                if (sqlMapper.LocalSession != null)
                {
                    session = sqlMapper.LocalSession;
                }
                else
                {
                    session = sqlMapper.OpenConnection();
                }
    
                RequestScope request = statement.Sql.GetRequestScope(mapStatement, paramObject, session);
                return request.PreparedStatement.PreparedSql;
            }

    调用示例

      public virtual int Update(string statement, object parameter)
            {
                ISqlMapper mapper = HisMapper.Instance();
                try
                {
                    string str = GetSql(mapper, statement, parameter);
                    System.Diagnostics.Debug.WriteLine(str);   //控制台输出
                    return mapper.Update(statement, parameter);
                }
                catch (Exception ex)
                {
                    throw new Exception("update faile!", ex);
                }
            }

    最后

    如果单纯的调试,建议还是直接根据修改配置文件将其输出到控制台即可。

    如果是想以其他形式记录执行的sql,可以通过配置log4net输出文件,也可以通过程序处理。

    当然如果想通过Ibatis.net执行返回DataTable或者DataSet则需要通过先获取Sql或者command在执行了。

    例如

      public virtual DataTable QueryForDataTable(string statementName, object paramObject)
            {
                DataSet ds = new DataSet();
                bool isSessionLocal = false;
                IDalSession session = HisMapper.Instance().LocalSession;
                if (session == null)
                {
                    session = new SqlMapSession(HisMapper.Instance());
                    session.OpenConnection();
                    isSessionLocal = true;
                }
    
                IDbCommand cmd = GetDbCommand(HisMapper.Instance(), statementName, paramObject);//SQL text command
    
                try
                {
                    cmd.Connection = session.Connection;
                    IDbDataAdapter adapter = session.CreateDataAdapter(cmd);
                    adapter.Fill(ds);
                }
                finally
                {
                    if (isSessionLocal)
                    {
                        session.CloseConnection();
                    }
                }
    
                return ds.Tables[0];
            }

    ok,就写这么多了。

    Top
    收藏
    关注
    评论
  • 相关阅读:
    Codeforces Round #251 (Div. 2) A
    topcoder SRM 623 DIV2 CatAndRat
    topcoder SRM 623 DIV2 CatchTheBeatEasy
    topcoder SRM 622 DIV2 FibonacciDiv2
    topcoder SRM 622 DIV2 BoxesDiv2
    Leetcode Linked List Cycle II
    leetcode Linked List Cycle
    Leetcode Search Insert Position
    关于vim插件
    Codeforces Round #248 (Div. 2) B. Kuriyama Mirai's Stones
  • 原文地址:https://www.cnblogs.com/Joy-et/p/4926571.html
Copyright © 2011-2022 走看看