物联传媒 旗下网站
登录 注册
RFID世界网 >  技术文章  >  物流  >  正文

数据访问中间件及其在物流仓储支撑平台中的应用

作者:鲍鹏
来源:通信市场网
日期:2011-01-07 09:26:19
摘要:本文分析现有的数据库访问中间件的现状,在物流仓储综合支撑平台中应用轻量级的ORM框架,介绍数据访问中间件的使用,通过具体实例表明,使用数据访问中间件可以简化数据存取访问过程,使扩展性得到了大大的增强,并可以最大限度的不影响上层的应用程序的结构,减少系统维护的难度。
  引言

  传统的数据库访问技术对于数据库操作的复杂性,以及扩展性差等问题已渐渐制约分布式应用集成的需要,利用新技术,研究和开发新的数据库访问中间件成为数据库研究领域的主要方向之一。中间件技术将传统的客户机/服务器体系结构扩展为三层体系结构模式,即客户机-中间件-服务器体系模式。

  本文所述系统为物流仓储综合支撑平台,用于支撑多种基本物流业务,包括报关(单证)、存储、运输、订舱等基本业务类型以及由这些基本业务类型所组成的各种复合业务类型。系统采用表示层、业务处理层与数据存储层三层结构的CS架构,表示层的主要职责是为用户提供信息以及提供交互。表示层细分为界面外观层与界面逻辑层。业务逻辑层的主要职责是对用户提交的输入指令与数据做校验,再加工后将数据提交到数据存储层或将数据存储层的数据提取后返回给表示层。数据存储层主要职责是存储用户数据。其中数据访问层与事务处理层,使用Castle ActiveRecord框架作为数据库持久层,框架提供对数据访问层与事务处理层的封装。
 
  数据访问中间件定义

  中间件为可以为其他程序员服用、实现特定功能接口的程序包或服务。中间件在操作系统软件,网络和数据库之上,应用软件之下,总的作用是为处于上层的应用程序提供开发环境,帮助用户高效、灵活的开发和集成更加复杂的应用软件。IDC对中间件的定义为:中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源,中间件定位于客户机服务器的操作系统之上,管理计算机资源和网络通信。按照IDC的分类方法,中间件可分为六类:终端仿真、数据访问中间件、远程过程调用中间件、消息中间件、交易中间件、对象中间件。

  本文涉及的数据访问中间件为中间件的一种,是指一切连接应用程序和数据库的软件,位于客户机服务器的操作系统之上,通过使用统一接口提供对运行在多种平台上的不同数据库的访问。通过使用数据访问中间件,可扩展性得到了大大的增强,可以最大限度的不影响上层的应用程序的结构,减少系统维护的难度。由于对于数据库的操作都被封装在数据库访问中间件,用户对数据的管理实现了对数据库操作的透明性。

  本文所述系统使用的数据库访问中间件为Castle .Net 中的额ActiveRecord组件,它是一个轻量级的ORM组件,它在底层封装了NHibernate. NHibernate是一个基于.Net,用于关系数据库的对象持久化类库,它是著名的Hibernate的.Net版本,采用xml配置文件进行关系的映射。在ActiveRecord中,则对这种方式进行了进一步的封装,采用特性(Attribute)的方式进行映射。
 
  数据访问中间件实现

  本系统采用表示层、业务处理层与数据存储层三层结构的CS架构。如下图所示为该系统项目软件结构如图一所示。

  表示层的主要职责是为用户提供信息以及提供交互。细分为:界面外观层、界面逻辑层。业务逻辑层的主要职责是对用户提交的输入指令与数据做校验,再加工后将数据提交到数据存储层或将数据存储层的数据提取后返回给表示层。细分为:业务逻辑层、实体操作层、数据访问层。数据存储层主要职责是存储用户数据。细分为:事务处理层、数据库层。

  由于本项目采用C/S架构,故仅主要使用Castle中的数据访问ORM框架Castle ActiveRecord。Castle ActiveRecord是Castle中提供的一个轻量级数据访问框架,它在底层封装了NHibernate的操作,使用特性来代替映射文件,从而提供非常简洁的O/R映射(一对一、一对多,多对多关系等均可以表达)。同时,它还实现了对象的最基本的CRUD操作,这在很大程度上减少了开发的工作量。另外,ActiveRecord支持HQL(Hibernate Query Language ),使开发人员可以自定义一些复杂查询。其他特性:多数据库连接、支持事务处理、维护方便性。提供对数据访问层与事务处理层的封装。
 
   数据访问中间件的配置

  ActiveRecord在底层封装了NHibernate,在框架启动时需要指定相关的配置信息。可以使用自己的XML文件来保存配置信息,例如有一个AppConfig.xml的文件。
<activerecord>
  <config>
       <add 
key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
       <add 
key="hibernate.dialect"   value="NHibernate.Dialect.MsSql2005Dialect" />
       <add             key="hibernate.connection.provider"value="NHibernate.Connection.DriverConnectionProvider" />
       <add 
key="hibernate.connection.connection_string" value="Data Source=.\SQLEXPRESS;Initial Catalog=DataBase;UID=sa;Password=password;" />
  </config>
