首页 > 其他分享 >七层登录总结

七层登录总结

时间:2022-12-19 16:03:49浏览次数:37  
标签:总结 登录 七层 Cmd System DataTable new using public


宏观:要明确是如何从三层转七层

七层登录总结_c#


引用图片自:​​图片作者原文章​

实体层(entity)

:用来封装一些功能性代码,定义实体类型和实体集合,用来各层次传递参数用来存放用户输入的信息。用getset实现达到传递参数的方法达到可以可读可写,同时又有封装性。

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

namespace Entity
{
public class UserInfo
{
//定义用户ID字段
private int userid;
public int UserId
{
get { return userid; }
set { userid = value; }

}

//定义用户名
private string username;
public string UserName
{
get { return username; }
set { username = value; }
}
//定义密码字段
private string password;
public string PassWord
{
get { return password;}
set { password = value; }

}
}
}

接口层(IDAL)

:定义一个统一的接口方法selectuser,解除B层和D层的耦合,具体代码靠DAL
实现。

注意:因为返回值类型为DataTable ,所以应该引用数据的命名空间。

using System.Data;
Data是数据的意思。
顾名思义,引用这个dll即表示你的命名空间下有需要使用数据、数组的地方,可以直接使用数组类型,而不需要再添加前缀。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;

namespace IDAL
{
public interface LoginIDAL
{
DataTable selectUser(Entity.UserInfo userInfo);
}
}

数据访问层(DAL)

:提供基本的数据访问,该层将有关数据库的操作放在单独的一个类中,针对数据的增删改查。

DAL层会封装一个sqlHelper。目的是连接数据库实现对数据库的增删改查,这是为了服务于DAL层的。

首先有个构造函数连接上数据库,然后重载了对数据库的增删改查有无参数的方法,

LoginSqlHelper

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

namespace DAL
{
///<summary>
///SqlHhelper created by ZGY 2021年11月22日20:25:30
///</summary>
public class SqlHelper
{
private SqlConnection Conn = null;
private SqlCommand Cmd = null;
private SqlDataReader SqlSdr = null;


public SqlHelper()
{
//利用反射连接数据库
//除了要在上边添加命名空间,也要手动在类的引用里边添加引用才能生效
//这里的AppSetting要注意大小写

string strconn = ConfigurationManager.AppSettings["strConn"];
//实例化一个连接
Conn = new SqlConnection(strconn);

}
///<summary>
///打开数据库
///<summary/>
/// <returns>sqlConnection</returns>
private SqlConnection GetConn()
{
if (Conn.State != ConnectionState.Open)
{
try
{
Conn.Open();
}
catch (Exception ex)
{

Conn.Dispose();//没有成功打开,释放资源
throw new Exception("打开数据库失败!");

}

}
return Conn;

}
///<summary>
///执行不带参数的增删改操作
///<summary/>
///<param name="CmdText">执行的sql语句或者存储过程</param>
///<param name="CmdType">语句类型</param>
///
/// <returns>sqlConnection</returns>
public int ExecuteNonQuery(string CmdText, CommandType CmdType)
{
//数据库连接语句
int res;
try
{
Cmd = new SqlCommand(CmdText, GetConn());
Cmd.CommandType = CmdType;
res = Cmd.ExecuteNonQuery();


}
catch (Exception ex)
{

throw ex;
}
finally
{
if (Conn.State == ConnectionState.Open)
{
Conn.Close();

}
}
return res;


}

/// <summary>
/// 执行带参数的增删改操作
/// </summary>
/// <param name="CmdText">执行的SQL语句或存储过程</param>
/// <param name="parameters">参数</param>
/// <param name="CmdType">(SQL语句或存储过程)的类型</param>
/// <returns>返回增删改的操作数(受影响的行数)</returns>
public int ExecuteNonQuery(string CmdText, SqlParameter[] parameters,CommandType CmdType)
{
int res;

try
{
Cmd = new SqlCommand(CmdText, GetConn()); //先建立sql语句
Cmd.Parameters.AddRange(parameters); //再进行参数匹配
Cmd.CommandType = CmdType;
res = Cmd.ExecuteNonQuery();


}

catch (Exception ex)
{

throw ex;
}

finally
{
if (Conn.State==ConnectionState.Open)
{
Conn.Close();
}
}
return res;


}

/// <summary>
/// 执行不带参数的查询操作
/// </summary>
/// <param name="CmdText">执行的SQL语句或存储过程</param>
/// <param name="CmdType">(SQL语句或存储过程)类型</param>
/// <returns>查询后的数据</returns>
public DataTable ExecuteQuery(string CmdText, CommandType CmdType)
{
DataTable dt = new DataTable();
using (SqlSdr = Cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
Cmd = new SqlCommand(CmdText, GetConn());
Cmd.CommandType = CmdType;
dt.Load(SqlSdr);
}
return dt;

}

/// <summary>
/// 执行带参数的查询
/// </summary>
/// <param name="CmdText">执行的SQL语句或存储过程</param>
/// <param name="parameters">(SQL语句或存储过程)类型</param>
/// <param name="CmdType"></param>
/// <returns>查询后的数据</returns>


public DataTable ExecuteQuery(string CmdText, SqlParameter[] parameters, CommandType CmdType)
{



DataTable dt = new DataTable();
Cmd = new SqlCommand(CmdText, GetConn());

Cmd.CommandType = CmdType;
Cmd.Parameters.AddRange(parameters);
using (SqlSdr = Cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
dt.Load(SqlSdr);

}
return dt;
//DataTable dt = new DataTable();
//using (SqlSdr = Cmd.ExecuteReader(CommandBehavior.CloseConnection))
//{
// Cmd = new SqlCommand(CmdText, GetConn());
// Cmd.Parameters.AddRange(parameters);
// Cmd.CommandType = CmdType;
// dt.Load(SqlSdr);

//}
//return dt;


}

}
}

LoginDAL
这里的代码和配置文件息息相关,容易出现错误,容易出现的错误和解决办法都会放在文章最后奥。

DAL是为了实现IDAL层中的方法。对数据进行增删改查。

首先实例化一个sqlhelper,对数据库进行连接
然后声明一个sql参数的数组,将实体层中的参数值传给我们定义的参数中
然后再数据库中进行语句查询。
然后大家都返回到sqlhelper中的一个带参数查询的方法。

添加命名空间
using System.Data.SqlClient;
using System.Data;
using System.Configuration;

同时在DAL层里边要手动添加上面的引用
不然就会出现confurgationManager找不到的情况发生,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;


namespace DAL
{
public class LoginDAL : IDAL.LoginIDAL
{
public DataTable selectUser(Entity.UserInfo UserInfo)
{
//实例化一个数据查询对象uu
SqlHelper sqlHelper = new SqlHelper();
//传参
SqlParameter[] sqlParams = { new SqlParameter("@UserID", UserInfo.UserId), new SqlParameter("@PassWord", UserInfo.PassWord) };
//数据库选择要查询的数据
string sql = @"SELECT* FROM Users WHERE UserName = @UserID AND PassWord = @PassWord";
//将参数放在语句中
DataTable table = sqlHelper.ExecuteQuery(sql, sqlParams, CommandType.Text);


return table;
}

}
}

Factory(工厂层)

:定义一个接口层,实现BLL层和DAL层之间的数据传递,工厂层用到了抽象工厂+反射+配置文件,实现了不同数据库之间的连接,反射+配置文件

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

using System.Configuration;
using System.Reflection;

namespace Factory
{
public class LoginFactory
{
string StrDB = System.Configuration.ConfigurationManager.AppSettings["DB"]; //接收来自配置文件的数据
public IDAL.LoginIDAL CreateUser()
{
string ClassName = StrDB + "." + "LoginDAL";//DAL层的类名
return (IDAL.LoginIDAL)Assembly.Load(StrDB).CreateInstance(ClassName);//反射+工厂的应用
}


}
}

BLL层:

执行特定的业务逻辑。
登陆界面BLL层:1.对D层返回来的信息进行判断,用户是否存在的问题,2.如果存在还会产生,返回更加具体的信息给U层

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

using System.Data;

namespace BLL
{
public class LoginBLL
{
public bool UserBLL(Entity.UserInfo UserInfo)
{
Factory.LoginFactory fact = new Factory.LoginFactory(); //实例化工厂
IDAL.LoginIDAL idal = fact.CreateUser(); //调用工厂方法创建接口
DataTable table = idal.selectUser(UserInfo); //接收D层的返回值
bool flag;

if (table.Rows.Count == 0)
{
flag = false;
}
else
{
flag = true;
}

return flag;



}


}
}

Facade层,

提供一个门面,一个UI层可访问多个BLL层,提供一个外观层,好比提供了一个简单的入口,降低UI层和BLL层之间的耦合度。

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

namespace Facade
{
public class LoginFacade
{
public Boolean SelectUser(Entity.UserInfo user)
{
bool flag;
BLL.LoginBLL userBLL = new BLL.LoginBLL(); //实例化一个b层的对象
flag = userBLL.UserBLL(user); //接收B层传过来的信号
return flag;


}


}
}

UI层:

1、提供一个登陆界面,获取用户输入的信息
2、给用户提供特定的业务功能

LoginUI

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public void btnLogin_Click(object sender, EventArgs e)
{
if (txtUserID.Text.Trim() == "")
{
MessageBox.Show("用户名不能为空,请输入用户名", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
if (txtPassword.Text == "")
{
MessageBox.Show("密码不能为空,请输入密码", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
//try
//{

Entity.UserInfo user = new Entity.UserInfo();
user.UserId = Convert.ToInt32(txtUserID.Text.Trim());
user.PassWord = txtPassword.Text;


Boolean flag = false;
Facade.LoginFacade FLogin = new Facade.LoginFacade(); //实例化外观

flag = FLogin.SelectUser(user);//调用外观方法,返回给user

if (flag != false)
{
MessageBox.Show("登录成功");
this.Hide();//隐藏当前窗体
MessageBox.Show("登录成功", "恭喜", MessageBoxButtons.OK);
}
else
{
MessageBox.Show("密码或用户名错误");
}

//}
//catch (Exception)
//{

// throw;
//}
}



private void Form1_Load(object sender, EventArgs e)
{

}

private void butCancel_Click_1(object sender, EventArgs e)
{
System.Environment.Exit(0);//这是最彻底的退出方式,不管什么线程都能被强制退出

//this.Close();//只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外,若有托管线程(非主线程),也无法干净退出
//Application.Exit();//强制所有消息终止,退出所有的窗体,但是若有托管线程(非主线程),也是无法干净退出的;
//Application.ExitThread();//强制终止调用线程上的所有消息,同样面临其他线程无法正确退出的难题

}

private void butCancel_Click(object sender, EventArgs e)
{

}
}
}

配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>

<appSettings>
<add key ="DB" value ="DAL"/>
<add key ="strConn" value ="server =ZGY;Database= Login;User ID = sa; Password = 123456"/>

</appSettings>





</configuration>

这中间也遇见很多问题,大家可以去看这一系列的文章,一定有你遇见的那个错误呦!

​​System.NullReferenceException:“未将对象引用设置到对象的实例。” System.Configuration.ConnectionStringSettingsCollect​​配置系统未能初始化

​​System.IO.FileNotFoundException:“未能加载文件或程序集“loginDAL”或它的某一个依赖项。系统找不到指定的文件。”​​

​​源文件与模块生成时的文件不同,是否希望调试器使用它?如何解决​​

​​System.ArgumentNullException:“值不能为 null。 Arg_ParamName_Name”​​

一定要先好好学习配置文件的写法奥!


标签:总结,登录,七层,Cmd,System,DataTable,new,using,public
From: https://blog.51cto.com/u_15845711/5952901

相关文章

  • 12月19日内容总结——
    目录一、Q查询进阶操作二、ORM查询优化三、ORM事务操作四、ORM常用字段类型五、ORM常用字段参数六、Ajax七、Content-Type八、ajax携带文件数据九、作业一、Q查询进阶操......
  • 麒麟V10输入密码后依然无法进入系统,重新跳到登录界面
    图形界面登录闪退,或输入正确用户名密码重新跳转到登录界面有两个常见原因:(1)磁盘原因:可能”/”分区被占满,ctrl+alt+F2切换到文本界面登录,命令行执行:df -h,如若/分区使用率......
  • 作品展-作品总结收获(vb与flash交互)
    万事开头难,一个作品的主题我感觉是最难的了,我和我的小伙伴光想主题就花了一两天,而且中间还把作品推翻重做,所以主题就很重要了,有了主题才有了最后的思想火花。我和孟伟的作品......
  • 4月自考总结
    由于学习热情的下降,4月份完成的自考到现在才来总结。自考一直从寒假到现在也有大概34个月了,一路过来我其实还是很风调雨顺的,该玩玩该学学,有时该学的时候也在玩。总的来说......
  • python3.7登录脚本
    下面是登录脚本,最后获取token值test${headers}   CreateDictionary  Content-Type=application/json    User-Agent=Mozilla/5.0(WindowsNT10.0;......
  • 日常总结:Vue写一个炫酷的时钟插件
    效果图代码奉上:<template><divclass="clock"><divclass="flip"><divclass="digitalfront":data-number="nextTimes[0]"></div><d......
  • 日常总结:Vue实现一个炫酷的代码瀑布流背景
    先看一下效果:代码奉上:<template><canvasid="canvas"/></template><script>exportdefault{name:"BackCanvas",props:{height:{......
  • Kafka知识总结之集群环境搭建
    简述Kafka是一个分布式流平台,本质是一个消息队列。消息队列的三个作用:异步、消峰和解耦。一.安装zookeeper1.1.下载并解压#下载wgethttps://mirror.bit.edu.cn/apache/z......
  • Kafka知识总结之Broker原理总结
    简介这篇文章介绍Kafka的Broker工作流程,包括其中控制器的选举过程;kafka副本的leader选举以及leader和follower故障流程;简单讲述了生产环境中如何调整分区副本;kafka的文件存......
  • Kafka知识总结之生产者简单使用
    一.测试环境搭建引入依赖:<dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>2.8.0</version></dependency>创......