基于C# NET的WinForm项目,我们经常使用基于三层架构Q,来构建项目框架,这里简单的梳理-一下三层架构的相关知识。
我们通常所说的三层框架指的是DAL、BIL和UIL三层, 分别是数据层、业务逻辑层和界面层,以及与之搭配的实体类和通用类库,
下面分别概述
一、实体类--Model
●我们将数据存放在数据库中,数据表的结构,我们通常会用一个类来抽象, 表的属性就是类的属性,我们通常将表的一行存储在一个
类中。我们在Java中,通常将其称为实体类Entity,在C#中,我们通常将其称为Model。
●●我们可以看到,在SQLServer数据库中,char varchar nchar nvarchar都用String类型, int就对应Int。
●Model类库- 般来说需要被DAL、 BIL和U弓|用。我们定义了一个数据表,表结构如下.
表结构
●我们根据表的信息,创建了如下的实体类
namespace mtWeightModel
{
[Serializable] //表示可以序列化
public class User
{
public int Id { get; set; }
public String username { get; set; }
public String password { get; set; }
public int status { get; set; }
}
}
●我们可以看到,在SQLServer数据库中,char varchar nchar nvarchar都用String类型, int就对应Int。
●Model类库- 般来说需要被DAL、 BIL和U弓|用。
二、DAL-数据访问层- DataAccessLayer
●数据访问层,就是调用我们数据库访问方法,专注于数据的增删改查操作,构建SQL语询,构建参数等,以下是- 个典型DAL方法
namespace mtWeightDAL
{
/// <summary>
/// 用户访问数据类
/// </summary>
public class UserService
{
/// <summary>
/// 根据账号和密码比对用户信息
/// </summary>
/// <param name="objUser">包含用户名和密码的用户对象</param>
/// <returns>返回用户对象信息(若无用户信息则对象为null)</returns>
public User UserLogin(User objUser) {
String sql = "SELECT Id,username,password,status FROM Users where username=@username and password=@password";
SqlParameter[] param = new SqlParameter[] {
new SqlParameter("@username",objUser.username),
new SqlParameter("@password", objUser.password)
};
SqlDataReader objReader = SqlHelper.getReader(sql, param);
if (objReader.Read())
{
objUser.Id = Convert.ToInt32(objReader["Id"]);
objUser.status = Convert.ToInt32(objReader["status"]);
}
else {
objUser = null;
}
objReader.Close();
return objUser;
}
}
}
●这里用到了一个SqlHelper类, 使我们后面要单独说的数据库帮助类
●DAL就是根据业务求,构建SQL语询,构建参数,调用帮助类,获取结果, DAL层被BIL层调用
三、BLL-业务逻辑层- Business Logic Layer
●BLL层索要负责的,就是处理业务逻辑上的问题,比如在调用数据库访问之前,对数据的处理、判断等。下面是一 个最简单的业务逻
辑方法,不处理任何信息,只做参数传递。
namespace mtWeightBLL
{
/// <summary>
/// 用户业务逻辑类
/// </summary>
public class UserManager
{
//创建数据访问对象
private UserService objUserService = new UserService();
public User UserLogin(User objUser) {
return objUserService.UserLogin(objUser);
}
}
}
.那你可能就会有疑问,为什么不把业务逻辑和数据访问合在一起呢,偏要搞出两个层,不够此一举么。其实呢,我们分层解决问
题的意义就是,功能专一, 并且解耦我们的程序,我们在DAL层只关心我的数据库访问操作,我默认你给我的数据是合法的、正确
的,那至于你如何保证数据的合法性和正确性就是你要在BLL层里去做的了。
●BLL职被UIL层引用
四、UIL-用户表现层
●就是窗体Form
●这里有-个click事件
private void btnLogin_Click(object sender, EventArgs e)
{
//数据验证
if (this.txtUsername.Text.Trim().Length == 0) {
MessageBox.Show("请输入用户名", "登录提示");
this.txtUsername.Focus();
}
if (this.txtPassword.Text.Trim().Length == 0)
{
MessageBox.Show("请输入密码", "登录提示");
this.txtPassword.Focus();
}
// 封装对象
User objUser = new User {
username = this.txtUsername.Text.Trim(),
password = this.txtPassword.Text.Trim()
};
try
{
objUser = objUserManager.UserLogin(objUser);
if (objUser != null)
{
if (objUser.status == 1)
{
Program.objCurrentUser = objUser;
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
MessageBox.Show("用户被禁用,请联系管理员", "登录提示");
}
}
else {
MessageBox.Show("用户名或密码错误!", "登录提示");
}
}
catch (Exception ex)
{
MessageBox.Show("登录异常:"+ex.Message,"登录提示");
}
}
五、通用类库
●对于一些程序中到的其他封装的类库,可以统一放在这里,比如一些第三方类库等
六、数据库帮助类
●我们可以用过封装ADO.NET形成自己的一方法,但是我们知道在ADO.NET中SQLServer、 Access、 Mysq|和Oracle使用的是不
同的类,那么我们可能需要对每一个数据库封装- 套帮助类。 其中常用的方泡括非查询方法(两个重载[sq],[sq|,参数)和查询
類法(两个重载[sq],[sql,参数]),事务类方法、 存储过程类方法等。
●我们通常为会先规定一 个接口,然后在帮助类中实现结构。这样后期可以通过反射或工厂的方式来实现不同数据库的切换(后面另
说)。
●下面是我定义的一个简单的数据库帮助类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
namespace DbUtil
{
public class SqlHelper
{
private static String ConnString = ConfigurationManager.ConnectionStrings["ConnString"].ToString();
#region 格式化SQL语句
/// <summary>
/// 增删改非查询类方法
/// </summary>
/// <param name="sql">SQL语句</param>
/// <returns></returns>
public static int UPDATE(string sql) {
SqlConnection conn = new SqlConnection(ConnString);
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
conn.Open();
return cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally {
conn.Close();
}
}
/// <summary>
/// 返回单条结果查询类方法
/// </summary>
/// <param name="sql">SQL语句</param>
/// <returns></returns>
public static object getSingleResult(string sql)
{
SqlConnection conn = new SqlConnection(ConnString);
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
conn.Open();
return cmd.ExecuteScalar();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
conn.Close();
}
}
/// <summary>
/// 多条结果查询类方法
/// </summary>
/// <param name="sql">SQL语句</param>
/// <returns></returns>
public static SqlDataReader getReader(string sql)
{
SqlConnection conn = new SqlConnection(ConnString);
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
conn.Open();
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception ex)
{
conn.Close();
throw new Exception(ex.Message);
}
}
/// <summary>
/// 返回DataSet数据集方法
/// </summary>
/// <param name="sql">SQL语句</param>
/// <returns>结果集DataSet</returns>
public static DataSet getDataSet(string sql)
{
SqlConnection conn = new SqlConnection(ConnString);
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
try
{
conn.Open();
adapter.Fill(ds);
return ds;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally {
conn.Close();
}
}
#endregion
#region 带参数SQL语句
/// <summary>
/// 增删改非查询类方法
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="param">SQl参数</param>
/// <returns></returns>
public static int UPDATE(string sql,SqlParameter[] param)
{
SqlConnection conn = new SqlConnection(ConnString);
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
conn.Open();
cmd.Parameters.AddRange(param);
return cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
conn.Close();
}
}
/// <summary>
/// 返回单条结果查询类方法
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="param">SQL参数</param>
/// <returns></returns>
public static object getSingleResult(string sql, SqlParameter[] param)
{
SqlConnection conn = new SqlConnection(ConnString);
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
conn.Open();
cmd.Parameters.AddRange(param);
return cmd.ExecuteScalar();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
conn.Close();
}
}
/// <summary>
/// 多条结果查询类方法
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="param">SQL参数</param>
/// <returns></returns>
public static SqlDataReader getReader(string sql,SqlParameter[] param)
{
SqlConnection conn = new SqlConnection(ConnString);
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
conn.Open();
cmd.Parameters.AddRange(param);
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception ex)
{
conn.Close();
throw new Exception(ex.Message);
}
}
#endregion
}
}
项目创建
●首先创建解决方案的过程中,创建默认项目Windows窗体应用程序UIL
●然后分别在解决方案中添加类库项目DAL、BLL和CL (通用类库)和Model
●然后新建一个DBUtil类库,面放SQL Header类
●下面添加引用,从下网往上添加,先给DAL添加Mode和DBHelper的引用,再为BLL添加DAL和Model的引用,再为IL添加BLL和
Mode引用,然后在为要使用通用类库的项目添加CL的弓|用。
●引完成后: