学习asp.net两周,通过学习发现,.net和php之间的区别还是蛮大的,比php要复杂一些,开始学习的有些吃力,后来跟着传智播客里的老师学习,渐渐的学到了一些东西。
今天要记录一下.net里的简单的三层架构是如何实现的,希望通过一次次的博客记录能加深自己对知识点的理解和记忆,当然,如果有幸能帮到某些和我一样的同学,那也是非常荣幸和欣喜的,好了,闲言少叙,下面开始记录。
三层架构我自己也不是很熟,只是大概的知道其工作原理,以及构建流程,这里贴出传智博客的老师讲解的一张原理图,然后就略过了,毕竟本人太菜,不敢误导别人。
如上图所示,是一张三层结构工作原理图,三层结构分为
UI(视图层):人眼直接能看到的内容,如winform,website等;
Bll(业务逻辑层):处理与业务相关的逻辑;
Dal(数据访问层):只负责接收业务逻辑层的调用,处理相关的数据库CURD操作,只跟数据库打交道,与UI层完全分离;
Common和Model:一些三层之外的文件,这些文件可以写一些静态类,实体类等东西,这里面的内容三个类都可以调用;
关于三层结构的原理只做简单说明,想要详细了解的同学,请自行百度,阅读技术大牛们的博客,下面对该三层实现的步骤做详尽的说明。
第一步:创建UI,BLL,和DAL
1.打开ide ,VS20XX,(我这里用的是最新版的VS2017),点击文件 ==》 新建 ==》项目,如下图所示:
2.选择其他项目类型下的VS'解决方案 ==》空白解决方案,命名,选择保存路径后点击确定;
3.右击解决方案 ==》点击添加 ==》新建项目 ==》选择 Windows窗体应用 ==》命名为UI(这里我们以窗体作为显示层,这里也可以把website空网站作为显示层,用起来都是一样的);
4.右击解决方案,添加新项目 ==》选择新建 类库(.net Framework),这里不要选错,因为选项里有三个类库选项,我们应该选择 后面 括号里带 .net Framework 的类库,选其他的会出错,至于为什么,我也不知道,见谅见谅哈。
5.同样的方法,新建Bll,建好之后,应该有如图所示的几个东西,
第二步:所要完成的功能的说明:
在这里我要完成的功能其实非常非常的简单,就是查询一张表,看里面有多少条数据,然后返回数据的条数,大致是这样的,我们有一个窗体窗体上有个按键,点击这个按键(查看XXX表中的数据条数),弹出窗口,显示:XXX表中有XX条数据。
这里我要操作的是一个名为TbAreas的表,如图所示:
第三步:三层实现流程介绍
1.确定sql语句
为了保证数据库操作语句不出错误,我先在数据库中新建查询,看能不能查到我要的结果,我用的数据库是sqlserver,数据库管理软件是微软的 MSMS,查询结果如图所示:
如图所示可以看到,用该语句查询出的结果是表中有54条数据,下面我看一下是否有误:
由图可知,无误,故我们的语句确定为:sql = "select count(*) from TbAreas" ;
2.在数据访问层编写执行该sql语句的函数
首先给DAL里的Class1.cs重命名为:表名+Dal+.cs,这里饿哦们命名为:TbAreasDal.cs;
需要我知道的是,三层里,每个表对应一个类,以后操作同一张表的所有函数都写在同一个类中。
然后,开始编写代码了,在Dal里的TbAreasDal类中编写如下方法:
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Dal
{
public class TbAreasDal
{
//在这里编写数据库操作函数
public int GetRecordCount()
{
//sql语句
string sql = "select count(*) from TbAreas";
//调用SqlHelper里的方法执行查操作语句
return (int)SqlHelper.ExcuteScalar(sql,System.Data.CommandType.Text);
}
}
}
这个里面的代码就是这样了,但是,很遗憾,这个代码是错误的,贴上图片给你看:
因为我的代码里没有SqlHelper这个类。SqlHelper这个类是需要自己封装的一个数据库操作类,这个类怎么封装不是我今天要记录的内容,以后有时间会记录一下的。这个类我已经封装过,直接复制到Dal项目下,如下图所示:
先给代码:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 封装SqlHelper类
{
public class SqlHelper
{
//定义一个连接字符串
//readonly修饰的变量,只能在初始化的时候赋值,以及构造函数中赋值
private static readonly string conStr = ConfigurationManager.ConnectionStrings["mssqlserver"].ConnectionString; //1.执行增(insert)删(delete)改(update)的方法 ExecuteNonQuery()
public static int ExecuteNonQurey(string sql,CommandType cmdType,params SqlParameter[] pms)
{
using (SqlConnection con = new SqlConnection(conStr))
{
using (SqlCommand cmd = new SqlCommand(sql,con))
{
cmd.CommandType = cmdType;
if (pms != null)
{
cmd.Parameters.AddRange(pms);
}
con.Open();
return cmd.ExecuteNonQuery();
}
}
} //2.执行查询,返回单个值的方法 ExecuteScalar
public static object ExecuteScalar(string sql, CommandType cmdType, params SqlParameter[] pms)
{
using (SqlConnection con = new SqlConnection(conStr))
{
using (SqlCommand cmd = new SqlCommand(sql, con))
{
cmd.CommandType = cmdType;
if (pms != null)
{
cmd.Parameters.AddRange(pms);
}
con.Open();
return cmd.ExecuteScalar();
}
}
} //3.执行查询,返回多行的方法ExecuteReader
public static SqlDataReader ExecuteReader(string sql, CommandType cmdType, params SqlParameter[] pms)
{
SqlConnection con = new SqlConnection(conStr);
using (SqlCommand cmd = new SqlCommand(sql,con))
{
cmd.CommandType = cmdType;
if(pms != null)
{
cmd.Parameters.AddRange(pms);
}
try
{
if (con.State == ConnectionState.Closed)
{
con.Open();
} //System.Data.CommandBehavior.CloseConnection这个枚举参数,表示将来使用完毕SqlDataReader后,在关闭reader的同时,在SqlDataReader内部会将关联的Connection对象也关闭掉
return cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
}
catch
{
con.Close();
con.Dispose();
throw;
}
} } public static DataTable ExecuteDataTable(string sql,CommandType cmdType,params SqlParameter[] pms)
{
DataTable dt = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter(sql,conStr))
{
adapter.SelectCommand.CommandType = cmdType;
if (pms != null)
{
adapter.SelectCommand.Parameters.AddRange(pms);
}
adapter.Fill(dt); }
return dt;
}
}
}
然后看看图片:
细心的你一定一眼就看到了这里有个bug啦,当前文中不存在这个ConfigurationManager类,所以啊,我要把这个东西搞进来先。那么问题来了,在哪里搞呢,自己写一个吗,不,不是的,这是个系统自带的东西,我只需要引用进来就行了;
怎么引用,往下看:
(1)右击Dal下的引用,点击 添加引用 ==》程序集 ==》 框架(如果最近引用过可以点击最近)==》找到这个东西 System.Configuration, 打上沟,点击确定,就可以了
(2)看一下引用后的结果吧:
现在可以看到,那个错误没有了。
事实上,做到这一步,我们的这个SqlHelper还是不能正常使用的,为什么,细心的你可能会发现,在SqlHelper里链接数据库的字符串conStr后面的东西跟我们学的时候看到的语句不一样啊,这里既没写我要连那个服务器,也没写要连那个数据库,更没写是那个用户登录的,登录密码是啥?那咋办呢,这是为啥呢?
下面来讲:因为数据库的链接是一个很频繁的操作,如果我们在每个数据库连接的方法中都写上一串下面这个代码:
string conStr = "Data Source = .;Initial Catalog = 数据库名;User ID = sa;Password = XXXX";
那会是非常繁琐的,而且如果有朝一日需要改动这个数据库,那需要改的文件就太多了,因此啊,我们把这个东西放到了一个全局配置文件中,这个文件就是App.config,这个文件vs2017是默认就有的,以前版本的好像要自己新建。
下面点击打开App.config, 在里面添加<connectionStrings><add XXXXXXXX/></connectionStrings>这样的一串代码:
代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="mssqlserver" connectionString="Data Source = acer-pc;Initial Catalog = FirstDB;User ID = sa; Password = 168168"/>
</connectionStrings>
</configuration>
添加好后,把name = "XXX"里的这个XXX名字写到SqlHelper里的那个位置去就可以了
到这个地方这数据库相关的东西就弄好了,下面我们回到TbAreasDal.cs里来,
此时SqlHeiper这个类已经有了,但是还没有引进来。
怎么引,简单,将光标定位到划红线的地方,使用快捷键 Ctrl + Alt +F10 ,会弹出提示语句,选中提示语句就可以了,这个快捷键还蛮好用,可以记一记。如图所示:
下面给出正确的TbAreasDal.cs代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 封装SqlHelper类; namespace Dal
{
public class TbAreasDal
{
//在这里编写数据库操作函数
public int GetRecordCount()
{
//sql语句
string sql = "select count(*) from TbAreas";
//调用SqlHelper里的方法执行查操作语句
return (int)SqlHelper.ExecuteScalar(sql,System.Data.CommandType.Text);
}
}
}
到这里Dal层就写完了,下面来看Blll层。
3.在业务层编写业务逻辑代码
首先给Bll里的类重命名为TbAreasBll.cs,然后编写代码:
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Bll
{
public class TbAreasBll
{
TbAreasDal dal = new TbAreasDal();
public int GetRecordCount()
{
return dal.GetRecordCount();
}
}
}
但是,此时这个代码还有问题,如下图所示
没错,这里缺少Dal项目的引用啊,只有把他引进来,才能使用他啊。怎么引,两种办法,一种、直接在上图左边的红框上点一下,还有一种,右击Bllx下的引用 ==》添加引用 ==》 项目 ==》勾上Dal,如图所示:
就是这样子了,引进来后就没有错误了。咋的,不信啊,不信给你看图啊:
到这里,业务层也交代完了,接下来看UI层。
4.UI层——进行用户操作,获取反馈结果
首先给UI层的窗体重命名为AreasNum.cs,然后在上面添加一个按钮。,如下图所示:
这样就可以了,接下来双击按钮,进行相应的代码编辑:代码如下:
private void button1_Click(object sender, EventArgs e)
{
//实例化TbAreasBll类,这里同样要引用一下Bll这个命名空间,否则会报错
TbAreasBll bll = new TbAreasBll(); //调用bll里的方法,获取条数
int row = bll.GetRecordCount(); //显示条数
MessageBox.Show("TbAreas表中有"+ row + "条记录"); }
需要注意的是,这个代码里同样需要先引用Bll,不然同样会出错,程序运行的结果为:
这与我前面用sql语句在数据库直接查询的数据是一致的。
好了,这个最简单的三层就记录到这里啦,虽然是如此的简单,但还是写了这么长,没办法,谁叫我菜呢。
以上的内容是观看传智播客赵晓虎老师的视频课所学,在此感谢传智播客。对于以上所述内容,发现有重大谬误的,欢迎口水留言,谢谢!
我的QQ:3074596466