简易三层架构详解
何为三层架构?通常意义上的三层架构就是将整个业务应用划分为:表现层(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; } }
上述用思想,图形表示如下: