2023年6月21日发(作者:)
三层架构详解
Power By: Tian
一、数据库
/*==========================================*/
/* DBMS name: Microsoft SQL Server 2000 */
/*==========================================*/
if exists (select 1
from sysobjects
where id = object_id('newsContent')
and type = 'U')
drop table newsContent
go
/*==========================================*/
/* Table: newsContent */
/*==========================================*/
create table newsContent (
ID int identity(1,1) primary key,
Title nvarchar(50) not null,
Content ntext not null,
AddDate datetime not null,
CategoryID int not null
)
go
二、项目文件架构
实现步骤为:4-3-6-5-2-1
ID
项目 描述 用途
项目引用实例所需文相关方法
1关系
1
件
Web
表现层 Web页和控件 引用BLL
引用
IDAL,GetContent()
2
BLL
业务逻辑层 业务逻辑组件
Model,使用DALFactory创建实例
ContentInfo
GetContentInfo(int id)
3
4
IDAL
数据访问层接每个DAL实现都要实现的口定义 一组接口
引用
Model
ContentInfo
GetContentInfo(int id)
Model
业务实体 传递各种数据的容器 无引用
引用IDAL,通过读取里设置的程序集,加载类的实例,返回给BLL使用。
SQLServSQLServererDAL
数据访问层
Microsoft SQL Server特引用
Model和IDAL,被SqlDataReader
ExecuteReader()
nt create()
5
DALFacto数据层的抽象
ry
工厂
创建反射,用来确定加载哪一个数据库访问程序集的类
6
定的Pet Shop DAL实现,PrepareCommand()
y加载的程
OracleDAOracle数据使用了IDAL接口
ContentInfo
序集,实现访问层
L
GetContentInfo(int id)
接口里的方法。
GetSqlServerConnectionString得到数据库连接字符串,也可省去该项目,在数据库访问组DBUtility
p件基础类
er中用static readonly
string
SqlConnectionString代替。
7
无引用
2 实现步骤过程
1、创建Model,实现业务实体。
2、创建IDAL,实现接口。
3、创建SQLServerDAL,实现接口里的方法。
4、增加里的配置信息,为SQLServerDAL的程序集。
5、创建DALFactory,返回程序集的指定类的实例。
6、创建BLL,调用DALFactory,得到程序集指定类的实例,完成数据操作方法。
7、创建WEB,调用BLL里的数据操作方法。
注意:
1、里的程序集名称必须与SQLServerDAL里的输出程序集名称一致。
2、DALFactory里只需要一个DataAccess类,可以完成创建所有的程序集实例。
3、项目创建后,注意修改各项目的默认命名空间和程序集名称。
4、注意修改解决方案里的项目依赖。
5、注意在解决方案里增加各项目引用。
三、各层间的访问过程
1、传入值,将值进行类型转换(为整型)。
2、创建BLL层的对象c,通过对象c访问BLL层的方法GetContentInfo(ID)调用BLL层。
3、BLL层方法GetContentInfo(ID)中取得数据访问层SQLServerDAL的实例,实例化IDAL层的接口对象dal,这个对象是由工厂层DALFactory创建的,然后返回IDAL层传入值所查找的内容的方法tentInfo(id)。
4、数据工厂通过配置文件中给定的webdal字串访问SQLServerDAL层,返回一个完整的调用SQLServerDAL层的路径给 BLL层。
5、到此要调用SQLServerDAL层,SQLServerDAL层完成赋值Model层的对象值为空,给定一个参数,调用SQLServerDAL层的SqlHelper的ExecuteReader方法,读出每个字段的数据赋值给以定义为空的Model层的对象。
36、SqlHelper执行sql命令,返回一个指定连接的数据库记录集,在这里需要引用参数类型,提供为打开连接命令执行做好准备PrepareCommand。
7、返回Model层把查询得到的一行记录值赋值给SQLServerDAL层的引入的Model层的对象ci,然后把这个对象返回给BLL。
8、回到Web层的BLL层的方法调用,把得到的对象值赋值给Lable标签,在前台显示给界面
四、项目中的文件清单
1、DBUtility项目
(1)
using System;
using uration;
namespace DBUtility
{
///
/// ConnectionInfo 的摘要说明。
///
public class ConnectionInfo
{
public static string GetSqlServerConnectionString()
{
return tings["SQLConnString"];
}
}
}
2、SQLServerDAL项目
(1)抽象类
using System;
using ;
using ent;
using DBUtility;
namespace SQLServerDAL
{
4 ///
/// SqlHelper 的摘要说明。
///
public abstract class SqlHelper
{
public static readonly string
CONN_STR = ServerConnectionString();
///
/// 用提供的函数,执行SQL命令,返回一个从指定连接的数据库记录集
///
///
/// 例如:
/// SqlDataReader r = ExecuteReader(connString, Procedure,
"PublishOrders", new SqlParameter("@prodid", 24));
///
/// SqlConnection有效的SQL连接字符串
/// CommandType:、Procedure
/// SQL语句或存储过程
/// SqlParameter[]参数数组
///
public static SqlDataReader ExecuteReader(string connString, CommandType cmdType,
string cmdText, params SqlParameter[] cmdParms)
{
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(connString);
// 我们在这里用 try/catch 是因为如果这个方法抛出异常,我们目的是关闭数据库连接,再抛出异常,
// 因为这时不会有DataReader存在,此后onnection将不会工作。
try
{
PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
SqlDataReader rdr = eReader(onnection);
();
return rdr;
}
catch
{
();
throw;
}
5 }
///
/// 为执行命令做好准备:打开数据库连接,命令语句,设置命令类型(SQL语句或存储过程),函数语取。
///
/// SqlCommand 组件
/// SqlConnection 组件
/// SqlTransaction 组件,可以为null
/// 语句类型:、Procedure
/// SQL语句,可以为存储过程
/// SQL参数数组
private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction
trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
{
if ( != )
();
tion = conn;
dText = cmdText;
if (trans != null)
ction = trans;
dType = cmdType;
if (cmdParms != null)
{
foreach (SqlParameter parm in cmdParms)
(parm);
}
}
}
}
(2)类
using System;
using ;
using ent;
using Model;
using IDAL;
6
namespace SQLServerDAL
{
///
/// Content 的摘要说明。
///
public class Content : IContent
{
private const string PARM_ID = "@ID";
//这里的SQL与下面的ci ContentInfo形参要匹配
private const string SQL_SELECT_CONTENT = "Select ID, Title, CategoryID, AddDate, Content
From newsContent Where ID = @ID";
public ContentInfo GetContentInfo(int id)
{
//创意文章内容类
ContentInfo ci = null;
//创建一个参数
SqlParameter parm = new SqlParameter(PARM_ID, , 8);
//赋上ID值
= id;
using (SqlDataReader sdr = eReader(_STR,
, SQL_SELECT_CONTENT, parm))
{
if (())
{
ci = new ContentInfo(32(0), ing(1), 32(2),
eTime(3), ing(4));
}
}
return ci;
}
}
}
3、Model项目
(1)
using System;
namespace Model
{
///
/// Class1 的摘要说明。
///
7 public class ContentInfo
{
private int _ID;
private string _Content;
private string _Title;
private DateTime _AddDate;
private int _clsID;
//private int _tmpID;
///
/// 文章内容构造函数
///
/// 文章流水号ID
/// 文章内容
/// 文章标题
/// 文章来源
/// 文章的分类属性ID
/// 文章的模板属性ID
//public ContentInfo(int id, string title, int clsid,DateTime addDate,string content,
string from, int tmpid)
public ContentInfo(int id, string title, int clsid, DateTime addDate, string content)
{
this._ID = id;
this._Content = content;
this._Title = title;
this._AddDate = addDate;
this._clsID = clsid;
}
//属性
public int ID
{
get { return _ID; }
}
public string Content
{
get { return _Content; }
}
public string Title
{
get { return _Title; }
}
public DateTime AddDate
{
get { return _AddDate; }
}
8 public int ClsID
{
get { return _clsID; }
}
}
}
4、IDAL项目
(1)
using System;
using Model;
namespace IDAL
{
///
/// 文章内容操作接口
///
public interface IContent
{
///
/// 取得文章的内容。
///
/// 文章的ID
///
ContentInfo GetContentInfo(int id);
}
}
5、DALFactory项目
(1)
using System;
using tion;
using uration;
using IDAL;
namespace DALFactory
{
///
/// 工产模式实现文章接口。
///
9 public class Content
{
public static nt Create()
{
// 这里可以查看 DAL 接口类。
string path =
tings["WebDAL"].ToString();
string className = path + ".Content";
// 用配置文件指定的类组合
return (nt)(path).CreateInstance(className);
}
}
}
6、BLL项目
(1)
using System;
using IDAL;
using Model;
namespace BLL
{
///
/// Content 的摘要说明。
///
public class Content
{
public ContentInfo GetContentInfo(int id)
{
// 取得从数据访问层取得一个文章内容实例
IContent dal = ();
// 用DAL查找文章内容
return tentInfo(id);
}
}
}
7、Web项目
1、:
10
Catalog=StudentInfo;User ID=sa;Password=8808708 "/>
2、
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind=""
Inherits="m1" %>
"/TR/xhtml1/DTD/">
3、后台调用显示:
using System;
using c;
using ;
using ;
using ;
//using trols;
using BLL;
using Model;
namespace Web
{
public partial class WebForm1 :
{
protected tlblMsg;
private ContentInfo ci;
private void Page_Load(object sender, rgs e)
{
if (!Back)
{
GetContent("1");
}
}
private void GetContent(string id)
{
int ID = (id);
Content c = new Content();
13 ci = tentInfo(ID);
if (ci != null)
{
= ;
= ng("yyyy-MM-dd");
= t;
}
else
{
= "没有找到这篇文章";
}
}
}
}
4、WebComponents项目
(1)
using System;
using ;
namespace ponents
{
///
/// CleanString 的摘要说明。
///
public class CleanString
{
public static int GetInt(string inputString)
{
try
{
return 32(inputString);
}
catch
{
return 0;
}
}
public static string InputText(string inputString, int maxLength)
{
StringBuilder retVal = new StringBuilder();
14 // check incoming parameters for null or blank string
if ((inputString != null) && (inputString != ))
{
inputString = ();
//chop the string incase the client-side max length
//fields are bypassed to prevent buffer over-runs
if ( > maxLength)
inputString = ing(0, maxLength);
//convert some harmful symbols incase the regular
{
{
(
(
(
(inputString[i]);
}
}
e( }
}
}
}
//expression validators are changed
for (int i = 0; i < ; i++)
switch (inputString[i])
case '"':
""");
break;
case '<':
"<");
break;
case '>':
">");
break;
default:
break;
// Replace single quotes with white space
"'", " ");
return ng();
1516
PS:项目结构图
2023年6月21日发(作者:)
三层架构详解
Power By: Tian
一、数据库
/*==========================================*/
/* DBMS name: Microsoft SQL Server 2000 */
/*==========================================*/
if exists (select 1
from sysobjects
where id = object_id('newsContent')
and type = 'U')
drop table newsContent
go
/*==========================================*/
/* Table: newsContent */
/*==========================================*/
create table newsContent (
ID int identity(1,1) primary key,
Title nvarchar(50) not null,
Content ntext not null,
AddDate datetime not null,
CategoryID int not null
)
go
二、项目文件架构
实现步骤为:4-3-6-5-2-1
ID
项目 描述 用途
项目引用实例所需文相关方法
1关系
1
件
Web
表现层 Web页和控件 引用BLL
引用
IDAL,GetContent()
2
BLL
业务逻辑层 业务逻辑组件
Model,使用DALFactory创建实例
ContentInfo
GetContentInfo(int id)
3
4
IDAL
数据访问层接每个DAL实现都要实现的口定义 一组接口
引用
Model
ContentInfo
GetContentInfo(int id)
Model
业务实体 传递各种数据的容器 无引用
引用IDAL,通过读取里设置的程序集,加载类的实例,返回给BLL使用。
SQLServSQLServererDAL
数据访问层
Microsoft SQL Server特引用
Model和IDAL,被SqlDataReader
ExecuteReader()
nt create()
5
DALFacto数据层的抽象
ry
工厂
创建反射,用来确定加载哪一个数据库访问程序集的类
6
定的Pet Shop DAL实现,PrepareCommand()
y加载的程
OracleDAOracle数据使用了IDAL接口
ContentInfo
序集,实现访问层
L
GetContentInfo(int id)
接口里的方法。
GetSqlServerConnectionString得到数据库连接字符串,也可省去该项目,在数据库访问组DBUtility
p件基础类
er中用static readonly
string
SqlConnectionString代替。
7
无引用
2 实现步骤过程
1、创建Model,实现业务实体。
2、创建IDAL,实现接口。
3、创建SQLServerDAL,实现接口里的方法。
4、增加里的配置信息,为SQLServerDAL的程序集。
5、创建DALFactory,返回程序集的指定类的实例。
6、创建BLL,调用DALFactory,得到程序集指定类的实例,完成数据操作方法。
7、创建WEB,调用BLL里的数据操作方法。
注意:
1、里的程序集名称必须与SQLServerDAL里的输出程序集名称一致。
2、DALFactory里只需要一个DataAccess类,可以完成创建所有的程序集实例。
3、项目创建后,注意修改各项目的默认命名空间和程序集名称。
4、注意修改解决方案里的项目依赖。
5、注意在解决方案里增加各项目引用。
三、各层间的访问过程
1、传入值,将值进行类型转换(为整型)。
2、创建BLL层的对象c,通过对象c访问BLL层的方法GetContentInfo(ID)调用BLL层。
3、BLL层方法GetContentInfo(ID)中取得数据访问层SQLServerDAL的实例,实例化IDAL层的接口对象dal,这个对象是由工厂层DALFactory创建的,然后返回IDAL层传入值所查找的内容的方法tentInfo(id)。
4、数据工厂通过配置文件中给定的webdal字串访问SQLServerDAL层,返回一个完整的调用SQLServerDAL层的路径给 BLL层。
5、到此要调用SQLServerDAL层,SQLServerDAL层完成赋值Model层的对象值为空,给定一个参数,调用SQLServerDAL层的SqlHelper的ExecuteReader方法,读出每个字段的数据赋值给以定义为空的Model层的对象。
36、SqlHelper执行sql命令,返回一个指定连接的数据库记录集,在这里需要引用参数类型,提供为打开连接命令执行做好准备PrepareCommand。
7、返回Model层把查询得到的一行记录值赋值给SQLServerDAL层的引入的Model层的对象ci,然后把这个对象返回给BLL。
8、回到Web层的BLL层的方法调用,把得到的对象值赋值给Lable标签,在前台显示给界面
四、项目中的文件清单
1、DBUtility项目
(1)
using System;
using uration;
namespace DBUtility
{
///
/// ConnectionInfo 的摘要说明。
///
public class ConnectionInfo
{
public static string GetSqlServerConnectionString()
{
return tings["SQLConnString"];
}
}
}
2、SQLServerDAL项目
(1)抽象类
using System;
using ;
using ent;
using DBUtility;
namespace SQLServerDAL
{
4 ///
/// SqlHelper 的摘要说明。
///
public abstract class SqlHelper
{
public static readonly string
CONN_STR = ServerConnectionString();
///
/// 用提供的函数,执行SQL命令,返回一个从指定连接的数据库记录集
///
///
/// 例如:
/// SqlDataReader r = ExecuteReader(connString, Procedure,
"PublishOrders", new SqlParameter("@prodid", 24));
///
/// SqlConnection有效的SQL连接字符串
/// CommandType:、Procedure
/// SQL语句或存储过程
/// SqlParameter[]参数数组
///
public static SqlDataReader ExecuteReader(string connString, CommandType cmdType,
string cmdText, params SqlParameter[] cmdParms)
{
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(connString);
// 我们在这里用 try/catch 是因为如果这个方法抛出异常,我们目的是关闭数据库连接,再抛出异常,
// 因为这时不会有DataReader存在,此后onnection将不会工作。
try
{
PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
SqlDataReader rdr = eReader(onnection);
();
return rdr;
}
catch
{
();
throw;
}
5 }
///
/// 为执行命令做好准备:打开数据库连接,命令语句,设置命令类型(SQL语句或存储过程),函数语取。
///
/// SqlCommand 组件
/// SqlConnection 组件
/// SqlTransaction 组件,可以为null
/// 语句类型:、Procedure
/// SQL语句,可以为存储过程
/// SQL参数数组
private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction
trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
{
if ( != )
();
tion = conn;
dText = cmdText;
if (trans != null)
ction = trans;
dType = cmdType;
if (cmdParms != null)
{
foreach (SqlParameter parm in cmdParms)
(parm);
}
}
}
}
(2)类
using System;
using ;
using ent;
using Model;
using IDAL;
6
namespace SQLServerDAL
{
///
/// Content 的摘要说明。
///
public class Content : IContent
{
private const string PARM_ID = "@ID";
//这里的SQL与下面的ci ContentInfo形参要匹配
private const string SQL_SELECT_CONTENT = "Select ID, Title, CategoryID, AddDate, Content
From newsContent Where ID = @ID";
public ContentInfo GetContentInfo(int id)
{
//创意文章内容类
ContentInfo ci = null;
//创建一个参数
SqlParameter parm = new SqlParameter(PARM_ID, , 8);
//赋上ID值
= id;
using (SqlDataReader sdr = eReader(_STR,
, SQL_SELECT_CONTENT, parm))
{
if (())
{
ci = new ContentInfo(32(0), ing(1), 32(2),
eTime(3), ing(4));
}
}
return ci;
}
}
}
3、Model项目
(1)
using System;
namespace Model
{
///
/// Class1 的摘要说明。
///
7 public class ContentInfo
{
private int _ID;
private string _Content;
private string _Title;
private DateTime _AddDate;
private int _clsID;
//private int _tmpID;
///
/// 文章内容构造函数
///
/// 文章流水号ID
/// 文章内容
/// 文章标题
/// 文章来源
/// 文章的分类属性ID
/// 文章的模板属性ID
//public ContentInfo(int id, string title, int clsid,DateTime addDate,string content,
string from, int tmpid)
public ContentInfo(int id, string title, int clsid, DateTime addDate, string content)
{
this._ID = id;
this._Content = content;
this._Title = title;
this._AddDate = addDate;
this._clsID = clsid;
}
//属性
public int ID
{
get { return _ID; }
}
public string Content
{
get { return _Content; }
}
public string Title
{
get { return _Title; }
}
public DateTime AddDate
{
get { return _AddDate; }
}
8 public int ClsID
{
get { return _clsID; }
}
}
}
4、IDAL项目
(1)
using System;
using Model;
namespace IDAL
{
///
/// 文章内容操作接口
///
public interface IContent
{
///
/// 取得文章的内容。
///
/// 文章的ID
///
ContentInfo GetContentInfo(int id);
}
}
5、DALFactory项目
(1)
using System;
using tion;
using uration;
using IDAL;
namespace DALFactory
{
///
/// 工产模式实现文章接口。
///
9 public class Content
{
public static nt Create()
{
// 这里可以查看 DAL 接口类。
string path =
tings["WebDAL"].ToString();
string className = path + ".Content";
// 用配置文件指定的类组合
return (nt)(path).CreateInstance(className);
}
}
}
6、BLL项目
(1)
using System;
using IDAL;
using Model;
namespace BLL
{
///
/// Content 的摘要说明。
///
public class Content
{
public ContentInfo GetContentInfo(int id)
{
// 取得从数据访问层取得一个文章内容实例
IContent dal = ();
// 用DAL查找文章内容
return tentInfo(id);
}
}
}
7、Web项目
1、:
10
Catalog=StudentInfo;User ID=sa;Password=8808708 "/>
2、
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind=""
Inherits="m1" %>
"/TR/xhtml1/DTD/">
3、后台调用显示:
using System;
using c;
using ;
using ;
using ;
//using trols;
using BLL;
using Model;
namespace Web
{
public partial class WebForm1 :
{
protected tlblMsg;
private ContentInfo ci;
private void Page_Load(object sender, rgs e)
{
if (!Back)
{
GetContent("1");
}
}
private void GetContent(string id)
{
int ID = (id);
Content c = new Content();
13 ci = tentInfo(ID);
if (ci != null)
{
= ;
= ng("yyyy-MM-dd");
= t;
}
else
{
= "没有找到这篇文章";
}
}
}
}
4、WebComponents项目
(1)
using System;
using ;
namespace ponents
{
///
/// CleanString 的摘要说明。
///
public class CleanString
{
public static int GetInt(string inputString)
{
try
{
return 32(inputString);
}
catch
{
return 0;
}
}
public static string InputText(string inputString, int maxLength)
{
StringBuilder retVal = new StringBuilder();
14 // check incoming parameters for null or blank string
if ((inputString != null) && (inputString != ))
{
inputString = ();
//chop the string incase the client-side max length
//fields are bypassed to prevent buffer over-runs
if ( > maxLength)
inputString = ing(0, maxLength);
//convert some harmful symbols incase the regular
{
{
(
(
(
(inputString[i]);
}
}
e( }
}
}
}
//expression validators are changed
for (int i = 0; i < ; i++)
switch (inputString[i])
case '"':
""");
break;
case '<':
"<");
break;
case '>':
">");
break;
default:
break;
// Replace single quotes with white space
"'", " ");
return ng();
1516
PS:项目结构图
发布评论