文档章节

深入浅出三层架构

 木宛城主
发布于 2015/03/02 19:42
字数 1569
阅读 19
收藏 2
点赞 0
评论 0

这几天看了不少三层架构的资料,整理整理

——故写篇博文谈谈自己的看法。

三层架构概念:

三层架构(3-tier application) 通常意义上的三层架构就是将整个业务应用划分为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)。区分层次的目的即为了“高内聚,低耦合”的思想,复杂项目不能把SQL语句直接写到程序里,不模块话,难以维护。应该采取三层架构。

1、表现层(UI):通俗讲就是展现给用户的界面,即用户在使用一个系统的时候他的所见所得。

2、业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。

3、数据访问层(DAL):该层所做事务直接操作数据库,针对数据的增添、删除、修改、查找等。
 
简单的说,UI层调用BLL,BLL调用DAL,数据用Model进行传递,Model为各层之间架起了数据传输的桥梁。
参考模型:UI<-->Model<-->BLL<-->Model<-->DAL

传统的两层结构和三层架构之间的区别:

 
下面我以一个简单的例子来细数三层架构:

代码剖析:

  • 新建一个项目(Windows 窗体应用程序),再在根目录下新建3个文件夹,分别是Model,DAL,BLL。
  • 在Model下添加一个Person类
  • 在DAL下添加一个SQLHelper类和一个PersonDAL类。
  • 在BLL下添加PersonBLL类

Person.cs代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 三层架构Demo.Model
{
class Person
{
public int Id { get;set;}
public int Age { get; set; }
public string Name { get; set; }

}
}



SQLHelper类,封装了数据库操作的方法:

SQLHelper.cs代码入下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;

namespace 三层架构Demo.DAL
{
class SQLHelper
{
//public static readonly string connStr = System.Configuration.ConfigurationSettings.AppSettings["dbconnstr"];
//获得连接字符串
public static readonly string connStr =
ConfigurationManager.ConnectionStrings["dbconnstr"].ConnectionString;

/// <summary>
/// 执行方法ExecuteNonQuery
/// </summary>
/// <param name="cmdText">要执行的sql语句</param>
/// <param name="parameters">参数数组</param>
/// <returns>受影响的行数</returns>
public static int ExecuteNonQuery(string cmdText,
params SqlParameter[] parameters)
{
using (SqlConnection conn=new SqlConnection (connStr))
{
conn.Open();
using (SqlCommand cmd= conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(parameters);
int i=cmd.ExecuteNonQuery();
return i;
}
}
}

/// <summary>
/// 执行ExecuteScalar() 返回第一行第一列数据
/// </summary>
/// <param name="cmdText">要执行的sql语句</param>
/// <param name="parameters">参数数组</param>
/// <returns>返回第一行第一列数据</returns>
public static object ExecuteScalar(string cmdText,
params SqlParameter[] parameters)
{
using (SqlConnection conn=new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(parameters);
return cmd.ExecuteScalar();
}
}
}

/// <summary>
/// 执行ExecuteDataTable()方法
/// </summary>
/// <param name="cmdText">要执行的Sql语句</param>
/// <param name="parameters">参数数组</param>
/// <returns>返回一个DataTable</returns>
public static DataTable ExecuteDataTable(string cmdText,
params SqlParameter[] parameters)
{
using (SqlConnection conn=new SqlConnection (connStr))
{
conn.Open();
using (SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(parameters);
using ( SqlDataAdapter adapter=new SqlDataAdapter (cmd))
{
DataTable dt = new DataTable();
adapter.Fill(dt);
return dt;
}
}
}
}

/// <summary>
/// 执行ExecuteSqlDataReader()方法
/// </summary>
/// <param name="cmdText">要执行的Sql语句</param>
/// <param name="parameters">参数数组</param>
/// <returns>返回一个SqlDataReader</returns>

public static SqlDataReader ExecuteSqlDataReader(string cmdText,
params SqlParameter[] parameters)
{
using (SqlConnection conn=new SqlConnection (connStr))
{
conn.Open();
using (SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(parameters);
return cmd.ExecuteReader();
}
}
}
}
}

PersonDAL.cs代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using 三层架构Demo.Model;
using System.Data.SqlClient;
using System.Data;

namespace 三层架构Demo.DAL
{
class PersonDAL
{
/// <summary>
/// 返回一个新增对象的主键,设为自动增长
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Addnew(Person model)
{
string sql = "insert into T_person(Age,Name) output inserted.id values(@Age,@Name)";

object obj=
SQLHelper.ExecuteScalar(sql,new SqlParameter("Age",model.Age),new SqlParameter("Name",model.Name));
//Convert : 与 value 等效的 32 位有符号整数,如果 value 为 null,则为零。
return Convert.ToInt32(obj);
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public int Delete(int id)
{
string sql = "delete form T_Person where Id=@Id";
return SQLHelper.ExecuteNonQuery(sql,new SqlParameter("Id",id));
}
/// <summary>
/// 修改数据
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Update(Person model)
{
string sql = "update T_Person set Age=@Age,Name=@Name where Id=@Id";
return SQLHelper.ExecuteNonQuery(sql,new SqlParameter("Age",model.Age),new SqlParameter("Name",model.Name),
new SqlParameter("Id",model.Id));
}

/// <summary>
/// 查询数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public Person Get(int id)
{
string sql="select * from T_Person where Id=@Id";
DataTable dt=SQLHelper.ExecuteDataTable(sql,new SqlParameter("Id",id));
if (dt.Rows.Count<=0)
{
return null;
}
else if (dt.Rows.Count==1)
{
Person model1 = new Person();
model1.Id = Convert.ToInt32(dt.Rows[0]["Id"]);
model1.Name = Convert.ToString(dt.Rows[0]["Name"]);
model1.Age = Convert.ToInt32(dt.Rows[0]["Age"]);
return model1;
}
else//以防意外情况
{
throw new Exception("数据库中有两条及以上重复数据");
}
}
/// <summary>
/// 获取全部数据
/// </summary>
/// <returns></returns>
public IEnumerable<Person> GetAll()
{
string sql = "select * from T_Person";
DataTable dt = SQLHelper.ExecuteDataTable(sql);
List<Person> list = new List<Person>();
foreach (DataRow row in dt.Rows)
{
Person model = new Person();
model.Id = Convert.ToInt32(row["Id"]);
model.Name =Convert.ToString(row["Name"]);
model.Age = Convert.ToInt32(row["Age"]);
list.Add(model);
}
return list;
}
}
}

 

进行逻辑判断的BLL层代码看似是这样的:

PersonBLL.cs代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using 三层架构Demo.Model;
using 三层架构Demo.DAL;
using System.Data.SqlClient;
using System.Data;

namespace 三层架构Demo.BLL
{
class PersonBLL
{
public int Addnew(Person model)
{
return new PersonDAL().Addnew(model);
}

public int Delete(int id)
{
return new PersonDAL().Delete(id);
}

public int Update(Person model)
{
return new PersonDAL().Update(model);
}

public Person Get(int id)
{
return new PersonDAL().Get(id);
}

public IEnumerable<Person> GetAll()
{
return new PersonDAL().GetAll();
}


}
}

 

UI层进行测试:

Form1.cs代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using 三层架构Demo.Model;
using 三层架构Demo.DAL;
using 三层架构Demo.BLL;

namespace 三层架构Demo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//Person p1 = new Person();
//p1.Age = 22;
//p1.Name = "Eyes";
//int id=new PersonDAL().Addnew(p1);
//MessageBox.Show(id.ToString());

//PersonDAL p = new PersonDAL();
//Person a = p.Get(1);
//a.Name = "jack";
//MessageBox.Show(a.Name + "," + a.Age);
//p.Update(a);


//PersonBLL bll = new PersonBLL();
//Person p = bll.Get(1);
//p.Name = "Admin";
//MessageBox.Show(p.Name + "," + p.Age);
//bll.Update(p);

PersonBLL b = new PersonBLL();
List<Person> list = (List<Person>)b.GetAll();
foreach (Person item in list)
{
MessageBox.Show(item.Id+","+item.Name+","+item.Age);
}

}

private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = new PersonBLL().GetAll();
}
}
}

 

总结:

 

优点

  1、开发人员可以只关注整个结构中的其中某一层;

  2、可以很容易的用新的实现来替换原有层次的实现;

  3、可以降低层与层之间的依赖;

  4、有利于标准化;

  5、利于各层逻辑的复用。

缺点

  1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。

  2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。

  3、增加了开发成本。






 

© 著作权归作者所有

共有 人打赏支持
粉丝 2
博文 222
码字总数 199010
作品 0
黄浦
基于C# winform企业进销存软件开发

基于C# winform企业进销存软件开发视频教程 下载地址分享:http://pan.baidu.com/s/1jI4w4bO 密码:qtvc 课程共6章,70讲,本教程以进销存管理实务为基础,使用流行的C#语言。涵盖软件开发的全...

妮妮我爱你 ⋅ 2017/03/29 ⋅ 1

【深入浅出MyBatis系列一】MyBatis入门

深入浅出MyBatis系列 【深入浅出MyBatis系列一】MyBatis入门 【深入浅出MyBatis系列二】配置简介(MyBatis源码篇) 【深入浅出MyBatis系列三】Mapper映射文件配置 【深入浅出MyBatis系列四】...

陶邦仁 ⋅ 2015/12/22 ⋅ 0

MVC与三层架构的区别

我们平时总是将三层架构与MVC混为一谈,殊不知它俩并不是一个概念。下面我来为大家揭晓我所知道的一些真相。 首先,它俩根本不是一个概念。   三层架构是一个分层式的软件体系架构设计,它...

xiaml ⋅ 2014/06/01 ⋅ 3

三层架构与MVC

三层架构与MVC有区别,但联系紧密。 他们的作用都是为了降低系统耦合度。 三层架构 三层架构 视图层(View) 存放接收用户提交请求的代码 服务层(Service) 存放系统的业务逻辑代码 持久层(Dao)...

stormxing ⋅ 2017/12/11 ⋅ 0

mvc与三层结构终极区别

注:本文章内所有内容都来自互联网,本人主要是起了一个收集的作用 http://www.cnblogs.com/zhhh/archive/2011/06/10/2077519.html 又看到有人在问三层架构和MVC的关系,感觉这种问题有点教条...

长平狐 ⋅ 2012/11/12 ⋅ 0

JavaEE软件开发体系架构

前言 上篇文章小编提到了什么是javaEE和它的13个核心规范,本篇文章,小编带您走进JavaEE的体系结构,从两层架构,三层架构,MVC,基于JavaEE架构模式下的MVC,JavaEE的四层架构。 两层架构 ...

weienjun ⋅ 2017/12/24 ⋅ 0

三层架构和MVC模式

1、三层架构 三层架构(3-tier application) 通常意义上的三层架构就是将整个业务应用划分为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)。区分层次的目的即为了“高内聚,低耦合”...

_Roger_ ⋅ 2015/10/21 ⋅ 1

.NET数据库编程求索之路--1.引子

  长期做.NET MIS系统开发,打交到最多还是数据库。闲来无事,朝花夕拾,将.NET数据库编程一路走来的经验整理并与朋友分享一下。以一个小小的订单管理系统为例,采用代码实战的方式,计划分...

夏春涛 ⋅ 2012/06/07 ⋅ 0

三层架构及其优缺点

三层架构及其优缺点 2010-09-26 21:50:49| 分类: 知识 | 标签: |举报 |字号大中小 订阅 三层架构(3-tier application) 通常意义上的三层架构就是将整个业务应用划分为:表现层(UI)、业务...

vga ⋅ 2014/07/04 ⋅ 3

J2EE开发三层架构的是与非

现在开发web大多都是基于MVC的三层架构,三层架构优势什么呢? 三层架构(3-tier application) 通常意义上的三层架构就是将整个业务应用划分为:表现层(UI)、业务逻辑层(BLL)、数据访问层...

JavaOlder ⋅ 2012/11/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

mysql5.7系列修改root默认密码

操作系统为centos7 64 1、修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不对密码进行验证 2、重启 mysqld 服务:systemctl restart mysql...

sskill ⋅ 21分钟前 ⋅ 0

Intellij IDEA神器常用技巧六-Debug详解

在调试代码的时候,你的项目得debug模式启动,也就是点那个绿色的甲虫启动服务器,然后,就可以在代码里面断点调试啦。下面不要在意,这个快捷键具体是啥,因为,这个keymap是可以自己配置的...

Mkeeper ⋅ 26分钟前 ⋅ 0

zip压缩工具、tar打包、打包并压缩

zip 支持压缩目录 1.在/tmp/目录下创建目录(study_zip)及文件 root@yolks1 study_zip]# !treetree 11└── 2 └── 3 └── test_zip.txt2 directories, 1 file 2.yum...

蛋黄Yolks ⋅ 28分钟前 ⋅ 0

聊聊HystrixThreadPool

序 本文主要研究一下HystrixThreadPool HystrixThreadPool hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/HystrixThreadPool.java /** * ThreadPool used to executed {@link Hys......

go4it ⋅ 47分钟前 ⋅ 0

容器之上传镜像到Docker hub

Docker hub在国内可以访问,首先要创建一个账号,这个后面会用到,我是用126邮箱注册的。 1. docker login List-1 Username不能使用你注册的邮箱,要用使用注册时用的username;要输入密码 ...

汉斯-冯-拉特 ⋅ 53分钟前 ⋅ 0

SpringBoot简单使用ehcache

1,SpringBoot版本 2.0.3.RELEASE ①,pom.xml <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELE......

暗中观察 ⋅ 54分钟前 ⋅ 0

监控各项服务

比如有三个服务, 为了减少故障时间,增加监控任务,使用linux的 crontab 实现. 步骤: 1,每个服务写一个ping接口 监控如下内容: 1,HouseServer 是否正常运行,所以需要增加一个ping的接口 ; http...

黄威 ⋅ 58分钟前 ⋅ 0

Spring源码解析(八)——实例创建(下)

前言 来到实例创建的最后一节,前面已经将一个实例通过不同方式(工厂方法、构造器注入、默认构造器)给创建出来了,下面我们要对创建出来的实例进行一些“加工”处理。 源码解读 回顾下之前...

MarvelCode ⋅ 58分钟前 ⋅ 0

nodejs __proto__跟prototype

前言 nodejs中完全没有class的这个概念,这点跟PHP,JAVA等面向对象的语言很不一样,没有class跟object的区分,那么nodejs是怎么样实现继承的呢? 对象 对象是由属性跟方法组成的一个东西,就...

Ai5tbb ⋅ 今天 ⋅ 0

Ubuntu16.04 PHP7.0 不能用MYSQLi方式连接MySQL5.7数据库

Q: Ubuntu16.04 PHP7.0 不能用MYSQLi方式连接MySQL5.7数据库 A: 执行以下2条命令解决: apt-get install php-mysql service apache2 restart php -m 执行后会多以下4个模块: mysqli mysqlnd...

SamXIAO ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部