摘要:最近幾天有時間看了一下Castle,原來它的功能是如此的強大,從數據訪問框架到IOC容器,再到WEB框架,基本包括了整個開發過程中的所有東西,看來得好好學習研究一下了,並且打算把自己學習過程的一些東西記錄下來。先從ActiveRecord開始吧,ActiveRecord提供的簡潔的O/R映射給我留下了很深的印象,本文將通過一個簡單對象的CRUD操作來帶你快速走進Castle ActiveRecord。
主要內容
1.概述
2.准備相關的數據表
3.編寫User實體類
4.構建配置信息
5.開始CRUD操作
6.使用ActiveRecord Generator生成實體類代碼
一.概述
如果你用過NHibernate,一定會對在NHibernate中編寫.hbm.xml文件印象深刻,我也是。而在Castle ActiveRecord中,我們不用再為編寫繁冗復雜的映射文件而頭疼,ActiveRecord是Castle中提供的一個數據訪問框架,它在底層封裝了NHibernate的操作,使用特性來代替映射文件,它提供的簡潔的O/R映射會讓你驚歎原來實現持久化數據層是那麼簡單。下面我們通過一個簡單對象的CRUD操作來快速進入Castle ActiveRecord。
二.准備相關的數據表
假定數據庫中有這樣一張用戶表,用來保存用戶的信息,如下
CREATE TABLE [dbo].[Users] (
[LogonID] [int] IDENTITY (1, 1) NOT NULL ,
[LogonName] [varchar] (40) COLLATE Chinese_PRC_CI_AS NULL ,
[Password] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,
[EmailAddress] [varchar] (40) COLLATE Chinese_PRC_CI_AS NULL ,
[LastLogon] [datetime] NULL
) ON [PRIMARY]
GO
三.編寫User實體類
首先我們新建一個User類並讓它繼承於ActiveRecordBase類
public class User : ActiveRecordBase
{
//
}
為User類添加特性,其實就是告訴ActiveRecord,User類所對應的數據庫中的數據表名為Users
[ActiveRecord("Users")]
public class User : ActiveRecordBase
{
//
}
下面我們的工作就是為實體類添加屬性
[ActiveRecord("Users")]
public class User : ActiveRecordBase
{
private int _id;
private string _name;
private string _password;
private string _emailAddress;
private DateTime _lastLogon;
[PrimaryKey(PrimaryKeyType.Identity, "LogonID")]
public int Id
{
get { return _id; }
set { _id = value; }
}
[Property("LogonName")]
public string Name
{
get { return _name; }
set { _name = value; }
}
[Property("Password")]
public string Password
{
get { return _password; }
set { _password = value; }
}
[Property("EmailAddress")]
public string Address
{
get { return _emailAddress; }
set { _emailAddress = value; }
}
[Property("LastLogon")]
public DateTime LastLogon
{
get { return _lastLogon; }
set {_lastLogon = value; }
}
}
大家可能注意到了,每一個屬性上面都加上了特性[Property()]。簡單的說明一下,這裡用[PrimaryKey]特性指定Id作為主鍵,並且說明了主鍵的類型為自增型的,用PrimaryKeyType.Identity來說明,在後續文章中我會詳細說明的。如果屬性名和字段名一致,[Property()]中可以為空,也可以寫上字段的名字。
下一步我們為實體類根據需要加上靜態的操作方法,至於Create(),Update(),Delete(),Save()等方法則會直接從ActiveRecordBase基類中繼承
[ActiveRecord("Users")]
public class User : ActiveRecordBase
{
//……
public static void DeleteAll()
{
DeleteAll( typeof(User) );
}
public static IList FindAll()
{
return (IList) FindAll( typeof(User) );
}
public static User Find(int id)
{
return (User) FindByPrimaryKey( typeof(User), id );
}
}
整個完成後的實體類代碼
using System;
using System.Collections;
using Castle.ActiveRecord;
namespace ARDemo
{
/**//// <summary>
/// User 的摘要說明。
/// </summary>
[ActiveRecord("Users")]
public class User : ActiveRecordBase
{
private int _id;
private string _name;
private string _password;
private string _emailAddress;
private DateTime _lastLogon;
[PrimaryKey(PrimaryKeyType.Identity, "LogonID")]
public int Id
{
get { return _id; }
set { _id = value; }
}
[Property("LogonName")]
public string Name
{
get { return _name; }
set { _name = value; }
}
[Property("Password")]
public string Password
{
get { return _password; }
set { _password = value; }
}
[Property("EmailAddress")]
public string Address
{
get { return _emailAddress; }
set { _emailAddress = value; }
}
[Property("LastLogon")]
public DateTime LastLogon
{
get { return _lastLogon; }
set {_lastLogon = value; }
}
public static void DeleteAll()
{
DeleteAll( typeof(User) );
}
public static IList FindAll()
{
return (IList) FindAll( typeof(User) );
}
public static User Find(int id)
{
return (User) FindByPrimaryKey( typeof(User), id );
}
}
}
四.構建配置信息
現在我們要告訴ActiveRecord相關的數據庫、數據驅動等信息,最簡單的就是使用配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="activerecord" type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord" />
</configSections>
<activerecord>
<config>
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<add key="hibernate.connection.connection_string" value="UID=sa;Password=sa;Initial Catalog=ARDemo;Data Source=." />
</config>
</activerecord>
</configuration>
用過NHibernate的朋友一定會對這段配置代碼很熟悉,沒錯,因為ActiveRecord在底層封裝了NHibernate,所以這裡的配置跟使用NHibernate時的配置一樣,同樣是指定了數據源驅動,連接字符串等信息。如果使用了配置文件在代碼中只要這樣去初始化就可以了
IConfigurationSource source = System.Configuration.ConfigurationSettings.GetConfig("activerecord") as IConfigurationSource;
ActiveRecordStarter.Initialize( source, typeof(User) );
我們也可以不使用配置文件,而使用代碼指定的方式,但是由於這種方式相當於硬編碼了,不大推薦大家使用這種方式:
InPlaceConfigurationSource source = new InPlaceConfigurationSource();
Hashtable properties = new Hashtable();
properties.Add("hibernate.connection.driver_class", "NHibernate.Driver.SqlClientDriver");
properties.Add("hibernate.dialect", "NHibernate.Dialect.MsSql2000Dialect");
properties.Add("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider");
properties.Add("hibernate.connection.connection_string", "UID=sa;Password=19811218;Initial Catalog=ARDemo;Data Source=.");
source.Add( typeof(ActiveRecordBase), properties );
ActiveRecordStarter.Initialize( source, typeof(User) );
五.開始CRUD操作
好了,經過了前面的步驟之後,就可以正式開始我們的對象CRUD操作了。
1.增加User對象
[Test]
public void AddUser()
{
User user = new User();
user.Name = "Terrylee";
user.Password = "aaa";
user.Address = "[email protected]";
user.LastLogon = DateTime.Now;
user.Create();
}
是不是非常簡單?我們甚至都沒有寫過Create()方法,它直接從ActiveRecordBase類繼承。我們所做的只是創建這樣一個User對象,然後調用它的方法就可以了。
2.查詢所有的User對象
[Test]
public void FildAll()
{
IList list = User.FindAll();
Assert.IsNotNull(list);
int actual = list.Count;
int expected = 2;
Assert.AreEqual(expected,actual);
}
3.查詢某一個指定Id的User對象
[Test]
public void Fild()
{
int id = 5;
User actual = User.Find(id);
Assert.IsNotNull(actual);
Assert.AreEqual("Terrylee",actual.Name);
Assert.AreEqual("aaa",actual.Password);
}
4.修改User對象
[Test]
public void UpdateUser()
{
User user = new User();
user.Id = 5;
user.Name = "Aero";
user.Password = "aaa";
user.Address = "[email protected]";
user.LastLogon = DateTime.Now;
user.Update();
}
5.刪除User對象
[Test]
public void DeleteUser()
{
User user = new User();
user.Id = 7;
user.Delete();
}
6.刪除所有的User對象
[Test]
public void DeleteAll()
{
User.DeleteAll();
}
可以看到,整個過程非常的簡潔簡單,沒有一點多余復雜的代碼,相信你已經開始體會到了ActiveRecord的魅力了。唯一有一點你會感到不舒服的是已經有了數據庫表還需要手工編寫實體類代碼,這個不用擔心,ActiveRecord已經為我們提供了代碼生成工具ActiveRecord Generator。
六.使用ActiveRecord Generator生成實體類代碼
1.執行Castle.ActiveRecord.Generator.exe,位於目錄C:\Program Files\Castle\Bin\net-1.1\下面,可以看到如下界面,選擇Project Explorer面板
2.點擊“Add DataBase Connection”圖標,如下圖中紅色方框所示,彈出設置連接字符串對話框,我們首先要為數據庫起一個別名,這個名字可以跟數據庫名不一樣,在後面我們會用到
注意:如果連接數據庫為SQL Server2000數據庫,必須在彈出的對話框中選中允許保存密碼選項,否則點擊OK按鈕時會報登錄失敗的錯誤!這點不知道是不是我機器的設置問題,如果有朋友遇到這樣的錯誤,不妨一試。
3.點擊OK後,選擇ActiveRecord Components面板
4.拖動ActiveRecord到左邊的空白區域,會出現如下界面,選擇我們剛才設置的數據庫別名
5.此後操作有選擇子段,設置類名等,全部完成後界面如下:
6.選擇Project菜單下的Generate Code,輸入命名空間,文件設置路徑,並選擇所要生成代碼語言
注意:有一個選項是否覆蓋已經存在的文件,可以根據自己的實際情況選擇
7.最後生成的完整實體類代碼如下
//
// Generated by ActiveRecord Generator
//
//
namespace ARDemo
{
using Castle.ActiveRecord;
[ActiveRecord("Users")]
public class User : ActiveRecordBase
{
private int _logonID;
private string _logonName;
private string _password;
private string _emailAddress;
private System.DateTime _lastLogon;
[PrimaryKey(PrimaryKeyType.Native)]
public int LogonID
{
get
{
return this._logonID;
}
set
{
this._logonID = value;
}
}
[Property()]
public string LogonName
{
get
{
return this._logonName;
}
set
{
this._logonName = value;
}
}
[Property()]
public string Password
{
get
{
return this._password;
}
set
{
this._password = value;
}
}
[Property()]
public string EmailAddress
{
get
{
return this._emailAddress;
}
set
{
this._emailAddress = value;
}
}
[Property()]
public System.DateTime LastLogon
{
get
{
return this._lastLogon;
}
set
{
this._lastLogon = value;
}
}
public static void DeleteAll()
{
ActiveRecordBase.DeleteAll(typeof(User));
}
public static User[] FindAll()
{
return ((User[])(ActiveRecordBase.FindAll(typeof(User))));
}
}
}
大家還應該注意的一點是生成One-Many/Many-One等關系的實體類文件時可能會出現一些問題,需要對生成的代碼手工改動。最後希望和研究Castle的朋友能夠多多交流!
參考資料
Castle的官方網站http://www.castleproject.org