何為三層架構?通常意義上的三層架構就是將整個業務應用划分為:表現層(UI)、業務邏輯層(BLL)、數據訪問層(DAL)。區分層次的目的即為了“高內聚,低耦合”的思想。
- 表現層(UI):即展現給用戶的界面;
- 業務邏輯層(BLL):針對具體問題的操作,也可以說是對數據層的操作,對數據業務邏輯處理;
- 數據訪問層(DAL):該層所做事務直接操作數據庫,針對數據的增添、刪除、修改、查找等。
下面通過通過一個簡單的例子來描述三層架構:
需求
- 實現一個客戶信息管理界面(包括增加、修改、刪除)操作;
- 用戶sql—server作為數據庫
以下是成型界面,至於UI設計是否合理,望各位大神拍磚
UI層設計
設計器代碼:
<Grid> <DockPanel> <ToolBar DockPanel.Dock="Top" Height="30"> <Button Name="BtnAdd" Click="BtnAdd_Click" ToolTip="新增"> <Image Source="Image\add.ico"></Image> </Button> <Button Name="BtnEdit" Click="BtnEdit_Click" ToolTip="編輯"> <Image Source="Image\edit.ico"></Image> </Button> <Button Name="BtnDel" Click="BtnDel_Click" ToolTip="刪除"> <Image Source="Image\delete.ico"></Image> </Button> </ToolBar> <DataGrid Name="DataGrid1" DockPanel.Dock="Top" IsReadOnly="True" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="姓名" Binding="{Binding Name}"></DataGridTextColumn> <DataGridTextColumn Header="生日" Binding="{Binding BirthDay}"></DataGridTextColumn> <DataGridTextColumn Header="電話" Binding="{Binding TelNum}"></DataGridTextColumn> <DataGridTextColumn Header="地址" Binding="{Binding Address}"></DataGridTextColumn> <DataGridTextColumn Header="等級" Binding="{Binding Custlevel}"></DataGridTextColumn> </DataGrid.Columns> </DataGrid> </DockPanel> </Grid>
主要是通過設計器后台代碼,DataGrid控件綁定數據,代碼如下:
/// <summary> /// 初始化加載數據 /// </summary> private void LoadData() { DataGrid1.ItemsSource = CustomDAL.GetAll(); }
數據業務邏輯代碼如下:
/// <summary> /// 新增 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnAdd_Click(object sender, RoutedEventArgs e) { CustomEditUI editUI = new CustomEditUI(); editUI.isInsert = true; if (editUI.ShowDialog() == true) { LoadData(); } }
/// <summary> /// 編輯 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnEdit_Click(object sender, RoutedEventArgs e) { Custom customer = (Custom)DataGrid1.SelectedItem; if (customer == null) { MessageBox.Show("請選擇要編輯的行!"); return; } CustomEditUI editUI = new CustomEditUI(); //添加標識便於區分是編輯保存還是新增保存 editUI.isInsert = false; editUI.editId = customer.Id; if (editUI.ShowDialog() == true) { LoadData(); } }
/// <summary> /// 刪除 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnDel_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show("確認刪除此條數據?", "提醒", MessageBoxButton.YesNo) == MessageBoxResult.Yes) { Custom custom = DataGrid1.SelectedItem as Custom; if (custom != null) { if ((MessageBox.Show("確認要刪除此調數據", "提醒") == MessageBoxResult.OK)) { CustomDAL.Delete(custom.Id); LoadData(); } } else { MessageBox.Show("請選擇要刪除的數據", "提醒"); return; } } }
數據訪問層(DAL),代碼如下:

public class CustomDAL { /// <summary> /// 查詢數據總條數 /// </summary> /// <returns></returns> public static int GetCount() { return (int)SqlHelper.ExecuteScalar("select * from T_Custom"); } /// <summary> ///根據ID查詢數據 /// </summary> /// <param name="id"></param> /// <returns></returns> public static Custom GetByid(long id) { DataTable table = SqlHelper.ExecuteDataTable("select * from T_custom where id=@id", new SqlParameter("@id", id)); return ToCustom(table.Rows[0]); ; } /// <summary> /// 根據id刪除數據 /// </summary> /// <param name="id"></param> public static void Delete(long id) { SqlHelper.ExecuteNonQuery("delete from T_custom where id=@id", new SqlParameter("@id", id)); } /// <summary> /// 插入空值處理 /// </summary> /// <param name="value"></param> /// <returns></returns> public static object FromDBNull(object value) { if (value == null) { return DBNull.Value; } else { return value; } } /// <summary> /// 查詢空值處理 /// </summary> /// <param name="value"></param> /// <returns></returns> public static object ToDBNull(object value) { if (DBNull.Value == null) { return null; } else { return value; } } /// <summary> /// 新增數據 /// </summary> /// <param name="custom"></param> public static void InSert(Custom custom) { SqlHelper.ExecuteNonQuery(@"insert into T_Custom(Name,Birthday,Address,Telnum,Custlevel)values(@Name,@Birthday,@Address,@Telnum,@Custlevel)", new SqlParameter("@Name", custom.Name), new SqlParameter("@Birthday", FromDBNull(custom.BirthDay)), new SqlParameter("@Address", custom.Address), new SqlParameter("@Telnum", custom.TelNum), new SqlParameter("@Custlevel", custom.Custlevel)); } /// <summary> /// 更新數據 /// </summary> /// <param name="custom"></param> public static void UpDate(Custom custom) { SqlHelper.ExecuteNonQuery(@"update T_Custom set Name=@Name,Birthday=@Birthday,Address=@Address,Telnum=@Telnum,Custlevel=@Custlevel where id=@id", new SqlParameter("@Name", custom.Name), new SqlParameter("@Birthday", FromDBNull(custom.BirthDay)), new SqlParameter("@Address", custom.Address), new SqlParameter("@TelNum", custom.TelNum), new SqlParameter("@Custlevel", custom.Custlevel), new SqlParameter("@Id", custom.Id)); } /// <summary> /// 查詢所有數據 /// </summary> /// <returns></returns> public static List<Custom> GetAll() { DataTable table = SqlHelper.ExecuteDataTable("select * from T_custom"); List<Custom> lst = new List<Custom>(); for (int i = 0; i < table.Rows.Count; i++) { lst.Add(ToCustom(table.Rows[i])); } return lst; } /// <summary> /// 影射關系賦值 /// </summary> /// <param name="row"></param> /// <returns></returns> public static Custom ToCustom(DataRow row) { Custom custom = new Custom(); custom.Name = row["Name"].ToString(); custom.Address = row["Address"].ToString(); custom.BirthDay = (DateTime?)ToDBNull(row["BirthDay"]); custom.TelNum = row["TelNum"].ToString(); custom.Custlevel = (int)row["CUstlevel"]; custom.Id = (long)row["id"]; return custom; } }

public class SqlHelper { private static string connstr = ConfigurationManager.ConnectionStrings["conn"].ConnectionString; /// <summary> /// 查詢數據 /// </summary> /// <param name="sql"></param> /// <param name="parameters"></param> /// <returns></returns> public static Object ExecuteScalar(string sql, params SqlParameter[] parameters) { using (SqlConnection cnn = new SqlConnection(connstr)) { cnn.Open(); using (SqlCommand cmd = cnn.CreateCommand()) { cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); return cmd.ExecuteScalar(); } } } /// <summary> /// 增、刪、改操作 /// </summary> /// <param name="sql"></param> /// <param name="parameters"></param> public static void ExecuteNonQuery(string sql, params SqlParameter[] parameters) { using (SqlConnection cnn = new SqlConnection(connstr)) { cnn.Open(); using (SqlCommand cmd = cnn.CreateCommand()) { cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); cmd.ExecuteNonQuery(); } } } /// <summary> /// 單個查詢結果返回 /// </summary> /// <param name="sql"></param> /// <param name="parameters"></param> /// <returns></returns> public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters) { using (SqlConnection cnn = new SqlConnection(connstr)) { cnn.Open(); using (SqlCommand cmd = cnn.CreateCommand()) { cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); SqlDataAdapter apter = new SqlDataAdapter(cmd); DataSet dataset = new DataSet(); apter.Fill(dataset); return dataset.Tables[0]; } } } } 業務模型層 public class Custom { public long Id { set; get; } public string Name { set; get; } public DateTime? BirthDay { set; get; } public string Address { set; get; } public string TelNum { set; get; } public int Custlevel { set; get; } }
業務模型層
public class Custom { public long Id { set; get; } public string Name { set; get; } public DateTime? BirthDay { set; get; } public string Address { set; get; } public string TelNum { set; get; } public int Custlevel { set; get; } }
上述用思想,圖形表示如下: