.net三层结构初探分析

对于学习,我选择了ACCESS数据库+存储过程的方式,这里记录的是我个人的学习体会和笔记,与网上的可能有不同之处,观点也不可能全部相同。

为什么使用三层结构:

首先要明确,三层结构并不能使系统变快,实际上它会比起“单类结构”慢。但越来越多人使用三层结构开发,为啥呢?我在使用中,发现三层结构十分清晰,一个类,一个文件你该放在哪层就放哪层,不会象单类结构那样全部放到App_Data中,造成结构混乱。当然,使用三层结构的原因肯定不是那么肤浅,它对团队开发,系统可维护性有十分重要的意义。

三层结构是代码量增多,且代码多重复?

确实,三层代码要写很多很白痴,很简单的代码,比如MODEL这个实体类,如果你需要一个admin的实体,那么你需要写这样的代码:

复制代码 代码如下:

public class admin

{

private int? _id;

private string _sname;

private string _spassword;

public int? id

{

set { _id = value; }

get { return _id; }

}

public string sname

{

set { _sname = value; }

get { return _sname; }

}

public string spassword

{

set { _spassword = value; }

get { return _spassword; }

}

}

而有多个实体的话,你要再写这些白痴代码,为什么叫它白痴代码?因为这些代码你看着个表就可以写出来了。一次和老汤讨论中,介绍了一个软件,叫做“动软.Net代码生成器”,这些白痴代码让这个软件自己去生成吧!在这里也推荐大家用这个软件,可以减少很多代码量,BLL,DAL,WEB层的代码都可以去生成,但要完全符合使用的话,还需要自己做些修改。

下面讲讲我理解的三层,先上张图1:

.net三层结构初探分析

WEB :界面层,其实就是一个网站。

BLL:逻辑处理层。

DAL:数据访问层

DBUtility:数据层基类

Model:实体类

Common:存放公用函数

.net三层结构初探分析

图2

这里需要讲讲那个DBUtility这个层,你可以看到有4个文件:

1、DbHelperOleDb.cs:用于SQL语句

2、DbHelperOleDbP.cs:用于存储过程

3、DbHelperOleDbS.cs:用于具体实现,比如“根据条件判断是否存在”、“返回最大的ID”...

4、PubConstant.cs:数据库连接代码

三层结构要求不能跨层访问,在图1中大家可以看到,3个层之间是逐层依赖的。与普通“单类结构”最明显的区别是,这里举一个添加数据的例子(伪代码):

单类结构(直接依赖于数据基类):

string sname = "阿会楠";

string surl     = "sosuo8.com";

string strSql = "insert into admin(sname,surl) values('" + sname + "','" + surl + ')";

DB.exeSQL(strSql);

我想对于单类结构来说,总是在WEB层拼凑SQL语句,然后调用数据操作类执行SQL语句,这样速度确实快一些。

看看三层结构

web层:

string sname = "阿会楠";

string surl = "sosuo8.com";

Model.admin model  = new Model.admin();//实体类

model.sname = sname;

mode.surl     = surl:

BLL.admin bll  = new BLL.admin();

bll.Add(model);

BLL层:

public void Add(MODEL.admin model)

{

dal.Add(model);

}

DAL层(需要依赖于DBUtility数据基类):

public void Add(Model.admin model)

{

string strSql = "insert into admin(sname,surl) values('" + model.sname + "','" + model.surl + "')":

DB.executeSQL(strSql);

}

Model实体类:

private string _sname;

private string _surl:

public string sname

{

set{_sname = value;}

get{return _sname};

}

public string surl

{

set{_surl = value;}

get{return _surl;}

}

你看出之间一层层的依赖关系了吗?“单类结构”直接就是WEB->DBUtility,而三层是WEB->BLL->DAL->DBUtility,MODEL作为实体类都可以不算一个层,COMMON也是,DBUtlity也是,它们只能算是把具有共同使用功能的代码堆放在一起。所以,三层就是WEB(界面层)->BLL(逻辑处理层)->DAL(数据访问层),并且是层层依赖。而后面引申出来的项目(COMMON,MODEL,DBUtlity),并不算层。按我理解是这样,如果有什么理解错误或不妥的地方欢迎指出,大家一起讨论。

最好的学习方法就是看代码,我写了比较简单的给大家学习下:

.net三层结构初探分析

