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

就个人而言,三层架构有点难理解,不知道该如何下手,各层与各层之间怎么调用

最近一直在研究三层架构,经过网上学习与多方打听写一下自己的心得。有不足之处,可以评论和私聊探讨

言归正传:

三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了"高内聚低耦合"的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、表示层。

三层体系的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。通常情况下,客户端不直接与数据库进行交互,而是通过COM/DCOM通讯与中间层建立连接,再经由中间层与数据库进行交互。

UI层:即表示层,就是展现给用户看到的界面

BLL:即业务逻辑层,就是实现功能的,用来写方法及其调用

DAL:即数据访问层,也就是说,是对数据库的操作,而不是数据,具体为业务逻辑层或表示层提供数据服务。说白了就是写sql语句的;主要是存放对数据类的访问,即对数据库的添加、删除、修改、更新等基本操作

除此三层外,聪明的人一定就还会说中间还有一个model(模型层)作为承载数据的媒介,供上面三个层引用。用来存储实体类的,所以model实体类也很重要,

model:实体类库,主要存放数据库中的表字段

引用顺序为UI引用BLL;BLL引用DAL;也可以间接引用

案例分析:

我们以一个登录窗体作为案例

首先在数据库建一张账号用户表,并填写部分数据,用来测试

如图

 

方案目录结构 

就个人而言还是从UI层开写更好一点,因为UI层能直观的看出你想实现什么功能效果,以便于下层该怎么下手

1.UI层

 

UI层做好,接下来最好做model实体类,实体类库(Model),主要存放数据库中的表字段。

后台代码:

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 登录
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //实例化model层中 userInfo类用于传递数据  
        Model.userInfo m_userInfo = new Model.userInfo();

        //实例化BAL层中 userAccess方法衔接用户输入与数据库匹配  
        BAL.userBLL b_userAccess = new BAL.userBLL();
        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            //将用户输入的账号密码 赋值给userInfo类 username、psw属性  
            m_userInfo.username = textBox1.Text.Trim().ToString();
            m_userInfo.psw = textBox2.Text.Trim().ToString();

            //如果BLL层中 useLogin调用返回记录条数 大于1 则账号密码正确  
            if (b_userAccess.userLogin(m_userInfo) > 0)
            {
                MessageBox.Show("登录成功");
            }
            else
            {
                MessageBox.Show("登录失败");
            }
        }
    }
}

 

2.MODEL模型层

model层其实就相当于一个中转站,用来存储用到的数据,贯穿三层,数据的赋值及提取

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

namespace WindowsFormsApp4.MODEL
{
    class userInfo //想创建一个用户实体类
    {
      //用get;set方法
      public string username { get; set; }
        public string password { get; set; }
    }
}

 

model实体类做好后接下来就可以写DAL层了,DAL就是书写sql语句操作数据库,(就拿登录窗体来说,我们在登录时要输入账号和密码,点击登录时就要与数据库里的数据进行对比,只有验证一致才能登陆成功。这时就要书写sql语句取出数据库里的数据与你在输入框输入的数据进行对比)

在写DAL层时要写一个SQLhelper帮助类(六面提供了很多方法与对象,极大的方便了开发人员的开发效率;其实一个sqlhelper帮助类可以放在任何地方调用,那小编就给大家一呗)

 

  1 using System;
  2 using System.Data;
  3 using System.Collections;
  4 using System.Configuration; //记得这个asp默认没引用,你要去添加引用的程序集里引用进来
  5 using System.Linq;
  6 using System.Web;
  7 using System.Xml.Linq;
  8 using System.Data.SqlClient;
  9 using System.Collections.Generic;
 10 
 11 namespace UMS.DbHelper
 12 {
 13     /// <summary>
 14     /// SQL数据库操作类
 15     /// </summary>
 16     public class SQLHelper
 17     {
 18         private string strConn;
 19         private SqlConnection sqlConn = null;
 20 
 21         public SQLHelper()
 22         {
 23             strConn = ConfigurationManager.ConnectionStrings["UserData"].ConnectionString;
 24             sqlConn = new SqlConnection(strConn);
 25        
 26         }
 27 
 28         /// <summary>
 29         /// 打开数据库连接
 30         /// </summary>
 31         private void OpenConn()
 32         {
 33             if (sqlConn != null && sqlConn.State == ConnectionState.Closed)
 34             {
 35                 sqlConn.Open();
 36             }
 37         }
 38 
 39         /// <summary>
 40         /// 关闭数据库连接
 41         /// </summary>
 42         private void CloseConn()
 43         {
 44             if (sqlConn != null && sqlConn.State == ConnectionState.Open)
 45             {
 46                 sqlConn.Close();
 47             }
 48         }
 49         /// <summary>
 50         /// 构造操作命令
 51         /// </summary>
 52         /// <param name="cmdText">带参命令</param>
 53         /// <param name="param">参数数组</param>
 54         /// <param name="values">参数值数组</param>
 55         /// <returns></returns>
 56         private SqlCommand CreateCommand(string cmdText, string[] param, object [] values)
 57         {
 58             SqlCommand myCmd = new SqlCommand(cmdText,sqlConn);
 59             for (int i = 0; i < param.Length; i++)
 60             {
 61                 myCmd.Parameters.AddWithValue(param[i],values[i]);
 62             }
 63             return myCmd;
 64         }
 65         /// <summary>
 66         /// 根据SQL指令返回相应查询阅读器,在阅读器使用完后请及时关闭
 67         /// </summary>
 68         /// <param name="cmdText">查询语句</param>
 69         /// <param name="param">参数列表,无参可设置为null</param>
 70         /// <param name="values">参数值列表,只有当参数不为空时有效</param>
 71         /// <returns></returns>
 72         public SqlDataReader ExecuteReader(string cmdText,string [] param,object [] values)
 73         {
 74             OpenConn();
 75             SqlCommand myCmd;
 76             if (param != null)
 77             {
 78                 myCmd = this.CreateCommand(cmdText, param, values);
 79             }
 80             else
 81             {
 82                 myCmd = new SqlCommand(cmdText,sqlConn);
 83             }
 84             return myCmd.ExecuteReader(CommandBehavior.CloseConnection);
 85         }
 86 
 87         /// <summary>
 88         /// 根据存储过程返回相应查询阅读器,在阅读器使用完后请及时关闭
 89         /// </summary>
 90         /// <param name="cmdText">存储过程名</param>
 91         /// <param name="parms">参数列表</param>
 92         /// <returns></returns>
 93         public SqlDataReader ExecuteReaderBySP(string cmdText, SqlParameter[] parms)
 94         {
 95             OpenConn();
 96             SqlCommand myCmd = new SqlCommand(cmdText, sqlConn);
 97             myCmd.CommandType = CommandType.StoredProcedure;
 98             if (parms != null)
 99             {
100                 myCmd.Parameters.AddRange(parms);
101             }
102             return myCmd.ExecuteReader(CommandBehavior.CloseConnection);
103         }
104 
105         /// <summary>
106         /// 根据SQL指令返回受影响行数,主要用于数据库的更新、插入、删除等操作
107         /// </summary>
108         /// <param name="cmdText">sql命令语句</param>
109         /// <param name="param">参数数组,若没有参数可以设置为空</param>
110         /// <param name="values">参数值数组,只有当param不为空时有效</param>
111         /// <returns></returns>
112         public int ExecuteNoneQuery(string cmdText, string[] param, object[] values)
113         {
114             OpenConn();
115             SqlCommand myCmd;
116             if (param != null)
117             {
118                 myCmd = this.CreateCommand(cmdText, param, values);
119             }
120             else
121             {
122                 myCmd = new SqlCommand(cmdText,sqlConn);
123             }
124             try
125             {
126                 return myCmd.ExecuteNonQuery();
127             }
128             catch (Exception ex)
129             {
130                 throw ex;
131             }
132             finally
133             {
134                 CloseConn();
135             }
136         }
137 
138         /// <summary>
139         /// 根据SQL指令返回第一行第一列结果
140         /// </summary>
141         /// <param name="cmdText">sql命令语句</param>
142         /// <param name="param">参数数组,若没有参数可以设置为空</param>
143         /// <param name="values">参数值数组,只有当param不为空时有效</param>
144         /// <returns></returns>
145         public object ExecuteScalar(string cmdText, string[] param, object[] values)
146         {
147             OpenConn();
148             SqlCommand myCmd;
149             if (param != null)
150             {
151                 myCmd = this.CreateCommand(cmdText, param, values);
152             }
153             else
154             {
155                 myCmd = new SqlCommand(cmdText,sqlConn);
156             }
157             try
158             {
159                 return myCmd.ExecuteScalar();
160             }
161             catch (Exception ex)
162             {
163                 throw ex;
164             }
165             finally
166             {
167                 CloseConn();
168             }
169         }
170         /// <summary>
171         /// 带事务执行存储过程,该方法主要用于执行用于数据维护类的存储过程执行
172         /// </summary>
173         /// <param name="cmdText">存储过程名称</param>
174         /// <param name="parms">SQL参数数组</param>
175         public int  ExecuteNoneQueryBySP(string cmdText, SqlParameter[] parms)
176         {
177             OpenConn();
178             SqlTransaction tran = sqlConn.BeginTransaction();
179             SqlCommand myCmd = new SqlCommand(cmdText, sqlConn);
180             myCmd.CommandType = CommandType.StoredProcedure;
181             if (parms != null)
182             {
183                 myCmd.Parameters.AddRange(parms);
184             }
185             myCmd.Transaction = tran;
186             try
187             {
188                 int result=myCmd.ExecuteNonQuery();
189                 tran.Commit();
190                 return result;
191             }
192             catch (Exception ex)
193             {
194                 tran.Rollback();
195                 throw ex;
196             }
197             finally
198             {
199                 CloseConn();
200             }
201         }
202         /// <summary>
203         /// 根据命令语句返回数据集
204         /// </summary>
205         /// <param name="cmdText">命令语句</param>
206         /// <param name="param">参数数组,若没有参数可以设置为空</param>
207         /// <param name="values">参数值数组,只有当param不为空时有效</param>
208         /// <returns></returns>
209         public DataSet FillDataSet(string cmdText, string[] param, object[] values)
210         {
211             OpenConn();
212             SqlCommand myCmd;
213             if (param != null)
214             {
215                 myCmd = this.CreateCommand(cmdText, param, values);
216             }
217             else
218             {
219                 myCmd = new SqlCommand(cmdText,sqlConn);
220             }
221             SqlDataAdapter myAdp = new SqlDataAdapter(myCmd);
222             DataSet ds = new DataSet();
223             try
224             {
225                 myAdp.Fill(ds);
226                 return ds;
227             }
228             catch (Exception ex)
229             {
230                 throw ex;
231             }
232             finally
233             {
234                 CloseConn();
235             }
236         }
237 
238         /// <summary>
239         /// 执行特定存储过程并返回查询后的数据结果,该方法用于执行查询类的存储过程
240         /// </summary>
241         /// <param name="cmdText">存储过程名</param>
242         /// <param name="parms">SQL参数数组,若没有参数可以设置为空</param>
243         /// <returns></returns>
244         public DataSet FillDataSetBySP(string cmdText, SqlParameter[] parms)
245         {
246             OpenConn();
247             SqlCommand myCmd = new SqlCommand(cmdText, sqlConn);
248             myCmd.CommandType = CommandType.StoredProcedure;
249             if (parms != null)
250             {
251                 myCmd.Parameters.AddRange(parms);
252             }
253             SqlDataAdapter myAdp = new SqlDataAdapter(myCmd);
254             DataSet ds = new DataSet();
255             try
256             {
257                 myAdp.Fill(ds);
258                 return ds;
259             }
260             catch (Exception ex)
261             {
262                 throw ex;
263             }
264             finally
265             {
266                 CloseConn();
267             }
268         }
269         /// <summary>
270         /// 执行存储过程返回输出参数
271         /// </summary>
272         /// <param name="cmdText">存储过程名</param>
273         /// <param name="parms">参数数组</param>
274         /// <returns>包含所有输出值的ArrayList</returns>
275         public ArrayList ExecuteSp(string cmdText, SqlParameter[] parms)
276         {
277             OpenConn();
278             SqlCommand myCmd = new SqlCommand(cmdText, sqlConn);
279             myCmd.CommandType = CommandType.StoredProcedure;
280             if (parms != null)
281             {
282                 myCmd.Parameters.AddRange(parms);
283             }
284             try
285             {
286                 myCmd.ExecuteNonQuery();
287                 ArrayList al = new ArrayList();
288                 for (int i = 0; i < parms.Length; i++)
289                 {
290                     if (parms[i].Direction == ParameterDirection.Output)
291                     {
292                         al.Add(parms[i]);
293                     }
294                 }
295                 return al;
296             }
297             catch (Exception ex)
298             {
299                 throw ex;
300             }
301             finally
302             {
303                 CloseConn();
304             }
305         }
306 
307         #region 批处理操作
308         /// <summary>
309         /// 批量数据导入操作
310         /// </summary>
311         /// <param name="dt">要批量导入的数据表</param>
312         /// <param name="destTableName">目标表名</param>
313         /// <param name="columnMappings">列映射集合</param>
314         public void BulkInsert(DataTable dt, string destTableName, List<SqlBulkCopyColumnMapping> columnMappings)
315         {
316             SqlBulkCopy bulkCopy = new SqlBulkCopy(this.sqlConn);
317             bulkCopy.DestinationTableName = destTableName;
318             bulkCopy.BatchSize = dt.Rows.Count;
319             foreach (SqlBulkCopyColumnMapping map in columnMappings)
320             {
321                 bulkCopy.ColumnMappings.Add(map);
322             }
323             try
324             {
325                 OpenConn();
326                 bulkCopy.WriteToServer(dt);
327             }
328             catch (Exception ex)
329             {
330                 throw ex;
331             }
332             finally
333             {
334                 this.CloseConn();
335                 bulkCopy.Close();
336             }
337         }
338         #endregion
339     }
340 }
View Code

 

 

类里边不是有个数据库访问方法,那里是在配置文件里配置了数据库连接字符串,所以就没有在方法里写连接字符串

例如

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
      
    </startup>
  <connectionStrings>
    <add name="UserData" connectionString="Data Source=.;Initial Catalog=账号表;User ID=sa;Password=密码"/>
  </connectionStrings>
</configuration>

 

 

SqlHelper

私有方法有四个,AssignParameterValues方法有一个重载:

AttachParameters:添加参数数组到指定的SqlCommand中 
AssignParameterValues:为SqlParameters(参数)数组赋值 
PrepareCommand:用于对SqlCommand(命令)的属性(如连接、事务环境等)进行初始化。

公有方法有十三个:这当中每个查询数据库的方法用到了大量的重载,每个方法用到了八个左右的重载。

ExecuteNonQuery

此方法用于执行不返回任何行或值的命令。这些命令通常用于执行数据库更新,但也可用于返回存储过程的输出参数。

ExecuteDataset

此方法返回DataSet对象,该对象包含由某一命令返回的结果集。

ExecuteReader

此方法用于返回SqlDataReader对象,该对象包含由某一命令返回的结果集。

ExecuteScalar

此方法返回一个值。该值始终是该命令返回的第一行的第一列。

ExecuteXmlReader

此方法返回 FOR XML 查询的 XML 片段。

FillDataset

此方法向DataSet填充数据。

UpdateDataset

此方法用于执行向DataSet增、删、改的命令。

CreateCommand

此方法用于创建SqlCommand。

 

3.DAL层

建好第一步就先把sqlhelper类和model实体类引进来(以创建对象的方式)

 我这里只写了登录时用到的,别的就要靠你自己摸索了

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

namespace DAL
{
    public class userDAL

    {
        //实例化DBbase 对象  
        DBbase db = new DBbase();

        //用户登录的方法  
        public int userLogin(string name, string psw)
        {
            string strsql = "select * from users where username = '" + name + "' and password = '" + psw + "'";
            return db.returnRowCount(strsql);
        }
    }
}
View Code

 登录的sqlhelper类,在这里叫DBbase

 

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 DBbase
    {
        //读取配置文件 连接数据库语句  
        public static string strCon = System.Configuration.ConfigurationManager.ConnectionStrings["TestDB"].ConnectionString;
        //public static string strCon = "Data Source=.;Initial Catalog=threeLayer;Persist Security Info=True;User ID=sa;Password=123";  

        //实例化连接对象 con  
        SqlConnection con = new SqlConnection(strCon);

        //检测连接是否打开  
        public void chkConnection()
        {
            if (this.con.State == ConnectionState.Closed)
            {
                this.con.Open();
            }
        }

        //执行语句,返回该语句查询的数据行的总行数  
        public int returnRowCount(string strSQL)
        {
            chkConnection();
            try
            {
                SqlDataAdapter da = new SqlDataAdapter(strSQL, con);
                DataSet ds = new DataSet();
                da.Fill(ds);
                return ds.Tables[0].Rows.Count;
            }
            catch
            {
                return 0;
            }
        }
    }
}

4.BLL层 

 

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

namespace BAL
{
    public class userBLL
    {
        DAL.userDAL d_userAccess = new DAL.userDAL();
        public int userLogin(Model.userInfo m_userInfo)//把model层的值传过来进行比对
        {
            return d_userAccess.userLogin(m_userInfo.username, m_userInfo.psw);//如果有返回值则登录成功
        }
    }
}

 

 

 

到这里就大功告成了,登录效果

 

转载于:https://www.cnblogs.com/kalezhangtao/p/9113395.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值