【本文原创,第一次离首页如此之近。发在候选区攒攒rp,管理员看着不合适可以撤下。】
  虽然只在iBatis的世界里小打小闹匆匆数月,却历经数次与领导和同事激辩,再通过不懈努力学习和开发积累,楼猪终于被它小巧而不失强大,稳定而不失灵活所折服。作为80后顽固、偏执和nc一族,楼猪一向保守认为自己是美貌与智慧并存的。仗着天资聪慧,在之前的“iBatis.net直接执行sql语句”里曾经公然抱怨iBATIS对sql语句的直接查看灰常的不友好,调试不方便,排除错误非常考验眼神,很重要的一条(甚至应该算是楼猪一开始就讨厌排斥iBatis的罪魁祸首)就是参数化的sql语句。但是也不能说获取到的运行时sql语句一点用木有,至少我们还是可以看到sql语句的大致组装情况的。说到这里,再对照标题,您可能会认为楼猪是要教大家怎么获取运行时的sql语句。以楼猪一贯自恋臭美的作风,这次会这么肤浅么......
  再给大家一次大胆猜测的机会......当当当当,我kao,新年新气象,大家变得更聪明了,一点惊喜和意外都木有,果然。好了,有没有新意,看看楼猪的介绍再说吧:
一、常见iBatis.net获取运行时sql语句方式
通常我们都是在一个公共类里写一个方法,单独作为获取sql语句的帮助类(IBatisHelper.cs),然后在sqlmapper方法调用的地方调用帮助类和它的方法。
1、实现代码

/// <summary>
        /// 得到运行时ibatis.net动态生成的SQL
        /// </summary>
        /// <param name="sqlMapper"></param>
        /// <param name="statementName"></param>
        /// <param name="paramObject"></param>
        /// <returns></returns>
        public static string GetRuntimeSql(ISqlMapper sqlMapper, string statementName, object paramObject)
        {
            string result = string.Empty;
            try
            {
                IMappedStatement statement = sqlMapper.GetMappedStatement(statementName);
                if (!sqlMapper.IsSessionStarted)
                {
                    sqlMapper.OpenConnection();
                }
                RequestScope scope = statement.Statement.Sql.GetRequestScope(statement, paramObject, sqlMapper.LocalSession);
                result = scope.PreparedStatement.PreparedSql;
            }
            catch (Exception ex)
            {
                result = "获取SQL语句出现异常:" + ex.Message;
            }
            return result;
        }

2、使用帮助类获取sql语句
接着采用类似如下实现方式进行调用:

public IList<Person> SelectPersons(Person model)
        {
            string sql = IBatisHelper.GetRuntimeSql(this.SqlMapper, this.GetStatementName("SelectPersons"), model);
            return this.SqlMapper.QueryForList<Person>(this.GetStatementName("SelectPersons"), model);
        }

在之前做过的大大小小形形色色的项目中,楼猪没少这么写,开发团队其他成员也是一样的,灰常和谐默契。
二、iBatis.net获取运行时sql语句方式的改进  但是每做一个新项目就要写个一模一样的帮助类来(嗨,您现在嗅到坏味道并且看到杯具了吧?!),偏执追求完美的nc楼猪就想,各位大神早就教导我们重复是邪恶的(Duplication is Evil (DIE)),大家一起不亦乐乎地重复呢?这里您一定会善意建议楼猪把帮助类写进公共类库里,大家以后公共调用那个类库就可以了。思路确实没错,很不客气地说,楼猪第一次使用iBatis就想这么干了。看到这里含蓄的您可能已经会心一笑,豪放点的也许已经也有“tmd,老子也和你想到一块去了”之感。其实在很多技术问题上,大家的看法最终还是非常容易达到高度统一的。
  楼猪是通过抽象出一个具有获取运行时sql语句的方法的BaseIBatisDao基类,封装并改进初始化SqlMapper对象的方式实现公共调用的:
1、BaseIBatisDao泛型抽象类