</activerecord>

  创建ActiveRecord类

  使用ActiveRecord中的配置关键字ActiveRecordAttributes、PrimaryKeyAttribute、PropertyAttribute等,为实体类配置表、字段、关系等映射信息。
  使用ActiveRecordAttributes配置实体类,关联映射信息。样例如下:
  默认实体类名与数据库表同名
  [ActiveRecord()]
  public class Transport_List : Transport_Department_Base
  在实体类中,通过PrimaryKeyAttribute来指定表的主键
  [PrimaryKey()]
  public int Id
  在ActiveRecord中通过PropertyAttribute来指定实体类属性与数据库中的字段映射。
  [Property(“ForReimburse”)]
  public string Reimburse_remark
  在ActiveRecord中,允许直接对Field进行映射,使用FieldAttribute。
  [Field”CheckName”]
  public string CheckName

  配置关系映射

  多对一关系可以使用BelongsToAttribute表示。
  [BelongsTo("end_point_id")]
  public Transport_Location End_point
  一对多关系可以使用HasManyAttribute表示。
  [HasMany(typeof(Signed_List),Table = "Signed_List", 
  ColumnKey = transport_list_id", Inverse = true, Cascade = ManyRelationCascadeEnum. AllDeleteOrphan, Lazy = true)]
  public IList Signed_Lists
  ActiveRecord还支持多对多关系,以及一对一关系。在ActiveRecord中把数据库表之间的关联关系采用对象间的聚合关系来表现,然而这却带来一系列的性能上的问题。就像在一对多中用到的例子Blog,使用Blog.Find(1)查找了一个Blog对象,也许我们只用到它,但事实它却把该Blog所关联的Post对象也读取出来放在了内存中,于是就需要有一种方法来实现只在需要Post对象的时候框架再自动读取。

  要实现延迟加载,其实只要在HasAndBelongsToMany、HasManyAttribute的特性中使用Lazy=true。另外,使用延迟加载时还需要将当前的Session保存下来,否则ActiveRecord在实现延迟载入时找不到一个NHibernate的ISession而出错。为了保存当前的Session我们必须使用new SessionScope()。

  使用Scope以及schema相关方法
 
  Scopes允许优化一系列数据库操作,以及为代码块加入业务语义。一个Scopes中的所有ActiveRecord的数据库操作都是在同一个数据库线程中执行。如果使用了延迟加载,则必须使用SessionScope。包括SessionScope,TransactionScope以及Nested Transactions.

  使用SessionScope过程如下:
  using (new Castle.ActiveRecord.SessionScope())
  {
    SelectedBizList = new List<Business_List>();
    for (int j = 0; j < selectedSheetList.Count ; j++)
    {
      selectedBiz=Business_List.Find(selectedSheetList[j].Id);
      SelectedBizList.Add(selectedBiz);
     }
   }    
使用TransactionScope过程如下:
using (TransactionScope btran = new TransactionScope())
   {
     try
       {       myDriver.Create();
                   btran.VoteCommit();        }
     catch
       {       btran.VoteRollBack()       }
    }
  Castle ActiveRecord提供了由实体类生成数据库表的方法,它其实在底层是封装了NHibernate.Tool.hbm2ddl中的SchemaExport。
  既创建数据库表的方法都是通过SchemaExport类来完成了,所有的这些方法都在ActiveRecordStarter中提供.

  使用HQL查询

  ActiveRecord只提供了Find(id),FindAll()这样两个静态的查询方法,在实际查询中比如综合支撑平台中对多种业务单的详细查询就不能满足要求了,这方面ActiveRecord为我们提供了HQL语言的支持。HQL全名是Hibernate Query Language,它是一种完全面向对象的查询语言。

  SimpleQuery是一种最简单的查询,它直接处理HQL语句,并返回一个集合,没有复杂的参数处理,具体用法参考下例:
        public static Driver[] FindDriversIs_inOrNot(bool is_in)
        {    string hql = @"from Driver where Is_in = ? ";
            Castle.ActiveRecord.Queries.SimpleQuery query = new Castle.ActiveRecord.Queries.SimpleQuery(typeof(Driver), hql, is_in);
            return (Driver[])ActiveRecordBase.ExecuteQuery(query);        }
  ScalarQuery查询也是一种简单的直接处理HQL的查询,它也没有复杂的参数处理,只不过返回的值不是集合而是单一的值,具体用法类似SimpleQuery。
  HqlBasedQuery是最为强大的Query类,支持跨库/跨基类联合查询;可以使用HqlBasedQuery来实现选定属性查询,返回的结果为ArrayList,结构形式与SQL查询类似,可每行作为一个Object,而后按顺序提取字段值,具体用法参考下例:
        public static string FindMaxSnOfOuterDriver()
        {
            string hql = ""; HqlBasedQuery query;
            hql = @"select max(dir.Driver_sn) from Driver dir where dir.Is_in = 'False' ";
            query = new HqlBasedQuery(typeof(Driver), hql);
           IList result= (IList)ActiveRecordBase.ExecuteQuery(query);
           if (result == null || result.Count == 0)
               return "10000";
           else          
               else return result[0].ToString();
        }

  小结

  根据以上的介绍,利用ActiveRecord数据库访问中间件,极大的简化了数据库操作,可以扩展数据库系统的应用范围。这种中间件不仅适应于局域网,更加适应于未来的基于广域网的应用程序。ActiveRecord数据访问中间件不仅跨平台,而且使用方便,并且扩展性高。上述例子是以微软的SQL SERVER作为数据库应用,如要扩展到Oracle或其他数据库只需更新其相应的.Net插件即可。Castle的ActiveRecord底层将NHibernate封装了起来,使用起来感觉比Nhibernate方便多了,不用再去生成一个个的映射文件,调试和维护起来都方便了很多。

  经过在物流仓储综合支撑平台中应用数据访问中间件,程序的开发周期大大缩短,程序的可维护性,以及可扩展性得到了提高,在信息管理平台中使用数据访问中间件将是一个有效的解决方案。