C_三层架构_简单实例分析
CS三层架构范文

CS三层架构范文CS三层架构(Client/Server Three-Tier Architecture)是一种在计算机科学和软件工程中常见的软件设计模式,用于将一个大型系统分割为三个独立的层级,以实现系统的可维护性、可扩展性和灵活性。
这三个层级分别是表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据持久化层(Data Persistence Layer)。
下面将详细介绍这三个层级的功能和特点。
业务逻辑层是系统的核心,负责处理业务逻辑和应用逻辑。
它负责接收来自表示层的请求,进行相应的业务处理,并将处理结果返回给表示层。
业务逻辑层通常包括对输入数据的验证、对数据的处理、业务逻辑的执行以及对输出数据的生成等。
业务逻辑层的主要功能包括业务逻辑的处理、数据的处理、事务管理和数据校验等。
数据持久化层负责将数据保存在持久化存储介质中(如数据库、文件系统等)。
它负责管理数据的读取、存储、更新和删除,以及数据的一致性和可靠性等。
数据持久化层通常包括对数据的操作、数据的存取、事务处理和数据校验等。
数据持久化层的主要功能包括数据的读写操作、数据的事务处理和数据的校验等。
1.可维护性和可扩展性:不同层级的功能独立,可以独立进行修改和扩展,且修改一个层级不会影响到其他层级。
2.可重用性:各层级之间通过接口进行交互,使得各层级可以被重用于不同的系统和场景。
3.高效性:通过将系统拆分为不同的层级,可以实现各层级的并行开发,加快开发效率。
4.灵活性:不同层级可以选择不同的技术和平台,使得系统更加灵活和易于迁移。
然而,CS三层架构也存在一些缺点:1.增加了系统的复杂性:拆分系统为不同层级会增加系统的复杂性和部署成本。
2.增加了系统的通信开销:不同层级之间需要通过接口进行通信,会增加系统的通信开销。
3.可能导致性能下降:多层级的架构可能会导致系统的性能下降,因为每个层级都需要额外的资源和处理时间。
三层架构CS模式程序设计实例