using System;
using IBatisNet.DataMapper;
using IBatisNet.DataMapper.Scope;
using IBatisNet.DataMapper.MappedStatements;
namespace DotNet.Common.IBatisUtil
{
    public abstract class BaseIBatisDao<T> where T : class
    {
        #region Properties
        public ISqlMapper SqlMapper { get; set; }
        #endregion
        #region Constructor
        public BaseIBatisDao()
        {
        }
        public BaseIBatisDao(string mapperName)
        {
            this.SqlMapper = SqlMapperManager.GetMapper(mapperName);
        }
        #endregion
        #region Functions
        /// <summary>
        /// 得到运行时ibatis.net动态生成的SQL
        /// </summary>
        /// <param name="sqlMapper"></param>
        /// <param name="statementName"></param>
        /// <param name="paramObject"></param>
        /// <returns></returns>
        public virtual string GetRuntimeSql(ISqlMapper sqlMapper, string statementName, object paramObject)
        {
            string result = string.Empty;
            try
            {
                IMappedStatement statement = sqlMapper.GetMappedStatement(statementName);
                if (!sqlMapper.IsSessionStarted)
                {
                    sqlMapper.OpenConnection();
                }
                RequestScope scope = statement.Statement.Sql.GetRequestScope(statement, paramObject, sqlMapper.LocalSession);
                result = scope.PreparedStatement.PreparedSql;
            }
            catch (Exception ex)
            {
                result = "获取SQL语句出现异常:" + ex.Message;
            }
            return result;
        }
        /// <summary>
        /// 获取sqlMap对应statement的完整id
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        protected virtual string GetStatementName(string name)
        {
            return string.Format("{0}.{1}", typeof(T).Namespace, name);
        }
        #endregion
    }
}

在这个基类中,在初始化SqlMapper对象的地方,楼猪是通过一个辅助类(SqlMapperManager)通过单例模式实现的:

using System;
using System.Collections.Generic;
using IBatisNet.DataMapper;
using IBatisNet.DataMapper.Configuration;
using IBatisNet.DataMapper.SessionStore;
namespace DotNet.Common.IBatisUtil
{
    /// <summary>
    /// SqlMap创建管理
    /// </summary>
    public class SqlMapperManager
    {
        private static readonly object objSync = new object();
        private static readonly IDictionary<string, ISqlMapper> dictMappers = null;
        static SqlMapperManager()
        {
            dictMappers = new Dictionary<string, ISqlMapper>();
        }
        /// <summary>
        /// 实例化SqlMap对象
        /// </summary>
        /// <param name="mapperName">通常.config文件</param>
        /// <returns></returns>
        public static ISqlMapper GetMapper(string mapperName)
        {
            if (string.IsNullOrEmpty(mapperName))
            {
                throw new Exception("MapperName为空!");
            }
            if (mapperName.ToLower().LastIndexOf(".config") == -1)
            {
                mapperName += ".config";
            }
            ISqlMapper mapper = null;
            if (dictMappers.ContainsKey(mapperName))
            {
                mapper = dictMappers[mapperName];
            }
            else
            {
                if (mapper == null)
                {
                    lock (objSync)
                    {
                        if (mapper == null)
                        {
                            mapper = new DomSqlMapBuilder().Configure(mapperName);
                            mapper.SessionStore = new HybridWebThreadSessionStore(mapper.Id);
                            dictMappers.Add(mapperName, mapper);
                        }
                    }
                }
            }
            return mapper;
        }
    }
}

2、在DAO中调用BaseIBatisDao基类