下面贴出相关代码:

web.config

<appSettings>

<add key="ConnectionString" value="Provider=Microsoft.Jet.OleDb.4.0;Data Source=|DataDirectory|data.mdb" />

</appSettings>

DBUtility--PubConstant.cs(连接字符串)

复制代码 代码如下:

using System;

using System.Configuration;

namespace MyCms.DBUtility

{

public class PubConstant

{

public static string ConnectionString

{

get

{

return ConfigurationSettings.AppSettings["ConnectionString"];

}

}

}

}

DBUtility--DbHelperOleDb.cs(数据基类SQL语句)

复制代码 代码如下:

using System;

using System.Collections;

using System.Text;

using System.Data;

using System.Data.OleDb;

namespace MyCms.DBUtility

{

//数据访问基类(基于OleDb)

public partial class DbHelperOleDb

{

//数据库连接字符串,在web.config中配置

public static string ConnectionString = PubConstant.ConnectionString;

public DbHelperOleDb()

{

}

/// <summary>

/// 执行SQL语句,返回影响的记录数

/// </summary>

/// <param name="strSql">SQL语句</param>

/// <returns>影响的记录数</returns>

public static int ExecuteSql(string strSql)

{

using (OleDbConnection conn = new OleDbConnection(ConnectionString))

{

using (OleDbCommand cmd = new OleDbCommand(strSql, conn))

{

try

{

conn.Open();

return cmd.ExecuteNonQuery();

}

catch(OleDbException E)

{

conn.Close();

throw new Exception(E.Message);

}

}

}

}

/// <summary>

/// 执行多条SQL语句,实现数据库事务

/// </summary>

/// <param name="SqlStrList">多条SQL语句</param>

public static void ExecuteSqlTran(ArrayList SqlStrList)

{

using (OleDbConnection conn = new OleDbConnection(ConnectionString))

{

conn.Open();

OleDbCommand cmd = new OleDbCommand();

cmd.Connection = conn;

OleDbTransaction tx = conn.BeginTransaction();

cmd.Transaction = tx;

try

{

for (int n = 0; n < SqlStrList.Count; n++)

{

string strSql = SqlStrList[n].ToString();

if (strSql.Trim().Length > 1)

{

cmd.CommandText = strSql;

cmd.ExecuteNonQuery();

}

}

tx.Commit();

}

catch (System.Data.OleDb.OleDbException E)

{

tx.Rollback();

throw new Exception(E.Message);

}

}

}

/// <summary>

/// 执行带一个存储过程参数的SQL语句

/// </summary>

/// <param name="strSql">SQL语句</param>

/// <param name="content">参数内容,比如一个字段是格式复杂的文章</param>

/// <returns>影响的记录数</returns>

public static int ExecuteSinglePro(string strSql, string content)

{

using (OleDbConnection conn = new OleDbConnection(ConnectionString))

{

OleDbCommand cmd = new OleDbCommand(strSql, conn);

OleDbParameter myParameter = new OleDbParameter("@content",OleDbType.VarChar);

myParameter.Value = content;

cmd.Parameters.Add(myParameter);

try

{

conn.Open();

return cmd.ExecuteNonQuery();

}

catch (OleDbException E)

{

throw new Exception(E.Message);

}

finally

{

cmd.Dispose();

conn.Close();

}

}

}

/// <summary>

/// 执行一条计算查询结果语句,返回查询结果

/// </summary>

/// <param name="strSql">SQL语句</param>

/// <returns>查询结果</returns>

public static object GetSingle(string strSql)

{

using (OleDbConnection conn = new OleDbConnection(ConnectionString))

{

using (OleDbCommand cmd = new OleDbCommand(strSql, conn))

{

try

{

conn.Open();

object obj = cmd.ExecuteScalar();

if ((Equals(obj, null)) || Equals(obj, DBNull.Value))

{

return null;

}

else

{

return obj;

}

}

catch (OleDbException E)

{

conn.Close();

throw new Exception(E.Message);

}

}

}

}

/// <summary>

/// 返回OleDbDataReader

/// </summary>

/// <param name="strSql">查询语句</param>

/// <returns>OleDbDataReader</returns>

public static OleDbDataReader ExecuteReader(string strSql)

{

OleDbDataReader dr = null;

using (OleDbConnection conn = new OleDbConnection(ConnectionString))

{

using(OleDbCommand cmd = new OleDbCommand(strSql,conn))

{

try

{

conn.Open();

cmd.CommandText = strSql;

cmd.CommandType = CommandType.Text;

dr = cmd.ExecuteReader();

}

catch

{

dr.Close();

conn.Close();

cmd.Dispose();

}

}

}

return dr;

}

/// <summary>

/// 执行查询语句,返回DataSet

/// </summary>

/// <param name="strSql">查询语句</param>

/// <returns>DataSet</returns>

public static DataSet Query(string strSql)

{

using (OleDbConnection conn = new OleDbConnection(ConnectionString))

{

DataSet ds = new DataSet();

try

{

conn.Close();

OleDbDataAdapter da = new OleDbDataAdapter(strSql, conn);

da.Fill(ds, "ds");

}

catch (OleDbException E)

{

throw new Exception(E.Message);

}

return ds;

}

}

}

}

DBUtility--DbHelperOleDbP.cs(数据基类存储过程)

复制代码 代码如下:

using System;

using System.Collections;

using System.Collections.Generic;

using System.Text;

using System.Data;

using System.Data.OleDb;

namespace MyCms.DBUtility

{

public partial class DbHelperOleDb

{

/// <summary>

/// 执行SQL语句,返回影响的记录数

/// </summary>

public static int ExecuteSql(string strSql, params OleDbParameter[] parms)

{

using (OleDbConnection conn = new OleDbConnection(ConnectionString))

{

using (OleDbCommand cmd = new OleDbCommand())

{

try

{

PrepareCmd(cmd, conn, null, strSql, parms);

int rows = cmd.ExecuteNonQuery();

cmd.Parameters.Clear();

return rows;

}

catch (OleDbException E)

{

throw new Exception(E.Message);

}

}

}

}

/// <summary>

/// 执行一条计算查询结果语句,返回查询结果(object)。

/// </summary>

/// <param name="SQLString">计算查询结果语句</param>

/// <returns>查询结果(object)</returns>

public static object GetSingle(string SQLString, params OleDbParameter[] cmdParms)

{

using (OleDbConnection connection = new OleDbConnection(ConnectionString))

{

using (OleDbCommand cmd = new OleDbCommand())

{

try

{

PrepareCmd(cmd, connection, null, SQLString, cmdParms);

object obj = cmd.ExecuteScalar();

cmd.Parameters.Clear();

if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))

{

return null;

}

else

{

return obj;

}

}

catch (System.Data.OleDb.OleDbException e)

{

throw new Exception(e.Message);

}

}

}

}

/// <summary>

/// 执行查询语句,返回OleDbDataReader

/// </summary>

/// <param name="strSQL">查询语句</param>

/// <returns>OleDbDataReader</returns>

public static OleDbDataReader ExecuteReader(string SQLString, params OleDbParameter[] cmdParms)

{

OleDbConnection connection = new OleDbConnection(ConnectionString);

OleDbCommand cmd = new OleDbCommand();

try

{

PrepareCmd(cmd, connection, null, SQLString, cmdParms);

OleDbDataReader myReader = cmd.ExecuteReader();

cmd.Parameters.Clear();

return myReader;

}

catch (System.Data.OleDb.OleDbException e)

{

throw new Exception(e.Message);

}

}

/// <summary>

/// 执行查询语句,返回DataSet

/// </summary>

/// <param name="SQLString">查询语句</param>

/// <returns>DataSet</returns>

public static DataSet Query(string SQLString, params OleDbParameter[] cmdParms)

{

using (OleDbConnection connection = new OleDbConnection(ConnectionString))

{

OleDbCommand cmd = new OleDbCommand();

PrepareCmd(cmd, connection, null, SQLString, cmdParms);

using (OleDbDataAdapter da = new OleDbDataAdapter(cmd))

{

DataSet ds = new DataSet();

try

{

da.Fill(ds, "ds");

cmd.Parameters.Clear();

}

catch (System.Data.OleDb.OleDbException ex)

{

throw new Exception(ex.Message);

}

return ds;

}

}

}

///添加存储过程参数

private static void PrepareCmd(OleDbCommand cmd, OleDbConnection conn, OleDbTransaction trans, string cmdText, OleDbParameter[] cmdParms)

{

if (conn.State == ConnectionState.Closed)

{

conn.Open();

}

cmd.Connection = conn;

cmd.CommandText = cmdText;

if (trans != null)

{

cmd.Transaction = trans;

}

cmd.CommandType = CommandType.Text;

if (cmdParms != null)

{

foreach (OleDbParameter parm in cmdParms)

cmd.Parameters.Add(parm);

}

}

/// <summary>

/// 执行多条SQL语句,实现数据库事务。

/// </summary>

/// <param name="SQLStringList">SQL语句的哈希表(key为sql语句,value是该语句的OleDbParameter[])</param>

public static void ExecuteSqlTran(Hashtable SQLStringList)

{

using (OleDbConnection conn = new OleDbConnection(ConnectionString))

{

conn.Open();

using (OleDbTransaction trans = conn.BeginTransaction())

{

OleDbCommand cmd = new OleDbCommand();

try

{

//循环

foreach (DictionaryEntry myDE in SQLStringList)

{

string cmdText = myDE.Key.ToString();

OleDbParameter[] cmdParms = (OleDbParameter[])myDE.Value;

PrepareCmd(cmd, conn, trans, cmdText, cmdParms);

int val = cmd.ExecuteNonQuery();

cmd.Parameters.Clear();

trans.Commit();

}

}

catch

{

trans.Rollback();

throw;

}

}

}

}

}

}

DBUtility--DbHelperOleDbS.cs(数据基类具体实现) 折叠展开C#复制代码

using System;

using System.Data;

using System.Data.OleDb;

using System.Text;

namespace MyCms.DBUtility

{

public partial class DbHelperOleDb

{

//根据条件判断是否存在

public static bool Exists(string strSql, params OleDbParameter[] parms)

{

object obj = DbHelperOleDb.GetSingle(strSql, parms);

int result;

if ((Equals(obj, null)) || (Equals(obj, DBNull.Value)))

{

result = 0;

}

else

{

result = int.Parse(obj.ToString());

}

if (result == 0)

{

return false;

}

else

{

return true;

}

}

}

}

DAL--admin.cs 折叠展开C#复制代码

using System;

using System.Collections.Generic;

using System.Text;

using System.Data;

using System.Data.OleDb;

using MyCms.DBUtility;

namespace MyCms.DAL

{

public class admin

{

public admin()

{

}

/// <summary>

/// 是否存在该记录

/// </summary>

public bool Exists(string sname)

{

StringBuilder strSql = new StringBuilder();

strSql.Append("select count(1) from admin");

strSql.Append(" where sname = @sname");

OleDbParameter[] parameters = {

new OleDbParameter("@sname",OleDbType.VarChar,50)};

parameters[0].Value = sname;

return DbHelperOleDb.Exists(strSql.ToString(), parameters);

}

/// <summary>

/// 增加一条记录

/// </summary>

public void Add(MyCms.MODEL.admin model)

{

StringBuilder strSql = new StringBuilder();

strSql.Append("insert into admin(");

strSql.Append("sname,spassword)");

strSql.Append(" values (");

strSql.Append("@sname,@spassword)");

OleDbParameter[] parameters = {

new OleDbParameter("@sname", OleDbType.VarChar,50),

new OleDbParameter("@spassword", OleDbType.VarChar,50)};

parameters[0].Value = model.sname;

parameters[1].Value = model.spassword;

DbHelperOleDb.ExecuteSql(strSql.ToString(), parameters);

}

/// <summary>

/// 更新一条数据

/// </summary>

public void Update(MyCms.MODEL.admin model)

{

StringBuilder strSql = new StringBuilder();

strSql.Append("update admin set ");

strSql.Append("sname=@sname,");

strSql.Append("spassword=@spassword");

strSql.Append(" where sname=@sname and spassword=@spassword ");

OleDbParameter[] parameters = {

new OleDbParameter("@sname", OleDbType.VarChar,50),

new OleDbParameter("@spassword", OleDbType.VarChar,50)};

parameters[0].Value = model.sname;

parameters[1].Value = model.spassword;

DbHelperOleDb.ExecuteSql(strSql.ToString(), parameters);

}

/// <summary>

/// 删除一条数据

/// </summary>

public void Delete(int id)

{

StringBuilder strSql = new StringBuilder();

strSql.Append("delete from admin ");

strSql.Append(" where id=@id ");

OleDbParameter[] parameters = {

new OleDbParameter("@id", OleDbType.Integer,4)};

parameters[0].Value = id;

DbHelperOleDb.ExecuteSql(strSql.ToString(), parameters);

}

/// 获取数据列表

public DataSet GetList(string strWhere)

{

StringBuilder strSql = new StringBuilder();

strSql.Append("select id,sname,spassword from admin ");

if (strWhere.Trim() != "")

{

strSql.Append(" where " + strWhere);

}

return DbHelperOleDb.Query(strSql.ToString());

}

}

}

BLL--admin.cs 折叠展开C#复制代码

using System;

using System.Data;

namespace MyCms.BLL

{

public class admin

{

private readonly MyCms.DAL.admin dal = new MyCms.DAL.admin();

public admin() { }

/// <summary>

/// 是否存在该记录

/// </summary>

public bool Exists(string sname)

{

return dal.Exists(sname);

}

/// <summary>

/// 增加一条记录

/// </summary>

public void Add(MyCms.MODEL.admin model)

{

dal.Add(model);

}

/// <summary>

/// 更新一条记录

/// </summary>

public void Update(MyCms.MODEL.admin model)

{

dal.Update(model);

}

/// <summary>

/// 删除一条记录

/// </summary>

public void Delete(int id)

{

dal.Delete(id);

}

/// <summary>

/// 获取数据列表

/// </summary>

public DataSet GetList(string strWhere)

{

return dal.GetList(strWhere);

}

/// <summary>

/// 获得数据列表

/// </summary>

public DataSet GetAllList()

{

return GetList("");

}

}

}

MODEL--admin.cs 折叠展开C#复制代码

using System;

using System.Collections.Generic;

using System.Text;

namespace MyCms.MODEL

{

public class admin

{

private int? _id;

private string _sname;

private string _spassword;

public int? id

{

set { _id = value; }

get { return _id; }

}

public string sname

{

set { _sname = value; }

get { return _sname; }

}

public string spassword

{

set { _spassword = value; }

get { return _spassword; }

}

}

}

default.aspx 折叠展开XML/HTML复制代码

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WEB._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>无标题页</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<table cellSpacing="0" cellPadding="0" width="100%" border="0">

<tr>

<td height="25" width="30%" align="right">

姓名 </td>

<td height="25" width="*" align="left">

<asp:TextBox id="txtsname" runat="server" Width="200px"></asp:TextBox>

</td></tr>

<tr>

<td height="25" width="30%" align="right">

密码 </td>

<td height="25" width="*" align="left">

<asp:TextBox id="txtspassword" runat="server" Width="200px"></asp:TextBox>

</td></tr>

<tr>

<td height="25" colspan="2"><div align="center">

<asp:Button ID="btnAdd" runat="server" Text="· 提交 ·" OnClick="btnAdd_Click" />

</div></td></tr>

</table>

</div>

<br />

数据显示:

<asp:Repeater ID="rptAdmin" runat="server">

<HeaderTemplate>

<table border="1">

<tr><th>ID</th><th>帐户</th><th>密码</th></tr>

</HeaderTemplate>

<ItemTemplate>

<tr>

<td><%#Eval("id") %></td>

<td><%#Eval("sname") %></td>

<td><%#Eval("spassword") %></td>

</tr>

</ItemTemplate>

<FooterTemplate>

</table>

</FooterTemplate>

</asp:Repeater>

</form>

</body>

</html>

default.aspx.cs 折叠展开C#复制代码

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using MyCms.BLL;

using MyCms.MODEL;

///阿会楠的练习 sosuo8.com

namespace WEB

{

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

bind();

}

/// 添加记录

protected void btnAdd_Click(object sender, EventArgs e)

{

string sname = this.txtsname.Text;

string spassword = this.txtspassword.Text;

MyCms.MODEL.admin model = new MyCms.MODEL.admin();

model.sname = sname;

model.spassword = spassword;

MyCms.BLL.admin bll = new MyCms.BLL.admin();

bll.Add(model);

bind();

}

/// 绑定数据

protected void bind()

{

MyCms.BLL.admin admin = new MyCms.BLL.admin();

this.rptAdmin.DataSource = admin.GetAllList();

this.rptAdmin.DataBind();

}

}

}

注明:大部分代码都来自“动软.Net代码生成器”

.net三层结构初探分析

net_sancen.rar