前言
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,就写这么多了。