using System.Collections.Generic;
using DotNet.Common.IBatisUtil;
using IBatisNetApp.DAL.Model;
namespace IBatisNetApp.DAL.DAO
{
    public class PersonDao : BaseIBatisDao<Person>
    {
        public PersonDao()
            : base("Query.config")
        {
        }
        public IList<Person> SelectPersons(Person model)
        {
            string sql = this.GetRuntimeSql(this.SqlMapper, this.GetStatementName("SelectPersons"), model);
            return this.SqlMapper.QueryForList<Person>(this.GetStatementName("SelectPersons"), model);
        }
        public IDictionary<int, Person> SelectDictStoreInfo(Person model)
        {
            string sql = this.GetRuntimeSql(this.SqlMapper, this.GetStatementName("SelectPersons"), model);
            return this.SqlMapper.QueryForDictionary<int, Person>(this.GetStatementName("SelectPersons"), model, "Id");
        }
        public IList<Person> SelectPagerPersons(Person model)
        {
            string sql = this.GetRuntimeSql(this.SqlMapper, this.GetStatementName("SelectPagerPersons"), model);
            return this.SqlMapper.QueryForList<Person>(this.GetStatementName("SelectPagerPersons"), model);
        }
        public int InsertPerson(Person model)
        {
            string sql = this.GetRuntimeSql(this.SqlMapper, this.GetStatementName("InsertPerson"), model);
            int result = 0;
            object obj = this.SqlMapper.Insert(this.GetStatementName("InsertPerson"), model);
            if (obj != null)
            {
                result = int.Parse(obj.ToString());
            }
            return result;
        }
        public int DeletePersonById(int id)
        {
            string sql = this.GetRuntimeSql(this.SqlMapper, this.GetStatementName("DeletePersonById"), id);
            int result = 0;
            object obj = this.SqlMapper.Delete(this.GetStatementName("DeletePersonById"), id);
            if (obj != null)
            {
                result = int.Parse(obj.ToString());
            }
            return result;
        }
        public int UpdatePersonById(Person model)
        {
            string sql = this.GetRuntimeSql(this.SqlMapper, this.GetStatementName("UpdatePersonById"), model);
            int result = 0;
            object obj = this.SqlMapper.Update(this.GetStatementName("UpdatePersonById"), model);
            if (obj != null)
            {
                result = int.Parse(obj.ToString());
            }
            return result;
        }
    }
}

如您所看到的那样,在每一个方法里,我们要获取运行时sql语句,只要用this来get一下就可以了,看上去这个方法就像是ibatis直接封装好提供给我们的一样,再对照之前的方式,强弱悬殊,高下立判。这里要特别说明,获取运行时sql语句通常都是开发者调试时的一种辅助。调试成功后,您可以及时把获取sql的那一行注释掉。有了这个方法,普通开发调试就比较圆满了(您还可以按照项目需要扩展出其他方法,比如通过datatable,datareader等等获取sql语句),而且调用灰常省事。
3、关于DAL层的几句废话
a、在本文最下面,楼猪会给出demo下载链接。之前的几篇介绍总结iBatis的文章里,iBatis的类库版本较低(1.3.0.0),现在已经升级到(1.6.1.0),开发环境Vs2008+Sql  Server2005 Express.在运行程序的时候,请先在Sql Server上执行Script文件夹下的sql脚步建数据库和对应的表。要下载学习的童鞋请注意。
b、model层的说明
Person类直接继承的第一个基类(BaseModel)存的是其他表也可能用到的公共字段(主键Id);BaseModel直接继承自用于作为扩展查询条件的BaseQuery类;BaseQuery类继承自支持with方式分页的PagerBase类。其实看命名您可以猜到它们的各自作用了。不同的实体类可以按需要继承这三个类。
c、with分页查询方式
这个是sql server2005的with和公用表表达式提供的功能,分页效率和效果都很不错,dao所对应的xml文件里用到了“iBATIS.net复用sql语句片段”功能。sql server2005前版本和非sql server的数据库不支持此方式。楼猪之前都是通过更通用的二次top方式进行分页,希望您留意。
最后ps,本来计划在本文把iBatis事务和它的自带分页功能一并介绍的,一想起曾经无比挫折的事务使用经历,兴致全无。低俗的一句结束:日后再说。
demo下载:IBatisApp

http://www.cnblogs.com/jeffwongishandsome/archive/2010/02/24/1672960.html

iBATIS.net获取运行时sql语句相关推荐

  1. PHP获取MySQL执行sql语句的查询时间

    PHP获取MySQL执行sql语句的查询时间 1. $t1=microtime(true); mysql_query($sql); echo microtime(true)-$t1; 2. //计时开 ...

  2. kettle job如何利用java的反射机制获取执行的sql语句

    kettle job中的JavaScript如何获取同一个job中SQL步骤的执行语句并让执行语句记录在日志中呢?首先写日志需要用到job中JavaScript写日志的方法,其次是利用java反射机制 ...

  3. oracle dml触发器 获取当前执行sql语句,Oracle DML触发器

    DML触发器的要点 DML触发器是定义在表上的触发器,由DML事件引发.编写DML触发器的要素是: * 确定触发的表,即在其上定义触发器的表. * 确定触发的事件,DML触发器的触发事件有INSERT ...

  4. php查看mysql最近执行过的sql_PHP获取MySQL执行sql语句的查询时间

    //计时开始 runtime(); //执行查询 mysql_query($sql); //计时结束. echo runtime(1); //计时函数 function runtime($mode=0 ...

  5. oracle 数据库如何获取一条sql语句执行所消耗耗费的时间?

    SQL> set timing on; SQL> select count(*) from test; COUNT(*) ---------- 22590 已用时间: 00: 00: 00 ...

  6. tp获取执行的sql语句

    $News = M("news"); echo $News->getlastsql() //sql查询语句排序的写法 order by id desc,sort desc ;

  7. web项目获取运行时...\WEB-INF\classes目录下文件

    Thread.currentThread().getContextClassLoader().getResource("文件名") 例如要在tomcat启动后改变.properti ...

  8. Ibatis学习总结7--SqlMapClient 执行 SQL 语句

    SqlMapCient 类提供了执行所有 mapped statement 的 API.这些方法如下: 1 public int insert(String statementName, Object ...

  9. 获取数据库的sql语句

    --查询表是否有标识列 select name from syscolumns  where id = object_id('tb_city') and autoval is not null 查询表 ...

最新文章

  1. elasticsearch 监控
  2. Java多线程的几种实现方法
  3. T(n) = 25T(n/5)+n^2的时间复杂度 计算方法
  4. android 16 登陆,那些年我们一起养过的电子鸡登陆Android平台
  5. keepalived+LVS实现高可用的Web负载均衡
  6. 漫话:如何给女朋友解释什么是BIO、NIO和AIO?
  7. 【备注】【C11】《Android游戏编程之从零开始》PDF 下载
  8. win7锁定桌面计算机图标,Win7锁定桌面图标的详细步骤(图文)
  9. 计算机二级保存错地方,盘点考计算机二级那些容易出错的地方
  10. SVN迁移IP变更地址修改relocate
  11. 中学生怎样才能合理使用计算机,浅析中学生计算机的使用
  12. 全国独一份!200万杭州人公积金可用支付宝刷脸提取,秒到账!
  13. 如何辅导孩子做学前班数学题?
  14. 沙尘暴天气空气净化器市场走俏
  15. Hog源码注释(hog.cpp的注解)
  16. 怎么完成一个无尽的长列表
  17. kaggle中关于图像的比赛整理
  18. C++怎样获取当前系统时间?
  19. iphone ios 视频拍摄旋转
  20. 2022-2028全球及中国智能手机摄像头模组行业研究及十四五规划分析报告

热门文章

  1. OpenGL instancing实例化的实例
  2. OpenGL 帧缓冲Framebuffers
  3. c++强制类型转换运算符
  4. C语言Fibonacci 数列
  5. netcore redis 存储集合_.net core redis的全套操作
  6. maven 整合支付宝,导入alipay-sdk-java包到本地仓库,远程仓库
  7. jQuery插件AjaxFileUpload文件上传实现Javascript多文件上传功能
  8. CXF客户端配置请求超时限制-SocketTimeoutException(Spring配置文件中配置和通过代码进行配置)
  9. ip中继对接_IP软交换系统解决方案
  10. 07- app的弱网测试