初探三层架构

时间:2022-07-01 05:34:09

在.net平台下目前盛行的框架有三层架构、MVC模式、MVVM模式等,各种框架都有其利弊,具体应用哪种框架都根据实际项目的需求来选择,不能评价哪种框架好,哪种宽假不好。今天就来初探一下三层架构的魅力。

三层架构:顾名思义,应该具有三个层(类),分别是:

模型层Model,也叫做实体层,一般我们将要用到数据库里面的字段都封装到这个里面来,并进行get;set;封装,以满足数据的读和写。

数据访问层DAL(Data    Access Layer),对数据库的操作一般都写在这里面,也就是写SQL语句。

业务逻辑层BLL( Business Logic Layer),调用DAL层中代码进行逻辑操作,比如:对于SQL语句中查询出来的值不能包含负数等。

特别注意:UI界面层不能直接调用DAL层。

下面以一个简单的例子来说明三层的用法

现在有一表tb_person,现在通过三层来完成对表数据进行增、删、改、查

Model层的代码:

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

namespace 简单的三层架构.Model
{
public class personModel
{
public int Id { get; set; }
public int Age { get; set; }
public string Name { get; set; }
}
}

DAL层的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using 简单的三层架构.Model;
using System.Data;
using System.Data.SqlClient;

namespace 简单的三层架构.DAL
{
class personDAL
{
//增
public int AddNew(personModel model)
{
string insertStr = "insert into tb_Person (Name,Age) values (@name,@age);select @@identity";
SqlParameter[] sp = {
new SqlParameter("@name",model.Name),
new SqlParameter("@age",model.Age)
};
sp[0].Value = model.Name;
sp[1].Value = model.Age;
int count = SQLHelper.ExecuteNonQuery(insertStr, sp);
//object count = SQLHelper.ExecuScalar("insert into tb_Person (Name,Age) values (@name,@age);select @@identity"
// ,new SqlParameter("@name", model.Name), new SqlParameter("@age", model.Age));
return Convert.ToInt32(count);
}
//删
public int DelData(personModel model)
{
string DelString = "Delete from tb_Person where Id=@id ";
SqlParameter sp=new SqlParameter("@id",DbType.Int32);
sp.Value=model.Id;
return SQLHelper.ExecuteNonQuery(DelString,sp);
}
//改
public int UpdateData(personModel model)
{
string UpdateString = "update tb_Person set Name=@name,Age=@age where Id=@id";
SqlParameter[] sp = { new SqlParameter("@name", DbType.String), new SqlParameter("@age", DbType.Int32), new SqlParameter("@id",DbType.Int32) };
sp[0].Value = model.Name;
sp[1].Value = model.Age;
sp[2].Value = model.Id;
return SQLHelper.ExecuteNonQuery(UpdateString,sp);
}
//查询一条数据
public personModel SelectData(int id)
{
string selectString = "select * from tb_Person where Id=@id";
SqlParameter sp = new SqlParameter("@id",DbType.Int32);
sp.Value =id;
DataTable dt = SQLHelper.getDataTable(selectString,sp);
if(dt.Rows.Count<=0)
{
return null;
}
else if (dt.Rows.Count == 1)
{
personModel model = new personModel();
DataRow dr = dt.Rows[0];
model.Id = (int)dr["Id"];
model.Name = (string)dr["Name"];
model.Age = Convert.ToInt32(dr["Age"]);
return model;
}
else//考虑意外情况,加入查询出来多个相同的id,则抛出异常
{
throw new Exception("出现多条数据!");
}
}
}
}

BLL层的代码:

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

namespace 简单的三层架构.BLL
{
class personBLL
{
//增
public int AddNew(personModel model)
{
return new personDAL().AddNew(model);
}
//删
public int DelData(personModel model)
{
return new personDAL().DelData(model);
}
//改
//BLL层进行逻辑的判断,DAL层只进行简单的数据库操作
public int UpdateData(personModel model)
{
if(model.Age<0)
{
throw new Exception("年龄");
}
return new personDAL().UpdateData(model);
}
//查询一条数据
public personModel SelectData(int id)
{
return new personDAL().SelectData(id);
}
}
}
UI界面层代码:

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 简单的三层架构.Model;
using 简单的三层架构.DAL;
using 简单的三层架构.BLL;

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

private void button1_Click(object sender, EventArgs e)
{
personModel person = new personModel();
person.Age = 23;
person.Name = "fengbo";
personBLL bll = new personBLL();
int a= bll.AddNew(person);
if(a>0){
MessageBox.Show("插入数据成功!");
}
}

private void button2_Click(object sender, EventArgs e)
{
personModel person = new personModel();
person.Id = 1;
personBLL bll = new personBLL();
int a = bll.DelData(person);
if(a>0)
{
MessageBox.Show("删除成功");
}

}

private void button3_Click(object sender, EventArgs e)
{
personModel model = new personModel();
model.Id = 2;
model.Name = "zhangsan";
model.Age = -21;
personBLL bll = new personBLL();
int a = bll.UpdateData(model);
if(a>0)
{
MessageBox.Show("更新成功");
}
}

private void button4_Click(object sender, EventArgs e)
{
personBLL bll = new personBLL();//这里实例化BLL层,不能去实例化DAL
personModel model = bll.SelectData(2);
MessageBox.Show(model.Name.ToString()+model.Age.ToString());
}
}
}

由于在DAL进行数据的操作时每次都得对数据库进行打开过关闭等重复的操作,我们这里封装了一个帮助类SQLHelper,由它去完成数据的增、删、改、查。

SQLHelper的代码:

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

namespace 简单的三层架构
{
public static class SQLHelper
{
//设置连接字符串
private static string conStr=ConfigurationManager.ConnectionStrings["conStr"].ConnectionString;
// 设置连接通道属性
private static SqlConnection conn;

public static SqlConnection Conn
{
get {
//要是连接通道没创建或者通道的连接状态中断,则重新建立连接通道
if(conn==null||conn.State==ConnectionState.Broken)
{
conn = new SqlConnection(conStr);
}
return conn;
}
}
/// <summary>
/// 带参数的查询
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="parameters">参数</param>
/// <returns></returns>
public static DataTable getDataTable(string sql,params SqlParameter[] parameters)
{
//创建命令对象
SqlCommand cmd = new SqlCommand(sql,Conn);
//判断是否有参数传递进来
if (parameters!=null && parameters.Length>0)
{
cmd.Parameters.AddRange(parameters);
}
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
try
{
da.Fill(dt);
}
catch (Exception ex)
{

throw ex;
}
return dt;
}
public static void OpenDB()
{
conn.Open();
}
public static void CloseDB()
{
conn.Close();
}
/// <summary>
/// 执行增删改操作
/// </summary>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <returns></returns>
public static int ExecuteNonQuery(string sql,params SqlParameter[] param)
{

SqlCommand cmd = new SqlCommand(sql,Conn);
if(param!=null && param.Length>0)
{
cmd.Parameters.AddRange(param);
}
OpenDB();
int res = 0;
try
{
res = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{

throw ex;
}
finally
{
CloseDB();
}
return res;
}
public static object ExecuScalar(string sql, params SqlParameter[] param)
{

SqlCommand cmd = new SqlCommand(sql, Conn);
if (param != null && param.Length > 0)
{
cmd.Parameters.AddRange(param);
}
OpenDB();
object res;
try
{
res = cmd.ExecuteScalar();
}
catch (Exception ex)
{

throw ex;
}
finally
{
CloseDB();
}
return res;
}

}
}
在SQLHelper中连接数据库的连接字符串为了不重复写,我们在项目中添加了一个APP.config的配置文件,在这里面将连接字符串以XML的形式写入

APP.config的代码:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="conStr" connectionString="Data Source=.;Initial Catalog=sanceng;User ID=sa;Password=admin"/>
</connectionStrings>
</configuration>

以上就是对三层的简单应用。做真实的项目可能还会遇到各种问题,到时候继续补充.......................