用反射和特性实现面向对象的数据持久方法 [无常译]

过去我是使用J2EE开发的,并且对OOD很狂热,几个月前开始使用.NET。现在我知道了在.NET下实现数据持久途径,在操作一个表中多个记录的时候,我认为ADO.net中的DataSets、DataReaders、DataAdapters是非常强大的,但我现在在设计中仍然使用Business Objects ,所以我写了一个小型基于.NET的持久层框架。

在过去使用JDO的时候,我会考虑为每个BO创建映射到数据中表的一个XML格式描述,但是我想到一个更好的方法,那就是使用.NET中的Attributes。我以前在网上看到一篇介绍如何使用attributes的文章使我有了这个打算。

User BO:

ContractedBlock.gif ExpandedBlockStart.gif User BO
 1 public class User
 2 {
 3    public User(){}
 4    private long _id;
 5    private string _name;
 6    private string _username;
 7    private string _password;
 8 
 9    //for each of these fields we have a Property
10    public long UserID {
11       set{_id = value;}
12       get {return _id;}
13    }
14 
15    //etc 
16    …     
17 }

现在把它映射到数据库中:

ContractedBlock.gif ExpandedBlockStart.gif User
 1 [DBTable("Users","dbo")]
 2 [Serializable]
 3 public class User
 4 {
 5     public User(){}
 6     private long _id;
 7     private string _name;
 8     private string _username;
 9     private string _password;
10 
11     [DBPrimaryKeyField("ID_User",DbType.Int16)]
12     [DBColumn("ID_User",DbType.Int16,false)]
13     public long UserID 
14     {
15         set{_id = value;}
16         get {return _id;}
17     }
18 
19     [DBColumn("Name",DbType.String,true)]
20     public string Name
21     {
22         //set, get
23     }
24 
25     [DBColumn("Username",DbType.String,false)]
26     public string Username
27     {
28         //set, get
29     }
30 
31     [DBColumn("Password",DbType.String,false)]
32     public string Password
33     {
34         //set, get
35     }
36 }
37 

有3个特性类DBTable, DBPrimaryKey, DBColumn.。下面看看它们各自的功能。

DBTable( string  tableName,  string  databaseOwner) 

建立BO到数据表的映射

DBPrimaryKey( string  pkFieldName, DBType pkFieldType,  bool  isAutoIncrement) 

建立表中主键到BO属性的映射

DBColumn( string  tableFieldName, DBType fieldType,  bool  allowsNulls) 

建立表中字段到BO属性的映射

现在来看一下BO的功能。这里用到一个接口IPersistenceService 。

ContractedBlock.gif ExpandedBlockStart.gif interface IPersistenceService
public interface IPersistenceService 
{
    
object Create(Object o, Type objectType);
    
void Update(Object o, Type objectType);
    
void Delete(Object id, Type objectType);
    
int Count(string condition, Type objectType);
    Object GetObject(Object id, Type objectType);
    
void LoadDataSet(DataSet dataSet, String sqlQuery);
    
void LoadDataSet(DataSet dataSet, String sqlQuery, String tableName);
    
object Create(SqlConnection con, Object o, Type objectType);
    
void Update(SqlConnection con,Object o, Type objectType);
    
void Delete(SqlConnection con,Object id, Type objectType);
    
int Count(SqlConnection con,string condition, Type objectType);
    Object GetObject(SqlConnection con,Object id, Type objectType);
    
void LoadDataSet(SqlConnection con,DataSet dataSet, String sqlQuery);
    
void LoadDataSet(SqlConnection con,DataSet dataSet, String sqlQuery,
                     String tableName);
    SqlConnection GetConnection();
    
void CloseConnection(SqlConnection con);
}

我们拥有一个取得实现这个接口的工厂。在这个例子中,有一个依赖说SQL Server 的实现PersistenceServiceImpl。我们来看一下这个实现:

String connectionString  =  “…”;
IPersistenceService ps 
=  PersistenceServiceFactory

现在来创建一个User并且将其持久化。

User u  =   new  User();
u.Name 
=   " Dan Bunea " ;
u.Password 
=   " myusername " ;
u.Password 
=   " mypassword " ;
// obtain id for the new user in the 
long  id  =  ( long )ps.Create(u, typeof (User));

或者仅需要这样:(如果你不需要获得对象的ID)

ps.Create(u, typeof (User));

现在Users表里有了一个用户,把它取出来。

User U2  =  (User)ps.GetObject(id, typeof (User));

更新并且保存。

U2.Name  =   " Dan Bunea Updates " ;
U2.Password 
=   " newusername " ;
U2.Password 
=   " newpassword " ;
P2s.Update(U2,
typeof (User));

是不是很简单?现在来把它删除。

Ps.Delete(id, typeof (User));

如果你有多个操作都使用相同的连接时,我也加入了一些可以很容易的加载DataSet对象的方法。我来说一下要使这些操作都用一个相同连接的方法:

ContractedBlock.gif ExpandedBlockStart.gif Same Connection
SqlConnection con = ps.GetConnection();
User u 
= new User();
u.Name 
= "Dan Bunea";
u.Password 
= "myusername";
u.Password 
= "mypassword";
object id = (long)ps.Create(con,u,typeof(User));
User U2 
= (User)ps.GetObject(con,id,typeof(User));
U2.Name 
= "Dan Bunea Updates";
U2.Password 
= "newusername";
U2.Password 
= "newpassword";
P2s.Update(con,U2,
typeof(User));
Ps.Delete(con,id,
typeof(User));
ps.CloseConnection(con);

说一下性能的问题。用户不需要要关心每个BO有关INSERT, UPDATE, DELETE 和 SELECT(使用主键)的操作,使用对象中指定的特性自动生成这些操作的代码。每个对象的每段代码只需要生成一次,可以使用它们对应的参数来调用。下一次执行相同的操作时,就可以从缓存中获取查询对象,使用反射给每个参数赋值,然后再执行。

特别感谢:.....

原文地址:http://www.codeproject.com/dotnet/persistence_by_reflection.asp

第一次翻译,不好的地方请见谅。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值