持久数据层框架设计
 

2009-06-08 作者:架构人生 来源:架构人生的blog

 

前言:

持久数据层框架是我在研究NHibernate后,受它的启发做的一次创新。当前版本支持多数据库,O/R Mapping等,同时与NHibernate相比,它是一个轻量级框架,在学习和应用上显得更加简单。以下是我的初稿,第一次将我的研究成果展现出来,有不对的地方或更好的建议,欢迎点评。

1.     以下是数据层调用接口: 

        int CreateDbTable(object objTable); 
        
bool IsExistTable(string tableName); 
        
int ExcuteSql(string sql); 
        
int Insert(string tableName, Hashtable values); 
        
int Update(string tableName, Hashtable values, string wher); 
        DataTable Query4DataTable(
object obj); 
        
string Query4Value(string sql); 
        
string Query4Value(string sql, int columnIndex); 
        
int GetCount(string sql); 
        
void BeginTransaction(); 
        
void Commit(); 
        
void Rollback(); 
        List<ValueText> Query4VtObject(
string sql); 
        DataSet Query4DataSet(
object obj); 
        IResultSet Query4ResultSet(
string sql); 
        Hashtable Query4Hashtable(
string sql); 
        DataRow Query4DataRow(
string strSql); 
        IDataReader Query4DataReader(
string strSql);      
        
int Insert(object ormTable); 
        
int Update(object ormTable); 
        
int Delete(object ormTable); 
        
bool Delete(string tableName); 

 2.     以下是数据层调用入口:

 1         /// <summary> 
 2
         /// Default Handler Operator for any database 
 3         /// </summary> 
 4
         public static IDbOperator DefaultDbOperator() 
 
5         { 
 
6             //get instance by db interface, such as SQL Server, Access, MYSQL, 
 7             Instance instance = new Instance(); 
 
8             object objDb = instance.GetInstance(); 
 
9             IDbOperator db = objDb as IDbOperator; 
10             if (db == null
11             { 
12                 throw new NotSuportedDbException(); 
                   
//need to write a library to support this database
13             } 
14             return db; 
15         }

在调用数据时,只需要使用

IDbOperator db=DbFactory.DefaultDbOperator(); 

3.     数据层后台配置:

从下面的配置,大家就应该可以看出,持久数据层框架支持任何类型的数据库。 

  <Data DbType="SQLServer"> 
     
<SQLServer type="Zivsoft.Data.SQLServerDbOperator;SQLServer"> 
      
<add key="ConnectionString" value="…"/> 
      
<add key="AutoCreateTable" value="true"/> 
            
<add key="AutoCreateDb" value="false"/> 
     
</SQLServer>
     
<MySQL type="Zivsoft.Data.MySQLDbOperator;MySQL"> 
           
<add key="ConnectionString" value="…"/> 
           
<add key="AutoCreateTable" value="true"/> 
            
<add key="AutoCreateDb" value="false"/> 
     
</MySQL>
  
</Data> 

4. 持久数据层对ORM支持

NHibernate中,每一个实体类都对应一个XML文件,个人看来有些复杂,因此,在此框架中,做了创新:

以下是自动生成的UserInfo.cs文件实体类完整代码:

using System; 
using System.Data; 
/**************************************************** 
 * 
 * Automatically Created by Zivsoft.Data.ORM.Setup 
 * 
 *****************************************************/
 
namespace Zivsoft.Data.ORM.Table 

      
public class UserInfo:OrmTable 
       { 
        
#region UserId 
        [PrimaryKey(
"UserId",DbType.String)] 
        
public ColumnValue<string> UserId{ 
            
get
                 
return new ColumnValue<string> { Name = "UserId", Value = GetString("UserId");
            } 
            
set
                Fields[
"UserId"]=value.Value; 
            } 
        } 
        
#endregion 
        
#region Password 
        [Column(
"Password",DbType.String)] 
        
public ColumnValue<string> Password{ 
         
get
                  
return new ColumnValue<string> {Name = "Password", Value = GetString("Password")}; 
        } 
        
set
              Fields[
"Password"]=value.Value; 
        } 
     } 
        
#endregion 

        
#region LoginTime 
        [Column(
"LoginTime",DbType.DateTime)] 
        
public ColumnValue<DateTime?> LoginTime{ 
           
get
                  
return new ColumnValue<DateTime?> { 
                       Name = 
"LoginTime", Value = GetDateTime("LoginTime"
                  }; 
            } 
           
set
               Fields[
"LoginTime"]=value.Value; 
            } 
        } 
        
#endregion 
    } 
}
 

通过以上实体类,可以看出只有得到这个类,对应数据库表所有字段、类型、表名信息全部可以得到。

比如,得到表名的信息:

                            var name=new UserInfo().GetName();

            得到字段UserId的对应数据库名称:

                             var name=new UserInfo().UserId.Name;

            另外,所有实体类,都可以通过框架自制工具根据数据库生成实体类代码。

5.     框架内嵌数据组件

由于持久数据层对业务无关,因此开发了一个内嵌数据组件。此组件在使用时只需要对其配置,便可显示所需要数据,包括修改、删除、添加等操作。

在之前发布了一篇《持久数据层框架设计(一)》后,有不少人关注,如今,总算Release一个稍微完整的测试版出来,提供DLL,并附配置说明。欢迎体验并提出宝贵的建议。

下面将配置文件以例子形式整理如下:

1. 在App.config或Web.config里配置

<configSections>
    
<section name="Data" type="Zivsoft.Data.ConfigHandler,Zivsoft.Data,Version=3.5.3295.29087,Culture=neutral, PublicKeyToken=3266f10ce3531d0e"/>
</configSections>
<Data DbType="SQLServer">
    
<Access type="Zivsoft.Data.Access.AccessDbOperator;Zivsoft.Data.Access,Version=3.5.3295.29087,Culture=neutral, PublicKeyToken=3266f10ce3531d0e">
      
<add key="ConnectionString" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=~\Db\SOAWeb.mdb"/>
      
<add key="AutoCreateTable" value="false"/>
      
<add key="AutoCreateDb" value="true"/>
    
</Access>
    
<SQLServer type="Zivsoft.Data.SQLServer.SqlServerDbOperator;Zivsoft.Data.SQLServer,Version=1.0.3295.29087,Culture=neutral, PublicKeyToken=3266f10ce3531d0e">
      
<add key="ConnectionString" value="Data Source=Lihua-PC\SQLEXPRESS;Initial Catalog=Sample;Integrated Security=True;Pooling=False"/>
      
<add key="AutoCreateTable" value="true"/>
      
<add key="AutoCreateDb" value="true"/>
    
</SQLServer>
    
<MySQL type="Zivsoft.Data.MySQL.MYSqlDbOperator;Zivsoft.Data.MYSQL,Version=1.0.3295.29087,Culture=neutral, PublicKeyToken=3266f10ce3531d0e">
      
<add key="ConnectionString" value="……"/>
      
<add key="AutoCreateTable" value="true"/>
      
<add key="AutoCreateDb" value="false"/>
    
</MySQL>
</Data>

2. 单独文件中配置

如果在单独文件配置,你需要一个新建Data.xml文件在当前目录,或在App_Data目录里。格式如下:

<?xml version="1.0" encoding="utf-8" ?>
<Config> 
  
<!--my area-->
  
<Data DbType="Access">
    
<Access type="Zivsoft.Data.Access.AccessDbOperator;Zivsoft.Data.Access,Version=1.0.3295.29087,Culture=neutral, PublicKeyToken=3266f10ce3531d0e">
      
<add key="ConnectionString" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Db\SOAWeb.mdb"/>
      
<add key="AutoCreateTable" value="false"/>
      
<add key="AutoCreateDb" value="true"/>
    
</Access>
    
<SQLServer type="Zivsoft.Data.SQLServer.SqlServerDbOperator;Zivsoft.Data.SQLServer,Version=1.0.3295.29087,Culture=neutral, PublicKeyToken=3266f10ce3531d0e">
      
<add key="ConnectionString" value="Data Source=Lihua-PC\SQLEXPRESS;Initial Catalog=Sample;Integrated Security=True;Pooling=False"/>
      
<add key="AutoCreateTable" value="true"/>
      
<add key="AutoCreateDb" value="true"/>
    
</SQLServer>
  
</Data>
  
<Localization loc="en-us">
    
<en-us>App_Data\Localization\ResourceEn.xml</en-us>
    
<zh-cn>App_Data\Localization\ResourceCn.xml</zh-cn>
    
<zh-tw>App_Data\Localization\ResourceTw.xml</zh-tw>
    
<jp-wh>App_Data\Localization\ResourceJp.xml</jp-wh>
    
<ko-kr>App_Data\Localization\ResourceKo.xml</ko-kr>
    
<es-mx>App_Data\Localization\ResourceEs.xml</es-mx>
  
</Localization>
  
<Log level="DEBUG">
    
<LogFile>App_Data\log.log</LogFile>
  
</Log>
</Config>

3. 配置主要以上两大类。另外需要提一下GAC。

由于程序集都是强命名,你可以将DLL都丢到GAC里面,但注意配置里必须指定完整的信息如下:

<Access type="Zivsoft.Data.Access.AccessDbOperator;Zivsoft.Data.Access,Version=1.0.3295.29087,Culture=neutral, PublicKeyToken=3266f10ce3531d0e">

如果不需要扔到GAC里,配置可以简化如下:

<Access type="Zivsoft.Data.Access.AccessDbOperator;Zivsoft.Data.Access">

4. 关于扩展。

由于程序集中Zivsoft.Data.dll含有所有数据操作、ORM等等接口,你可以继承IDbOperator来扩展对其它数据库的支持,如DB2, MySQL, Oracle等。目前我只做了常用的SQLServer和Access。

5. 如何自动生成实体Entity。

程序包里有一个Zivsoft.Data.ORM.Setup.dll,你可以执行里面的接口,指定数据库,自动生成zivsoft.Data.ORM.Entity.dll。


火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织