///</summary>
private void CloseDataBase()
{
if (this.m_objConnection != null)
{
if (this.m_objConnection.State == ConnectionState.Open)
{
strSql += " WHERE NewsEnable = 1";
strSql += " ORDER BY NewsId ";
return OleDBAgent.GetDataView(strSql);
}
}
由于数据库结构比较简单,在此就不再给出详细的表结构。
4.UI层对Business中接口的调用
public class News : Base
{
public DataView GetNewsList()
{
string strSql;
strSql = "";
strSql += " SELECT Top 10 NewsId,NewsTitle ";
strSql += " FROM Tb_News";
优点:
l增加了代码的重用。Data Access可在多个项目中公用;Business可在同一项目的不同地方使用(如某个软件B/S和C/S部分可以共用一系列的Business组件)。
l使得软件的分层更加明晰,便于开发和维护。美工人员可以很方便地设计UI设计,并在其中调用Business给出的接口,而程序开发人员则可以专注的进行代码的编写和功能的实现。
三层架构简易实例详解

三层架构简易实例详解何为三层架构?通常意义上的三层架构就是将整个业务应用划分为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)。
区分层次的目的即为了“高内聚,低耦合”的思想。
1.表现层(UI):即展现给用户的界面;2.业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理;3.数据访问层(DAL):该层所做事务直接操作数据库,针对数据的增添、删除、修改、查找等。
下面通过通过一个简单的例子来描述三层架构:需求1.实现一个客户信息管理界面(包括增加、修改、删除)操作;2.用户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="{BindingCustlevel}"></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,@Teln um,@Custlevel)",new SqlParameter("@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", ),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(); = 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()){mandText = 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()){mandText = 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()){mandText = 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; } }上述用思想,图形表示如下:。
三层架构简易实例详解

三层架构简易实例详解三层架构是一种软件设计模式,它将软件系统分为三个层次:表现层、业务逻辑层和数据访问层。
每个层次都有特定的职责,通过分层的方式提高了系统的可维护性、可扩展性和可复用性。
以下是一个简单的示例来解释三层架构的概念:1. 表现层(Presentation Layer):这是用户与系统交互的界面。
它负责接收用户的输入、展示数据和呈现界面效果。
可以使用 Web 页面、桌面应用程序或移动应用程序等来实现。
2. 业务逻辑层(Business Logic Layer):该层处理系统的核心业务逻辑。
它接收来自表现层的请求,执行相应的业务规则和计算,并与数据访问层进行交互以获取和保存数据。
3. 数据访问层(Data Access Layer):这一层负责与数据库或其他数据源进行交互。
它封装了数据的读取、写入、修改和查询操作,提供了一个统一的数据访问接口。
以下是一个简单的示例,以在线书店为例:1. 表现层:用户通过网站或移动应用程序浏览图书列表、查看图书详细信息、添加到购物车和进行结算。
2. 业务逻辑层:处理用户的请求,例如检查购物车中的图书数量、计算价格、应用折扣等。
它还负责与数据访问层交互以获取图书信息和保存用户的订单。
3. 数据访问层:与数据库进行交互,执行图书的查询、插入、更新和删除操作。
通过将系统划分为三层,每层专注于特定的职责,可以提高代码的可维护性和可复用性。
当需求发生变化或需要进行系统扩展时,只需修改相应层次的代码,而不会影响其他层次。
这种分层的架构也有助于团队协作和开发效率。
请注意,这只是一个简单的示例,实际的三层架构应用可能会更加复杂,并涉及更多的模块和技术。
具体的实现方式会根据项目的需求和规模而有所不同。
CS三层架构

CS三层架构1、表现层(UI):通俗讲就是展现给用户的界面,即用户在使用一个系统的时候他的所见所得。
2、业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。
3、数据访问层(DAL):该层所做事务直接操作数据库,针对数据的增添、删除、修改、查找等。
各层的作用1:数据数据访问层:主要是对原始数据(数据库或者文本文件等存放数据的形式)的操作层,而不是指原始数据,也就是说,是对数据的操作,而不是数据库,具体为业务逻辑层或表示层提供数据服务.2:业务逻辑层:主要是针对具体的问题的操作,也可以理解成对数据层的操作,对数据业务逻辑处理,如果说数据层是积木,那逻辑层就是对这些积木的搭建。
3:表示层:主要表示WEB方式,也可以表示成WINFORM方式,WEB方式也可以表现成:aspx, 如果逻辑层相当强大和完善,无论表现层如何定义和更改,逻辑层都能完善地提供服务。
具体的区分方法1:数据数据访问层:主要看你的数据层里面有没有包含逻辑处理,实际上他的各个函数主要完成各个对数据文件的操作。
而不必管其他操作。
2:业务逻辑层:主要负责对数据层的操作。
也就是说把一些数据层的操作进行组合。
3:表示层:主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。
表示层位于最外层(最上层),离用户最近。
用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。
业务逻辑层业务逻辑层(Business Logic Layer)无疑是系统架构中体现核心价值的部分。
它的关注点主要集中在业务规则的制定、业务流程的实现等与业务需求有关的系统设计,也即是说它是与系统所应对的领域(Domain)逻辑有关,很多时候,也将业务逻辑层称为领域层。
例如Martin Fowler 在《Patterns of Enterprise Application Architecture》一书中,将整个架构分为三个主要的层:表示层、领域层和数据源层。
c语言三层架构简介

c语言三层架构简介
c语言三层架构简介
三层架构答案:通常意义上的三层架构就是将整个业务应用划分为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)。
区分层次的目的即为了“高内聚,低耦合”的思想。
表现层(UI):通俗讲就是展现给用户的界面,即用户在使用一个系统的.时候的所见所得。
业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。
数据访问层(DAL):该层所做事务直接操作数据库,针对数据的增添、删除、修改、更新、查找等每层之间是一种垂直的关系。
三层结构是N层结构的一种,一般来说,层次之间是向下依赖的,下层代码未确定其接口(契约)前,上层代码是无法开发的,下层代码接口(契约)的变化将使上层的代码一起变化。
优点:分工明确,条理清晰,易于调试,而且具有可扩展性。
缺点:增加成本。
c语言中描述线程与进程的区别?
1.线程(Thread)与进程(Process)二者都定义了某种边界,不同的是进程定义的是应用程序与应用程序之间的边界,不同的进程之间不能共享代码和数据空间,而线程定义的是代码执行堆栈和执行上下文的边界。
2.一个进程可以包括若干个线程,同时创建多个线程来完成某项任务,便是多线程。
而同一进程中的不同线程共享代码和数据空间。
用一个比喻来说,如果一个家庭代表一个进程,在家庭内部,各个成员就是线程,家庭中的每个成员都有义务对家庭的财富进行积累,同时也有权利对家庭财富进行消费,当面对一个任务的时候,家庭也可以派出几个成员来协同完成,而家庭之外的人则没有办法直接消费不属于自己家庭的财产。
【c语言三层架构简介】。
C# 最简单的三层架构实例教程

