之前谈了NHibernate的几个方面,似乎抱怨的居多,不过这次我想谈一下我对Interceptor的感受,则基本上都是好话了。这并不一定是说Interceptor设计的又多么好(事实上它使用起来还是挺麻烦的),但是这的确也是我认为NHibernate超越LINQ to SQL,尤其是Entity Framework的又一个重要方面——因为Entity Framework本身也已经不差了。更重要的是,Interceptor机制让我得以实现我“理想中的”数据访问功能。当然现在只是浅尝辄止一番,我打算以后再慢慢地,详细地谈谈我所满意的“数据访问层”设计。
Interceptor的作用是为NHIbernate中的Session(如LINQ to SQL中的DataContext)增加一个“拦截器”,这个拦截器会捕获到Session各个阶段所发生的事情,并且有机会访问到它们所牵涉到的数据。例如:
OnLoad:当前Session加载了哪些对象
OnDelete:当前Session删除了哪些对象
OnSave:Session保存了哪些对象
PostFlush:当前Session的Flush已经完成了
关于Interceptor功能,NHibernate的文档上只是一笔带过,更详细的信息可以参考Hibernate的API说明。由于Interceptor可以记录到Session中所经过的所有对象,因此它可以做的事情就很多了。例如已经被人写滥的“日志记录”或“审查(Audit)”,但好像少有人把它真正用在数据访问的功能上。我了解Interceptor之后感觉非常兴奋,因为终于有人为我想要实现的功能做好铺垫了。这个功能便是“结合其它数据访问机制”。
说到数据访问层,大家肯定知道它的职责是“从数据源读写数据”。在很长一段时间内,这个数据源基本上就是关系型数据库,无论是商业的SQL Server,Oracle还是开源的MySQL,PostgreSQL,万变不离其宗。于是有人提出了SqlHelper,Data Access Block这样的数据库读取辅助工具、iBatis这样的SQL-对象映射工具(我不认为它是ORM)、还有NHibernate、LINQ to SQL这样的ORM框架。但是无论是什么工具,无论怎么访问,数据访问层作的事情也无非是SQL、SQL、SQL,然后再把得到的数据集转化为内存中的对象。
但是到了如今的时代,数据访问层所负责的数据源已经远远不止这些了。例如,许超前在博客上介绍了手机之家的数据访问层功能,这是其中一幅截图: