你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / 数据库开发
3.9 网站管理分层架构技术
 

一、引言 

网站系统管理是网站系统设计的一个重要组成部分,通常说来系统管理包括用户管理、角色管理、模块管理和系统日志等功能。这些功能具有一定的通用性,一般网站应用中对这部分的需求基本一致。因此,对系统管理功能的设计具有一定的代表性。

本文讨论的网站系统管理功能采用微软的VS .NET 2005来实现,VS .NET 2005为开发者提供了丰富的控件和新的设计理念,是网络系统应用开发的有效工具,但目前VS .NET下关于系统设计框架结构的讨论较少,这方面的解决方案的实现方法还不是很多。为解决这一问题,笔者想从系统解决方案的框架入手,按MVC模式分层的思想来设计,在分析比较.NET各种解决方案的基础上,构建了一种通用性较好的三层企业级解决方案。为提高解决方案的实现效率,利用现有的代码生成工具完成一些重复性的编码工作,比较了目前流行的各种代码生成工具,发现CodeSmith的功能比较全面,其使用的语法与ASP.NET非常相似,便于开发者学习和使用,因此选择CodeSmith作为生成工具。在CodeSmith工具中已有很多可利用的代码模板,本系统的设计中借鉴NHibernate生成模板,并对它进行了改进。原来的模块只能根据数据库来生成NHibernate的映射文件和类文件,改进后可以生成模型层、领域层,页面层所有的文件,也包括了项目工程文件(*.sln文件和*.csproj文件),从而实现了由数据库到解决方案的代码自动生成功能。

笔者的设计是一种初步的尝试,希望能在软件设计模式的应用上进行一些研究,形成可操作的使用方法,以减少开发者的编程工作量,提高编程的效率,希望本文的方法能起到抛砖引玉的作用。

二、数据库设计

系统总体设计思路是自下而上的,根据系统的功能需求,先开始数据库设计,然后进行系统编码。本系统管理考虑的功能有部门管理、用户管理、角色管理、模块管理和系统日志等几个部分组成。系统共包括7张数据表,分别是用户信息表User、部门信息表Department、用户登录信息表UserLogin、角色信息表Roles、模块信息表Modules、用户角色关系表UserRole和角色模块关系表RoleModule,其数据关系如图1所示。数据库的设计还是基于用户的需求来考虑,首先建立了用户信息表,这是系统管理的基础,用户注册的信息存放于该表中。由于用户隶属于不同的部门,建立了部门信息表,这两者为一对多的数据关系,由于部门信息间也存在隶属关系,部门信息表自身也是一个一对多的数据关系表。系统通常是由若干功能模块组成,为实现对这些模块的管理功能,要定义一个模块信息表,记录模块的名称和页面地址等信息。为实现系统的权限分组管理,建立了角色信息表,它与模块信息表是多对多的数据关系,为方便设计,建立了角色与模块关系表,把这种多对多的数据关系转化为两个一对多的数据关系,以便于系统的设计。同样的道理,对用户与角色表的关系也一样,建立了用户角色关系表,形成两个一对多的数据关系。


 

 

1 系统管理数据库结构图

 

三、系统实现

1.系统解决方案

系统解决方案由5个工程项目组成,其解决方案组成如图2所示。其中BOSS.Core, BOSS.DataWeb工程为主要项目,ProjectBase.DataProjectBase.Utils工程为引用的基础项目。其中ProjectBase.Data为数据访问基础类工程,提供了基础的数据访问接口和数据访问方法。ProjectBase.Utils为数据基础工具类,主要是为系统提供数据报错、警告等功能。这两个工程项目的目的是提供一个基础平台。设计的重点是在三个主要项目上,Web层为页面层,负责系统页面的显示。BOSS.Core层为领域层,负责系统的核心业务。BOSS.Data层为数据访问层,负责数据库访问有关的功能。其中BOSS.Core层的设计最为关键,它由三个文件夹组成,DataInterfaces文件夹为数据访问接口文件,Domain文件夹中为NHibernate的映射文件和类文件,Entity文件夹中为业务实体对象文件。按领域层的设计理念,避免“贫血模型”的设计,建立实体对象,让它具有基本的数据访问操作和业务管理的功能。


2 系统解决方案组织图

    这五个项目间存在一定的依赖关系,下面以用户表功能设计为例来说明它们之间的关系。

领域层BOSS.Core中对用户表功能的定义有三处。文件夹DataInterfaces中的IUserDao.cs定义访问接口如下,该接口利用泛型技术来实现了通用的数据访问接口,接口IDao的具体定义位于ProjectBase.Data层。

public interface IUserDao  : IDao<User , int >

    {

    }

文件夹Domain中的User.cs定义如下,该类为模型类,类似于Java中的POJO文件,类DomainObject的具体定义位于BOSS.Core层。

 public partial class User :  DomainObject<int>

    {

        #region Member Variables

}

文件夹Domain中的映射文件User.hbm.xml定义如下所示,该文件为NHibernate的映射文件,这个与Hibernate中的使用方法基本一致。下面的代码说明了用户的主键标识为ID,它为整型,属性为数据库自动标识,另外,它有一个字符串的属性LoginName

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">

    <class name="BOSS.Core.Domain.User, BOSS.Core" table="`User`" lazy="false">

        <id name="ID" type="Int32" unsaved-value="null">

            <column name="UserID" length="4" sql-type="int" not-null="true" unique="true" index="PK_User"/>

            <generator class="native" /></id>

        <property name="LoginName" type="String">

            <column name="LoginName" length="50" sql-type="varchar" not-null="false"/>

       </property>

Entity文件夹的类文件UserEntity.cs中定义,该文件目的是实现User类的业务逻辑功能。为解决模型层的“贫血”问题,在实体类中利用了.NET 2005中的部分类(partial class)的技术,对模型层的类在这里进行补充定义,加上系统的业务管理功能。

public partial class User

    {

//Business Method

}

数据访问层BOSS.Data中对用户访问的定义如下,其中类AbstractNHibernateDao的具体定义位于ProjectBase.Data层。该类的实现原理与上面的IUserDao接口类似,利用泛型技术实现了通用的数据操作功能,具体的操作函数在抽象类AbstractNHibernateDao已经有了明确定义,包括基本的数据添加、修改和删除功能。

public class UserDao : AbstractNHibernateDao<User, int>, IUserDao

    {

public UserDao(string sessionFactoryConfigPath) : base(sessionFactoryConfigPath) { }

}

为系统使用该类的数据访问功能,需要对其进行初始化,系统设计中对数据访问层采用了DAO方式,使用工厂模式来进行设计,在工厂类中定义如下:

public IUserDao GetUserDao()

    {

        return new UserDao(sessionFactoryConfigPath);

}// sessionFactoryConfigPath为类工厂的配置文件路径

Web层使用该类功能代码示例如下:

User entity = new User();//创建领域模型

        Department parent = new Department();

        parent.DepartmentDao = DaoFactory.GetDepartmentDao();

//依赖注入,体现IOC的思想, DaoFactoryDAO工厂类,具体配置在CASTLE会有说明

        entity.UserDao = DaoFactory.GetUserDao();

        entity.LoginName = dataLoginName.Text.Trim();

        entity.Password = dataPassword.Text.Trim();

        entity.ActualName = dataActualName.Text.Trim();

        entity.Address = dataAddress.Text.Trim();

        entity.MobilePhone = dataMobilePhone.Text.Trim();

        entity.OfficePhone = dataOfficePhone.Text.Trim();

        entity.PostNumber = dataPostNumber.Text.Trim();

        entity.Department = parent.GetById(int.Parse(dataDepartmentID.SelectedValue),false);

        entity.CreateTime = DateTime.Now;

        entity.State = 0;

        if (entity.Save() != null)

        {

            lbinfo.Text = "添加用户信息成功";

        }

2.关键技术

系统主要应用了CodeSmith代码生成工具, NHibernate技术和Castle技术。在实现部门管理中,还使用AJAX技术来实现无页面刷新的部门树结构,在此,对AJAX技术不作深入的讨论,具体实现方法参考代码实例。

1CodeSmith代码生成工具

CodeSmith是一个基于模板的代码生成器免费软件,目前笔者使用的版本为4.0。在程序开发中使用它自动生成代码,避免大量的重复代码的编写。CodeSmith可以生成任何基于ASCII的编程语言代码,它的语法与ASP.NET几乎相同。如果熟悉ASP.NET ,那么应该会很快理解模板语法,并且模板语法支持C#VB.NETJScript.NET等语言。CodeSmith带有不少优秀的模板,包括所有.NET集合类型的模板以及生成存储过程的模板等,但它真正强大的功能在于允许用户创建和定制模板,只要你掌握了CodeSmith的语法,定制了合适的开发模板,你也许会难以相信自己能制造如此神奇的工具,这也是CodeSmith最受人推崇的地方。 CodeSmith提供强大的数据库支持功能,利用它可以方便地访问到数据库的表对象、表间关系及存储过程对象等,这为我们代码生成功能提供了很好的条件。

下面的代码说明如何来实现让用户选择要操作的数据库,并得到该数据库中的所有数据表对象。

private DatabaseSchema _sourceDatabase;

[Category("Database")]

    [Description("Database that the mapping file should be based on.")]

    public DatabaseSchema SourceDatabase {

        get { return _sourceDatabase; }

        set { _sourceDatabase = value; }

    }

//上面的代码是定义一个数据库连接,这样,在模板生成后会提示用户要选择需要操作的数据库。

foreach(TableSchema sourceTable in SourceDatabase.Tables)

        {

            //遍历数据库中的所有的表对象

            if (IsManyToManyTable(sourceTable))

            {

                //判断是否是多对多的表

            }

2NHibernate技术

NHibernate是一个面向.Net环境的对象/关系数据库映射工具。它采用了对象/关系数据库映射(object/relational mapping (ORM))技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。本文中使用的版本为1.2,支持.NET 2.0框架。使用NHibernate包括以下几个步骤:

NHibernate的基本配置,首先在.NET下添加NHibernate的引用,然后修改它的配置文件,包括连接数据提供者、连接数据驱动类、连接数据方言、数据库字符串等,本文用到的配置文件NHibernate.config如下所示。

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >

  <session-factory name="EPZLDB">

    <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>

    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>

    <property name="connection.connection_string">

      Data Source=ADMIN;Initial Catalog=XTGLDB;Connect Timeout=30;user id=sa;

      pwd=</property>

    <property name="connection.isolation">ReadCommitted</property>

    <property name="default_schema">XTGLDB.dbo</property>

    <!-- HBM Mapping Files -->

    <mapping assembly="BOSS.Core" />

  </session-factory>

</hibernate-configuration>

持久化的.Net类与映射XML文件的生成。持久化类文件类似于JavaPOJO文件,XML则负责完成对象与数据库之间的映射功能。NHibernate提供了由XML文件生成持久化类和数据库结构等功能,目前还不支持由数据库生成XML文件,只能利用工具来完成自动生成的功能。代码生成器CodeSmith已提供了NHibernate的生成模板,该模板能由数据库直接生成这两种文件。

使用NHibernateAPI来编程。利用NHibernate提供的数据访问功能,通常情况下为便于设计,将提供的数据访问功能建立基础类,在其他业务对象使用它时,再调用这些基础类函数,没必要对每个业务对象把这些功能都再写一次。使用泛型技术有效地实现Nhibernate访问接口的封装。

3Castle技术

Castle是针对.NET平台的一个开源项目,从数据访问框架ORMIOC容器,再到Web层的MVC框架、AOP,基本包括了整个开发过程中的所有内容,为快速的构建企业级的应用程序提供了很好的服务。WindsorCastle 的一个IOC容器。它构建于MicroKernel之上,功能非常之强大,能检测类并了解使用这些类时需要何种参数,检测类型和类型之间工作依赖性,并提供服务或者发生错误时提供预警的机制。使用Windsor的步骤如下:

第一步:注册一个Windsor容器。

public void Application_Start(object sender, EventArgs e) {

            // Initialize log4net

            XmlConfigurator.Configure();

            // Create the Windsor Container for IoC.

            windsorContainer = new WindsorContainer(new XmlInterpreter());

        }

第二步:向容器中注册服务。所谓服务,就是指我们要用到的组件类的接口,其具体的配置文件CastleComponents.config如下所示。

<?xml version="1.0"?>

<configuration>

  <components>

    <component id="primaryDaoFactory"

               type="BOSS.Data.NHibernateDaoFactory, BOSS.Data"

               service="BOSS.Core.DataInterfaces.IDaoFactory, BOSS.Core">

      <parameters>

        <sessionFactoryConfigPath>F:\编程论文\工程文件\Web\Config\NHibernate.config</sessionFactoryConfigPath>

      </parameters>

    </component>

  </components>

</configuration>

上面的代码完成BOSS.Data中的工厂类NHibernateDaoFactory的注册。

第三步:在页面层中使用该注册服务,代码如下:

public IDaoFactory DaoFactory {

            get {

 return (IDaoFactory) CustomHttpApplication.WindsorContainer[typeof(IDaoFactory)];

            }

这样,调用页面基础类的DaoFactory属性就可以得到工厂类,可以在页面中直接利用它对所有的DAO数据访问类进行调用。

四、结语

本文分析了网站系统管理的业务需求,并以此作为实例,研究其解决方案的组成,形成基于MVC的框架设计结构。从数据库设计入手,利用CodeSmith自动生成了解决方案的分层框架结构,并在VS .NET 2005下按MVC模式进行了功能实现。本文涉及到目前.NET研究最新的技术和工具,形成了一种比较高效的开发模式,具有较好的操作性,大大提高了开发效率。

 

 

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089