Richie

Sometimes at night when I look up at the stars, and see the whole sky just laid out there, don't you think I ain't remembering it all. I still got dreams like anybody else, and ever so often, I am thinking about how things might of been. And then, all of a sudden, I'm forty, fifty, sixty years old, you know?

NHibernate代码解析 - Driver

    NHibernate-1.2.0.Beta3-debug

    为什么从Driver开始?数据库的使用、多数据库的封装是NHibernate比较底层的东西,因此决定从这里开始。
    多数据库支持的实现无外乎几个方面:使用标准的SQL语句;对客户(Client)封装各类数据库的ADO.NET对象;一些数据库之间特殊性的处理。

    Driver目录下一系列的类,主要目的是封装DbConnection、DbCommand对象的创建,以及Prepare Command,和Command相关的Parameter的操作和处理。
    各类数据库的ADO.NET Provider,都会从DbConnection、DbCommand、DbParameter等这些基础的对象继承,因此对各类数据库ADO.NET Provider的封装使用Facade模式。
   
    Facade模式从上面类图可以看出来。通过配置指定你使用的数据库Driver类,用反射创建Driver实例代替了Factory,Client只使用IDriver或DriverBase类型。
    配置属性hibernate.connection.driver_class从IDriver的具体实现中选择。

    1. IDriver
    最基础的抽象。主要声明的方法:创建IDbConnection、IDbCommand对象;创建IBatcher对象(什么作用?不知道);同一个IDbConnection对象是否支持同时打开多个IDataReader对象等。
    为什么不使用IDbConnection的CreateCommand方法?有数据库的IDbConnection不支持这个方法?不可能。还是为了避免IDbCommand对象一创建就绑定了IDbConnection对象?
    2. ISqlParameterFormatter
    获取Sql语句中第n个参数的参数名。只声明一个方法string GetParameterName(int index)。
        a.) 后面可以看到对于一个Sql语句,NHinbernate用SqlString进行封装,最主要是处理参数名后帮定。在生成最终数据库可以执行的Sql语句时,需要生成参数名,然后生成最终可执行的sql语句。不同的数据库参数的表示不一样,因此生成参数名这个职责落在Driver对象上或至少跟它密切相关。
        b.) 不仅仅是处理数据库不同参数表示不一样的问题,ISqlParameterFormatter同时也确定了一个参数名生成规则,即按照参数的索引顺序生成参数名。在DriverBase的实现中,假如sql语句中有三个参数,则参数名按照顺序分别是p0、p1、p2,这些参数名被用于生成的sql语句、IDbCommand的Parameters对象中。执行时刻也按照顺序提供各个参数的值。
    Odbc、Oledb等使用单一的一个?号表示参数,SqlServer在参数名前面加@符号表示,Oracle使用:前缀,MySql使用?前缀。
    3. DriverBase
    对IDriver最基本的实现,以及部分实现上的扩展。
    4. OdbcDriver、OleDbDriver、SqlClientDriver
    具体实现。
    这三个类都是直接从DriverBase继承,重载实现DriverBase的CreateConnection()、CreateCommand()等方法。因为.Net Framework已经包含了这几种ADO.NET对象,在实现这些方法时,只须用相应的命名空间直接创建对象即可。对于其它的数据库,NHibernate不能将他们的ADO.NET Provider一一引用到项目里面来,因此通过配置使用反射的方式来创建这些数据库的相关对象,这就是ReflectionBasedDriver的分支。
    5. ReflectionBasedDriver
    提供通过反射创建相应数据库ADO.NET对象的支持。继承的子类在构造函数中提供数据库驱动的Assembly Name、IDbConnection和IDbCommand的类名。ReflectionBasedDriver构造函数根据子类提供的信息,在CreateConnection()和CreateCommand()时就可以使用反射创建对象。
    6. OracleClientDriver、MySqlDataDriver、FirebirdDriver等
    具体实现。

    SqlStringFormatter和NDataReader相关的两个类结合其它部分看。

posted on 2007-01-18 23:56 RicCC 阅读(340) 评论(2)  编辑 收藏 所属分类: NHibernate

Feedback

#1楼  2007-02-10 14:18 flybird [未注册用户]

支持,好东西,继续努力!   回复  引用    

#2楼  2007-09-04 01:52 jecray      

是不是支持所有的主流数据库啊
  回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  博客园首页

  新闻频道

  社区

  小组

  博问

  网摘

  闪存

  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-11-14 22:07 编辑过


相关链接: