本文文字方面引用 微冷的風丶(博客地址:https://www.cnblogs.com/smbk/)

代码部分是本人亲自写的一个sqlite数据库的最简单登录界面练手(当时写的太烂了,现在回顾重构一下)

三层架构分为:表现层(UI(User Interface))、业务逻辑层(BLL(Business Logic Layer))、数据访问层(DAL(Data Access Layer))再加上实体类库(Model)

这个例子的思路是:

实体类库(Model)作为定义我们需要的类的空间,在实体类库(Model)我们定义的类会在UI,DAL,BLL的任意层次实例化为对象,这个对象用于临时存储变量和调用函数,用完就被垃圾收集器清理了

DAL BLL UI三层都会引用Model类库,类库嘛,就是拿来放大家都可能使用的公共类。

数据访问层(DAL(Data Access Layer)),有且只有Model类库被引用。作为存放数据库增删改查方法的层次,这些方法被定义在一个类中,这个类只会被BLL层实例化为对象并使用,用完就被垃圾收集器清理了

业务逻辑层(BLL(Business Logic Layer)),有Model类库和DAL层被引用。这一层就是理清楚所需功能的逻辑,引用DAL层的各种方法,并把它们封装成BLL层的方法供UI层调用,即把DAL层写的类实例化成对象,,用完就被垃圾收集器清理了。

表现层(UI(User Interface)),有Model类库和BLL层被引用,这一层就是制作界面之类的,使用winfrom的情况下,给按钮添加各种功能来达到想达到的效果,需要的功能从BLL层调用即可,即把BLL层写的类实例化成对象,用完就被垃圾收集器清理了。

1、实体类库(Model),主要存放数据库中的表字段。

操作:

(1)先建立实体类库Model,打开项目,在解决方案中右键——>添加——>新建项目——>选中类库——>改名Model——>确定

(2)选中Model类库——>建立实体类命名为:UserInfo

    public class UserInfo
{
//以下字段用来存储
public string UserAccount { get; set; }//注册时的用户名,还可以做查询返回字段使用
public string UserPassword { get; set; }//注册时的密码,还可以做查询返回字段使用
public string UserPasswordConfirm { get; set; }//注册时的确认密码(仅做此作用) public string InputAccount { get; set; }//用户输入的用户名(非第一次注册)
public string InputPassword { get; set; }//用户输入的密码(非第一次注册)
public string PasswordInDB { get; set; }//返回时用到的数据库中存储的密码
public string ChangePassword { get; set; }//用户修改密码时输入的密码
}

2、数据访问层(DAL),主要是存放对数据类的访问,即对数据库的添加、删除、修改、更新等基本操作

操作:

(1)先建立数据访问层类库DAL,打开项目,在解决方案中右键——>添加——>新建项目——>选中类库——>改名DAL——>确定

(2)在DAL中添加对Model的引用,点击DAL前▲——>右键点击引用——>添加引用——>项目——>选中Model——>确定

(3)在DAL中添加对system.configuration的引用,点击DAL前▲——>右键点击引用——>添加引用——>程序集——>选中System.configuration——>确定

(4)在建立的类文件中添加using Model;

(5)建立数据访问类,右键DAL——>建立类——>建立实体类命名为:UserDB、

UserDB类我只列举这几个方法:

我们数据库就叫Aniki(因为这样很哲♂学)

        /// <summary>
/// 填充表_注册新账号
/// </summary>
public void FillTable(UserInfo NewUser)
{
using (SQLiteConnection cnn = new SQLiteConnection(@"Data Source=D:\Aniki.sqlite")) //创建链接,链接到该数据库
{
if (cnn.State != System.Data.ConnectionState.Open) //判断数据库是否是打开,打开状态则不进行操作并关闭。
{
cnn.Open(); //打开数据库
using (SQLiteCommand cmd = new SQLiteCommand(cnn)) //创建对该数据库操作的命令
{
cmd.CommandText = "INSERT INTO UserList(Account, Password) VALUES('" + NewUser.UserAccount + "', '" + NewUser.UserPassword + "')"; //输入命令内容
cmd.ExecuteNonQuery();//执行cmd命令的sql语句
}
}
cnn.Close();
}
}
        /// <summary>
/// 表内查找
/// </summary>
public DataTable SelectTable(UserInfo OldUser)
{
DataTable dt = new DataTable();
using (SQLiteConnection cnn = new SQLiteConnection(@"Data Source=D:\Aniki.sqlite"))
{
if (cnn.State != System.Data.ConnectionState.Open)
{
cnn.Open(); using (SQLiteCommand cmd = new SQLiteCommand(cnn))
{
cmd.CommandText = "SELECT * FROM UserList WHERE Account='" + OldUser.InputAccount + "'";
SQLiteDataAdapter adaper = new SQLiteDataAdapter(cmd);
adaper.Fill(dt);
}
}
cnn.Close();
return dt;
}
}

3、业务逻辑层(BLL)对传送数据进行逻辑判断分折,并进行传送正确的值。

(1)先建立业务逻辑层类库BLL,打开项目,在解决方案中右键——>添加——>新建项目——>选中类库——>改名BLL——>确定

(2)在BLL中添加对Model、DAL的引用,右键BLL项目下的引用——>添加引用——>项目——>勾选Model和DAL——>确定

(3)在建立的类文件中添加using Model;using DAL;

(4)建立类,类名为:LoginManager

    public class LoginManager
{
//string NewAccount;
//string NewPassword;
//string ValidCode; /// <summary>
/// 新用户_注册
/// 验证密码和再次输入密码,两次密码正确则帐号和密码写入数据库
/// </summary>
/// <param name="NewUser">新用户</param>
/// <returns></returns>
public bool SignUpVerifyPassword(UserInfo NewUser)
{
UserDB Aniki = new UserDB();//创建数据库类以进行操作
if (NewUser.UserPasswordConfirm == NewUser.UserPassword)//微软牛逼!
{
Aniki.FillTable(NewUser);//写入数据库
return true;
}
else
return false;
}
        /// <summary>
/// 新用户注册查询
///查询是否以经被注册,所以作老用户属性来判断一下(用的代码部分与老用户登录类似,逻辑是看看这个帐号能不能返回密码)
/// </summary>
/// <param name="OldUser"></param>
/// <returns></returns>
public bool SignUpIsAccountExist(UserInfo OldUser)
{
UserDB Aniki = new UserDB();
if (Aniki.SelectTable(OldUser).ToString() == "")
{
return false;
}
else
return true;
}

上面为什么要把验证能不能注册这一个事情,分成两个函数呢?

因为注册不成功的报错有两种:

1,密码与重复输入密码不相符

2,帐号已经注册

因此我们要写成两个函数,对应两个massage.box()。

        /// <summary>
/// 老用户_验证登录验证输入的密码
/// </summary>
/// <param name="OldUser"></param>
/// <returns></returns>
public bool LoginVerifyPassword(UserInfo OldUser)
{
UserDB Aniki = new UserDB();
if (OldUser.InputPassword == (string)Aniki.SelectTable(OldUser).Rows[0][0])
{
return true;
}
else
{
return false;
}
} /// <summary>
/// 老用户_修改密码
/// </summary>
/// <param name="OldUser"></param>
/// <returns></returns>
public bool UpdataPassword(UserInfo OldUser)
{
UserDB Aniki = new UserDB();
if (OldUser.InputPassword == OldUser.PasswordInDB)
{
Aniki.UpdataTable(OldUser);
return true;
}
else
{
return false;
}
}
}

4.表现层(UI)即用户界面层

(1)先建立业务逻辑层类库BLL,打开项目,在解决方案中右键——>添加——>新建项目——>选中Winform——>改名UI——>确定

(2)在BLL中添加对Model、BLL的引用,右键UI项目下的引用——>添加引用——>项目——>勾选Model和BLL——>确定

(3)在建立的winform类文件中添加using Model;using BLL;

Winform代码太难看了,这里只举个例子好了,这是点击LogIn按钮的内容,这里的逻辑比较有代表性。

LogIn窗体内的Login按钮


private void btnLogin_Click(object sender, EventArgs e)
{
UserInfo OldUser = new UserInfo();
OldUser.InputAccount = tbUserAccount.Text;
OldUser.InputPassword = tbUserPassword.Text;
LoginManager BLL = new LoginManager();
if (BLL.LoginVerifyPassword(OldUser))
{
MessageBox.Show("登录成功!");
DialogResult = DialogResult.Cancel;//用于关闭本LogIn窗口
DialogResult = DialogResult.OK;//用于打开Main窗口
/*
原因:
Main窗口代码先运行,给LogIn窗口建立了个对象frmLogIn,frmLogIn的frmLogIn.ShowDialog()方法打开了LogIn窗口。
DialogResult是对话框的返回值,写在btnLogin_Click函数中,就是在btnLogin_Click函数中给这个DialogResult返回值赋值了OK(1)
回到Main窗体中判断LogIn中的DialogResult,如果是OK(1)就打开Main窗体,否则不打开。
*/
}
else
MessageBox.Show("账号或密码错误!");
}

btnLogin_Click()这个方法是注册新用户的按钮,如果登录成功会跳转到Main窗体。这里引用了BLL层的BLL.LoginVerifyPassword()方法。

之前以经展示过BLL.LoginVerifyPassword()这个方法,在BLL层中(因此建立了一个叫BLL的对象,代码是LoginManager BLL = new LoginManager();)

BLL层的LoginVerifyPassword()方法

        public bool LoginVerifyPassword(UserInfo OldUser)
{
UserDB Aniki = new UserDB();
if (OldUser.InputPassword == (string)Aniki.SelectTable(OldUser).Rows[0][0])
{
return true;
}
else
{
return false;
}
}

这里的LoginVerifyPassword()方法有用到了DAL层的SelectTable()方法,SelectTable()方法是非常简单直接的一个方法,即返回你要查找的结果集(我这里的返回结果只有一个密码)

DAL层的SelectTable()方法,这个方法是table类型的

        public DataTable SelectTable(UserInfo OldUser)
{
DataTable dt = new DataTable();
using (SQLiteConnection cnn = new SQLiteConnection(@"Data Source=D:\Aniki.sqlite"))
{
if (cnn.State != System.Data.ConnectionState.Open)
{
cnn.Open(); using (SQLiteCommand cmd = new SQLiteCommand(cnn))//建立一个SQLite命令对象cmd,构造函数需要cnn
{
cmd.CommandText = "SELECT * FROM UserList WHERE Account='" + OldUser.InputAccount + "'";//sql语句写入命令cmd
SQLiteDataAdapter adaper = new SQLiteDataAdapter(cmd);//DataAdapter是个数据转换器类,构造函数需要cmd
adaper.Fill(dt);
/*DataAdapter类里的Fill这个方法,可以填充DataSet或将DataSet表中的更改传送到相应的数据存储区,
从数据源增加或刷新行,并将这些行放到DataSet表中,Fill方法调用SelectCommand属性所指定的SELECT语句。*/
}
}
cnn.Close();
return dt;
}
}

我们回到 BLL层的LoginVerifyPassword()方法

if (OldUser.InputPassword == (string)Aniki.SelectTable(OldUser).Rows[0][0])

这里DataTable SelectTable()是DataTable类型,返回一个DataTable类型的对象(原方法中对象是dt)

这个对象的使用方式就是 dt.Rows[m][n],即像个二维数组一样返回想要位置的数值。Rows是按照行来算,Columns是按照列来算,此外还有很多方法。

if (OldUser.InputPassword == (string)Aniki.SelectTable(OldUser).Rows[0][0])

所以即表示返回第一个数据(我这里只有Password,所以就是第一个数据)

强制类型转换未string,然后判断是不是与用户输入的InputPassword相符,相符则说明密码是符合的,即跳转Main窗体。

C# 三层架构的一个小练习(Winfrom与SQLite数据库组合)的更多相关文章

  1. 基于三层架构下的公共数据访问方法(Sqlite数据库)

    作者总结了一下,使用Winform的三层架构做窗体应用程序,在数据访问方面,有用到纯sql语句方法.参数方法.存储过程方法. 那么什么是三层架构呢? UI---存放Form窗体---(用户所关心的) ...

  2. c#利用三层架构做一个简单的登录窗体

    就个人而言,三层架构有点难理解,不知道该如何下手,各层与各层之间怎么调用 最近一直在研究三层架构,经过网上学习与多方打听写一下自己的心得.有不足之处,可以评论和私聊探讨 言归正传: 三层架构(3-ti ...

  3. 有关于web server架构的一个小疑问

    今天闲的时候trace route了yahoo和sina的域名,yahoo的如下: 1     1 ms     1 ms    <1 ms  172.21.127.1   2     3 ms ...

  4. MVP架构的一个小例子

    主角: MVP是一种编程的架构模式,M=Model,负责提供数据:V=View,负责显示数据:P=Presenter,负责处理数据. 应用例子: csharp写的一个qq机器人. 一.Model层 获 ...

  5. 怎么在三层架构中使用Quartz.Net开源项目(与数据库交互)

    1.首先在项目中先创建一个控制台应用程序 2.然后右击项目中的[引用],可以[添加引用],也可以[管理NuGet程序包],作者使用的是[添加引用],添加本地应用.版本不同,所使用的方式不同.需要此版本 ...

  6. Java Web 三层架构详解

    java 三层架构ssh 一个spring2.5+hibernate3.2+struts2.0组合框架,使用spring的 IoC来管理应用的 所有bean,包括struts2的 action,充分发 ...

  7. 关于三层架构与MVC的一些理解

    刚毕业的时候,参与了一个上位机的系统开发.上位机所使用的是.net Windows Form技术. 当时,和一个北理的姑娘在一个项目组里.因为她来公司时间比较长,而且经验比较丰富,所以,上位机的架构由 ...

  8. 三层架构和MVC

    注:本文章内所有内容都来自互联网,本人主要是起了一个收集的作用 http://www.cnblogs.com/zhhh/archive/2011/06/10/2077519.html 又看到有人在问三 ...

  9. Web项目的三层架构和MVC架构异同

    http://www.cnblogs.com/zhhh/archive/2011/06/10/2077519.html 又看到有人在问三层架构和MVC的关系,感觉这种问题有点教条化了.因为它们都在逻辑 ...

随机推荐

  1. Flask-sqlalchemy-表关系

        表关系   表之间的关系存在三种:   一对一.一对多.多对多.   而SQLAlchemy中的ORM也可以模拟这三种关系.因为一对一其实在SQLAlchemy中底层是通过一对多的方式模拟的, ...

  2. SSM框架搭建过程

    引入依赖的jar包(pom.xml) a. <!--Spring SpringMVC相关-->  spring-webmvc b. <!--Spring事务-->  sprin ...

  3. php7类型约束的意义

    在PHP7之前,函数和类方法不需要声明变量类型,任何数据都可以被传递和返回,导致几乎大部分的调用操作都要判断返回的数据类型是否合格. 为了解决这个问题,PHP7引入了类型声明. 目前有两类变量可以声明 ...

  4. python用户名密码限定次数登录

    """ 1. 用户输入帐号密码进行登陆 2. 用户信息保存在文件内 3. 用户密码输入错误三次后锁定用户"""" test.txt ...

  5. Oracle with as语法

    with as优点 增加了sql的易读性,如果构造了多个子查询,结构会更清晰: 更重要的是:“一次分析,多次使用”,这也是为什么会提供性能的地方,达到了“少读”的目标 用法:给查询的语句起个别名 e. ...

  6. winform 控件拖拽和缩放

    核心类: using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using ...

  7. ssh登录失败的常见问题分析

    操作系统为了安全,一般只允许普通用户使用public_key登录,这时如果以root用户登录,就会出现各种错误.下面是常见的错误及解决方案. Permission denied (publickey) ...

  8. html相关操作点

    $( "#members li a" ).bind( "click", function( e ) {} ); $( document ).live( &quo ...

  9. java入门经验分享——记面向对象先导课程学习感想

    选择在暑期学习面向对象先导课程的初衷是为大二下学期面向对象课程做一些铺垫,接触入门java语言.在接触java的过程中,就编程语言的学习方法而言,我从刚入学时的手慌脚乱四处寻求帮助到现在慢慢养成了自己 ...

  10. 2019杭电多校第四场hdu6623 Minimal Power of Prime

    Minimal Power of Prime 题目传送门 解题思路 先打\(N^\frac{1}{5}\)内的素数表,对于每一个n,先分解\(N^\frac{1}{5}\)范围内的素数,分解完后n变为 ...