這篇文章討論如何在.net中實現3層架構,使用MS sqlserver2005數據庫存儲數據。在此,我在3層架構中實現一個小型的可複用的組件保存客戶數據。並提供添加,更新,查找客戶數據的功能。
什麼是3層架構?
3層架構是一種“客戶端-服務器”架構,在此架構中用戶接口,商業邏輯,數據保存以及數據訪問被設計爲獨立的模塊。主要有3個層面,第一層(表現層,GUI層),第二層(商業對象,商業邏輯層),第三層(數據訪問層)。這些層可以單獨開發,單獨測試。
爲什麼要把程序代碼分爲3層。把用戶接口層,商業邏輯層,數據訪問層分離有許多的優點。
在快速開發中重用商業邏輯組件,我們已經在系統中實現添加,更新,刪除,查找客戶數據的組件。這個組件已經開發並且測試通過,我們可以在其他要保存客戶數據的項目中使用這個組件。
系統比較容易遷移,商業邏輯層與數據訪問層是分離的,修改數據訪問層不會影響到商業邏輯層。系統如果從用SQL Server存儲數據遷移到用Oracle存儲數據,並不需要修改商業邏輯層組件和GUI組件
系統容易修改,假如在商業層有一個小小的修改,我們不需要在用戶的機器上重裝整個系統。我們只需要更新商業邏輯組件就可以了。
應用程序開發人員可以並行,獨立的開發單獨的層。
代碼
這個組件有3層,第一個層或者稱爲GUI層用aspx頁面實現,叫做defalt.aspx。第二層或者稱爲商業邏輯層,叫做BOEmployee,是Bussniess Object Employee的縮寫。最後是第三層或者稱爲數據層,叫做DAEmployee,是Data Access Employee的縮寫。
用戶接口層(表示層default.cs代碼)
下面是用戶接口成的一段代碼,我只選取了調用商業邏輯層的一部分代碼。
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{ }
}
protected void ButtonAdd_Click(object sender, EventArgs e)
{
BOEmployee employee = new BOEmployee();
employee.EmployeeId = TextBoxEmployeeID.Text;
employee.FirstName = TextBoxFirstName.Text;
employee.LastName = TextBoxLastName.Text;
employee.HomePhone = TextBoxHomePhone.Text;
employee.Address = TextBoxAddress.Text;
employee.Add();
}
protected void ButtonFind_Click(object sender, EventArgs e)
{
BOEmployee employee = new BOEmployee();
string str = TextBoxFind.Text;
DataSet ds = new DataSet();
ds=employee.Find(str);
foreach( DataRow row in ds.Tables[0].Rows)
{
TextBoxEmployeeID.Text = row["EmployeeID"].ToString();
TextBoxFirstName.Text = row["FirstName"].ToString();
TextBoxLastName.Text = row["LastName"].ToString();
TextBoxAddress.Text = row["Address"].ToString();
TextBoxHomePhone.Text=row["HomePhone"].ToString();
}
}
protected void ButtonUpdate_Click(object sender, EventArgs e)
{
BOEmployee employee = new BOEmployee();
employee.EmployeeId = TextBoxFind.Text;
employee.FirstName = TextBoxFirstName.Text;
employee.LastName = TextBoxLastName.Text;
employee.HomePhone = TextBoxHomePhone.Text;
employee.Address = TextBoxAddress.Text;
employee.Update();
}
}
商業邏輯層
下面是商業邏輯層的所有代碼,主要包括定義Employee對象的屬性。但這僅僅是個虛構的Employee對象,如果需要可以加入其他的屬性。商業邏輯層還包括添加,更新,查找,等方法。
商業邏輯層是一箇中間層,處於GUI層和數據訪問層中間。他有一個指向數據訪問層的引用 employee = new DAEmployee().而且還引用了System.Data名字空間。商業邏輯層使用DataSet返回數據給GUI層
以下是實現商業邏輯層的代碼:
/// <summary>
/// BOEmployee 的摘要說明
/// </summary>
namespace _3tierarchitecture
{
public class BOEmployee
{
public BOEmployee()
{
//
// TODO: 在此處添加構造函數邏輯
//An instance of the Data access layer!
employee = new DAEmployee();
}
//Employee property
private string firstName;
private string lastName;
private string homePhone;
private string address;
private DAEmployee employee;
//Employee Field
public string Address
{
get { return this.address; }
set
{
this.address = value;
if (this.address == "")
throw new Exception("please provide address");
}
}
public string HomePhone
{
get { return this.homePhone; }
set
{
this.homePhone = value;
if (this.homePhone == "")
throw new Exception("please provide homePhone");
}
}
private string employeeId;
public string EmployeeId
{
get { return this.employeeId; }
set
{
this.employeeId = value;
if (this.employeeId == "")
throw new Exception("please provide employeeid");
}
}
public string FirstName
{
get
{
return this.firstName;
}
set
{
this.firstName = value;
if (this.firstName == "")
throw new Exception("please provide firstname");
}
}
public string LastName
{
get { return this.lastName; }
set
{
this.lastName = value;
if (this.lastName == "")
throw new Exception("please provide lastname");
}
}
/// <SUMMARY>
/// Function Add new employee. Calls
/// the function in Data layer.
/// </SUMMARY>
public void Add()
{
employee.Add(this);
}
///<SUMMARY>
///Function Update new employee calls
///the function in data layer
///</SUMMARY>
public void Update()
{
employee.Update(this);
}
///<SUMMARY>
/// function in Data layer.
/// It returns the details of the customer using
/// customer ID via a Dataset to GUI tier.
/// </SUMMARY>
public DataSet Find(string str)
{
if (str == "")
throw new Exception("Please provide Employeeid");
DataSet ds = new DataSet();
ds=employee.Find(str);
return ds;
}
}
}
數據訪問層
數據層包括處理MS sqlserver 2005數據庫的細節。所有這些細節都是透明的,不會影響到商業邏輯層。數據訪問層有個指向商業邏輯層的引用BOEmployee employee。爲了應用方便並且支持其他數據庫。
/// <summary>
/// DACustomer 的摘要說明
/// </summary>
namespace _3tierarchitecture
{
public class DAEmployee
{
//數據庫連接
private SqlConnection myConnection=new SqlConnection(ConfigurationManager.ConnectionStrings["SqlConnectionString"].ConnectionString);
public DAEmployee()
{
//
// TODO: 在此處添加構造函數邏輯
//
}
private string strTable = "";
private string strFields = "";
private string strValues = "";
private string strInsert = "";
private const string thisTabel = "Employees";
private const string employeeId = "EmployeeID";
private const string lastName = "LastName";
private const string firstName = "FirstName";
private const string address = "Address";
private const string homePhone = "HomePhone";
//增記錄語句
private string BuildAddString(BOEmployee employee)
{
// these are the constants as
// set in the top of this module.
strTable = "Insert into " + thisTabel;
strFields = " (" + employeeId +
"," + firstName+
"," + lastName +
"," + address +
"," + homePhone + ")";
//these are the attributes of the
//customer business object.
strValues = " Values ( '" + employee.EmployeeId +
"' , '" + employee.FirstName +
"' , '" + employee.LastName +
"' , '" + employee.Address +
"' , '" + employee.HomePhone + "' )";
strInsert = strTable + strFields + strValues;
return strInsert;
}
/// <summary>
/// 增加一個數據記錄
/// </summary>
/// <param name="employee"></param>
public void Add(BOEmployee employee)
{
string str = BuildAddString(employee);
SqlCommand myCommand = new SqlCommand(str,myConnection);
ConOpen();
myCommand.ExecuteNonQuery();
ConClose();
}
///<summary>
///更新一個記錄
///</summary>
public void Update(BOEmployee employee)
{
//打開數據庫
string updateString = "update " + thisTabel + " set " + firstName + "='" + employee.FirstName + "'," + lastName + "='" + employee.LastName + "'," + address + "='" + employee.Address + "'," + homePhone + "='" + employee.HomePhone + "' where " +
employeeId + "='" + employee.EmployeeId+"'";
SqlCommand myCommand = new SqlCommand(updateString,myConnection);
ConOpen();
myCommand.ExecuteNonQuery();
//關閉數據庫
ConClose();
}
///<summary>
/// 查找一個記錄
///</summary>
public DataSet Find(string argStr)
{
DataSet ds = null;
string selectStr = "select * from " + thisTabel + " where employeeId= '" + argStr + "'";
//SqlCommand myCommand = new SqlCommand(selectStr,myConnection);
ds = new DataSet();
//打開數據庫
ConOpen();
SqlDataAdapter da = new SqlDataAdapter(selectStr,myConnection);
da.Fill(ds,thisTabel);
//關閉數據庫
ConClose();
return ds;
}
//打開數據庫連接
public void ConOpen()
{
myConnection.Open();
}
//關閉數據庫連接
public void ConClose()
{
myConnection.Close();
}
}
}