C# 最简单的三层架构实例教程很多初学三层架构的用户,都对三层架构无从入手!而这些用户往往会通过搜索引擎搜索,例如“最简单的三层架构例子”,等关键词,就算用户找到这个实例,又会感觉不太明白,(心想有没有还可以再简单的例子)!今天,很多初学三层架构的用户,都对三层架构无从入手!而这些用户往往会通过搜索引擎搜索,例如“最简单的三层架构例子”,等关键词,就算用户找到这个实例,又会感觉不太明白,(心想有没有还可以再简单的例子)!今天,我就写一个什么是最简单的三层架构例子(这个例子对你学习绝对有用,我说的!)代码/// <summary>/// 初始化登录名称、登录密码(Model类)/// </summary>private string adminUser = string.Empty; //设置用户名称为空值private string adminPwd = string.Empty; //设置用户密码为空值public string AdminUser{get{return this.adminUser;}set{this.adminUser = value;}}public string AdminPwd{get{return this.adminPwd;}set{this.adminPwd = value;}}代码/// <summary>/// 用户登录(BLL类)/// </summary>/// <param name="m"></param>/// <returns></returns>public static int sysLogin(Model m){string str = "adminValid"; //存储过程名称SqlParameter[] sqlParameter ={//将UI层传递过来的用户名称和密码赋值给存储过程中的变量分别是adminUser和adminPwd(注意大小写)new SqlParameter("adminUser",m.AdminUser),new SqlParameter("adminPwd",m.AdminPwd)};DAL d = new DAL();return Int32.Parse(d.ExecuteScalar(str,sqlParameter));}代码/// <summary>/// 新建一个SQL登录链接/// </summary>/// <returns></returns>private static SqlConnection con(){return new SqlConnection("Data Source=localhost;Initial Catalog=数据库名称;Integrated Security=SSPI;");}/// <summary>/// 执行操作(DAL类)/// </summary>/// <param name="str"></param>/// <param name="sql"></param>/// <returns></returns>public string ExecuteScalar(string str, SqlParameter[] sql){SqlConnection con = DAL.con();try{con.Open();SqlCommand com = new SqlCommand(str, con);mandType = CommandType.StoredProcedure;com.Parameters.AddRange(sql);return Convert.ToString(com.ExecuteScalar()); //返回受影响的行数(例如影响的行数为1,那么返回数值1到BLL层,然后BLL层将数值1返回到UI层)}catch (Exception Error){throw Error;}finally{con.Close();}}代码//UI层Model m = new Model(); //实例化Model类m.AdminUser = this.TextBox1.Text.ToString(); //将文本框1中的值传递给Model类中的AdminUserm.AdminPwd = this.TextBox2.Text.ToString(); //将文本框2中的值传递给Model类中的AdminPwdif (BLL.sysLogin(m) > 0){bel1.Text = "登录成功!马上进入管理平台...";}else{bel1.Text = "用户或密码错误,请重新输入!";}代码--存储过程(SQL2005)set ANSI_NULLS ONset QUOTED_IDENTIFIER ONgoALTER PROC [dbo].[adminValid]@adminUser varchar(20),@adminPwd varchar(120)ASSELECT COUNT(*) FROM admin WHERE adminUser = @adminUser AND adminPwd = @adminPwd。
图解三层架构

企业初期方案(Scale In one) 某企业目前的业务需求比较简单,使用用户也仅局限在某些核心部门,人数不过十几、二 十个人。这时的规划方案将企业使用到的所有服务都安装在一台服务器设备上,这种形式 称为 Scale In(向内扩展)。 该方案在一台服务器上实现三层结构的全部工作。简单实用是该方案的最大特点,而且三 层结构的 ERP 产品还支持未来的方案扩展。
三层架构可以更好的支持分布式计算环境。逻辑层的应用程序可以在多个计算机上运行,充分利用网络的计 算功能。分布式计算的潜力巨大,远比升级 CPU 有效。美国人曾利用分式计算解密,几个月就破解了据称永远 都破解不了的密码。
三层架构的最大优点是它的安全性。用户只能通过逻辑层来访问数据层,减少了入口点,把很多危险的系统 功能都屏蔽了。
业务逻辑层:用于做一些有效性验证的工作,以更好地保证程序运行的健壮性。如完成数据添加、修改和查询 业务等;不允许指定的文本框中输入空字符串,数据格 式是否正确及数据类型验证;用户的权限的合法性判断 等等,通过以上的诸多判断以决定是否将操作继续向后传递,尽量保证程序的正常运行。
数据访问层:顾名思义,就是用于专门跟数据库进行交互。执行数据的添加、删除、修改和显示等。需要强调 的是,所有的数据对象只在这一层被引用,如 System.Data.SqlClient 等,除数据层之外的任何地方都不应该出现 这样的引用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于3层架构的课程管理系统本模块工作任务任务3-1:三层架构划分任务3-2:数据访问层的实现任务3-3:业务逻辑层的实现 任务3-4:表示层的实现本模块学习目标1、掌握三层架构的划分原理2、掌握各层的设计思路,和层之间的调用关系3、利用三层架构实现对课程管理模块的重构4、巩固OOP 的基本概念和 OOP 的编程思路---------------------------------------------------------------------------------------------------------------------------------http://211.147.15.119/mmdy.html任务3-1:三层架构划分效果与描述图3.1 包含多个项目的3层架构解决方案本任务要求学生能够将原来的只有1个项目的课程管理模块,重构为标准的具有5个项目的3层架构的模块,并进行恰当的初始化,仍能实现课程记录的添加、浏览功能。
在此过程中理解3层架构的划分原理,各层的任务,层之间的调用关系。
本任务的业务流程: 将原项目改为UI 层新建BLL/ DAL/COMMON/MODL 项目并初始化初始化后仍能实现课程记录的浏览和添加业务逻辑层数据访问层界面层图3.2 单层转化为3层架构的业务流程相关知识与技能3-1-1 三层架构的划分原理三层架构的划分如下图:图3.3 三层架构原理图1、各层的任务数据访问层:使用中的数据操作类,为数据库中的每个表,设计1个数据访问类。
类中实现:记录的插入、删除、单条记录的查询、记录集的查询、单条记录的有无判断等基本的数据操作方法。
对于一般的管理信息软件,此层的设计是类似的,包含的方法也基本相同。
此层的任务是:封装每个数据表的基本记录操作,为实现业务逻辑提供数据库访问基础。
业务逻辑层:为用户的每个功能模块,设计1个业务逻辑类,此时,需要利用相关的数据访问层类中,记录操作方法的特定集合,来实现每个逻辑功能。
界面层:根据用户的具体需求,为每个功能模块,部署输入控件、操作控件和输出控件,并调用业务逻辑层中类的方法实现功能。
2、层之间的调用关系数据访问层的类,直接访问数据库,实现基本记录操作。
业务逻辑层的类,调用相关的数据访问类,实现用户所需功能。
界面层:部署控件后,调用业务逻辑层的类,实现功能。
将应用程序的功能分层后,对于固定的DBMS,数据访问层基本可以不变,一旦用户的需求改变,首先修改业务逻辑层,界面层稍做改动即可。
这种做法使程序的可复用性、可修改性,都得到了很好的改善,大大提高了软件工程的效率。
3-1-2 ORM(对象关系映射)在图3.1中看到,除了界面层、业务逻辑层和数据访问层之外,还有2个项目。
其中,Common项目中一般放的是公用文件,如数据操作类DBHelper等,被数据访问层的类调用,其必要性在上个模块已述。
Modal项目中存放的是实体类。
所谓的对象关系映射Object Relational Mapping,简称ORM,是为了解决面向对象的类,与关系数据库的表之间,存在的不匹配的现象,通过使用描述对象和关系之间映射的元数据,在程序中的类对象,与关系数据库的表之间建立持久的关系,用于在程序中描述数据库表。
本质上就是将数据从一种形式转换到另外一种形式。
ORM是一个广义的概念,适应于关系数据库与应用程序之间的各类数据转换,目前有许多自动转换工具可用,如codesmith 等。
在本教材中,利用手工书写代码的形式,实现ORM。
如对于学生选课管理系统数据库中的课程表course,其设计视图如下:图3.4 Course表设计视图可以这样设计类来描述它:public class Course{private string courseId;public string CourseId{get { return courseId; }set { courseId = value; }}private string courseName;public string CourseName{get { return courseName; }set { courseName = value; }}private int courseCredit;public int CourseCredit{get { return courseCredit; }set { courseCredit = value; }}public Course() { }public Course(string courseId,string courseName,int courseCredit){this.courseId = courseId;this.courseName = courseName;this.courseCredit = courseCredit;}}将表中的每个字段抽取为类的字段(注意类型匹配),并封装成属性,设计构造函数,来将表抽取为类。
这种类就称为实体类。
这个抽取过程称为对象关系映射ORM。
在Modal项目中,为数据库的每个表,都设计一个相应的实体类,这样,就相当于对每个表实体,在.NET程序中,都可以通过类对象来应用。
在上面介绍的3层中,通常都会用到实体类对象。
综上所述,这5个项目之间的关系是这样的:UI(界面层)BLL(业务逻辑层)Modal(实体类)DAL(数据访问层)Common(DBHelper数据操作类)数据库图3.5 三层架构中5个项目之间的关系图任务的设计思路1、在上个模块基于单层的课程管理的基础上,将原有的WINDOWS窗体应用程序的项目,设置为界面层,改名为UI,界面层的控件部署不用改变,并设置为启动项目;2、在解决方案中添加业务逻辑层项目BLL、数据访问层项目DAL、Common项目、Modal项目,他们都是类库型的项目;3、将DBHelepr类移到Common项目中;4、在Modal项目中,为学生选课管理系统的每个表,设计对应的实体类。
5、设置好引用关系后,运行,可实现课程记录的添加和浏览。
注意:此时,3层结构虽已架设好,运行也可实现课程管理的记录添加和浏览功能。
但是运行的仍是界面层代码,其余层的代码尚未设计。
任务的实施1、在原来的版本中,用1个WINDOWS窗体应用项目就实现了课程管理,在3层架构体系中,当然,这个项目就是界面层。
首先,把原有的项目改名为UI,右击此项目,改名即可。
然后,右击解决方案,选择“设置启动项目”,即可将界面层项目设置为启动项目。
2、右击解决方案,分别生成4个新的项目,这些项目均是类库项目,按照惯例,数据访问层项目起名为DAL,业务逻辑层项目起名为BLL,另外2个项目起名为Common和Modal。
3、右击Common,选择“添加”里的“现有项”,将DBHelper类添加入此项目。
右击UI下原有的DBHelper类文件,选择“从项目中排除”。
就实现了将DBHelepr类移到Common 项目中。
将命名空间改为mon,其中BFCourse为解决方案名。
以后每个项目中的每个文件,都需要在前面加上解决方案名,这样,就都处于同一个命名空间BFCourse。
4、在Modal项目中,选择添加新建项,参考课程表的抽取方法,为学生选课管理系统的每个表,设计对应的实体类。
同理,命名空间改为BFCourse. Modal。
5、此时,界面层代码会显示DBHelper找不到,因为移到了Common项目。
所以,必须在界面层项目UI中添加对Common项目的引用。
然后,整个系统就可以运行了。
当然,虽然形式是3层的,但实际运行的是UI和Common中的代码。
举一反三1、把选课系统数据库的另外3张表,学生表、选课表和用户表,都进行对象关系映射,为其生成实体类。
2、在包含5个项目的3层架构的系统中,为DAL、BLL项目添加类文件,只需添加空文件,但命名方式按各层的功能需求设计,将所有需要的类文件添加齐全。
---------------------------------------------------------------------------------------------------------------------------------任务3-2:课程添加的3层实现效果与描述效果图仍然如图2.1所示,实现课程记录的添加。
但需要用3层的技术来实现。
首先,回顾一下,记录添加的业务流程,如图2.14所示。
要判断输入的完整性;然后判断输入的课程号主键在数据库中是否已有;若无,则插入记录到数据库中。
然后,根据业务需求,从底到高来设计每层。
单纯的判断记录有无、单纯的记录添加操作,就可以放在数据访问层。
记录添加的逻辑功能:判断输入的课程号主键在数据库中是否已有,若无,则插入记录到数据库中,则由业务逻辑层调用数据访问层的添加方法来实现;最后,在界面层,其控件部署不用改变,只需判断文本框的输入完整性,然后调用业务逻辑层的添加方法就可以了。
本任务的设计流程如下:设计数据访问类CourseAccess的Exist和AddCourse方法设计业务逻辑类CourseBiz类的Addcourse方法利用业务逻辑层优化界面层相关代码图3.6 数据添加的3层设计流程相关知识与技能3-2-1 数据访问层的方法设计一般为系统数据库中的每个表设计一个数据访问类,实现基本的记录操作。
为了实现课程记录的添加,目前,可在数据访问类包含如下方法:1、判断某主键的记录是否存在方法名:Exist形参:代表主键的变量返回值:bool方法内代码设计:(1)设计语句select * from 表where 主键名=形参(2)利用using语句,调用DBHelper类,生成一个datareader对象(3)利用HasRows 属性判断此datareader对象是否有行,若有,返回真,否则返回假。
应用场合:在插入记录前判断,若有则不用再插;在删除记录前判断,若有则不能删。
2、方法名:AddXX形参:代表此表实体类的对象返回值:int方法内代码设计:(1)设计语句insert(2)调用DBHelper类,用ExeccuteNonQuery()方法执行此语句并返回。
应用场合:在表中添加一条记录,根据返回值是否大于0判断执行成功否。
3-2-2 业务逻辑层的方法设计一般为系统中的每个功能模块设计1个业务逻辑层的类,实现此模块的所有业务逻辑。
在课程添加中,所需要的业务逻辑为课程添加。
首先,由于需要调用数据访问类CourseAccess,因此,在类内设计1个字段为此类对象:CourseAccess courseAccess = new CourseAccess();其次,此类需要设计如下方法:1、添加课程方法名:AddXX形参:课程类对象返回值:void方法内代码设计:(1)调用CourseAccess类对象的Exist()方法,判断形参所表示的课程类对象是否存在,若存在方法返回;(2)调用CourseAccess类对象的AddCourse()方法,添加课程,并利用返回值判断添加是否成功。