一、三层架构
1、什么是三层?
UI(表现层): 主要是指与用户交互的界面。用于接收用户输入的数据和显示处理后用户需要的数据。
BLL:(业务逻辑层): UI层和DAL层之间的桥梁。实现业务逻辑。业务逻辑具体包含:验证、计算、业务规则等等。
DAL:(数据访问层): 与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。(当然这些操作都是基于UI层的。用户的需求反映给界面(UI),UI反映给BLL,BLL反映给DAL,DAL进行数据的操作,操作后再 一 一 返回,直到将用户所需数据反馈给用户)
每一层都各负其责,那么该如何将三层联系起来呢?
1、单项引用(见下图)
2、这时候实体层(Entity)来了。(注:当然,实体层的作用不止这些)
Entity(实体层):它不属于三层中的任何一层,但是它是必不可少的一层。
Entity在三层架构中的作用:
- 1、实现面向对象思想中的"封装";
- 2、贯穿于三层,在三层之间传递数据;(注:确切的说实体层贯穿于三层之间,来连接三层)
- 3、对于初学者来说,可以这样理解:每张数据表对应一个实体,即每个数据表中的字段对应实体中的属性(注:当然,事实上不是这样。为什么?1>,可能我们需要的实体在数据表对应的实体中并不存在;2>,我们完全可以将所有数据表中的所有字段都放在一个实体里)
- 4、每一层(UI—>BLL—>DAL)之间的数据传递(单向)是靠变量或实体作为参数来传递的,这样就构造了三层之间的联系,完成了功能的实现。
综上所述:三层及实体层之间的依赖关系:
2、为什么使用三层?
使用三层架构的目的:解耦!!!
三层之中每一层当不再适合程序时都可以没有负担的进行更换,不会影响其它层的正常工作。
二、采用三层架构的小Demo
3、三层的具体表现形式
采用三层架构的小Demo的目录结构
UI界面:
导入文件(位置在上面的架构目录上):
App.config
配置用来连接数据库的参数
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <appSettings> 4 <add key="ConnectionString" value="Data Source=.;Initial Catalog=student;Integrated Security=True" /> 5 <add key="ConnectionStringxx" value="server=localhost;database=student;uid=sa;pwd=12345678" /> 6 </appSettings> 7 </configuration>
SqlHelper.cs
主要用来封装操作数据库的方法
1 //=============================================================================== 2 // This file is based on the Microsoft Data Access Application Block for .NET 3 // For more information please go to 4 // http://msdn.microsoft.com/library/en-us/dnbda/html/daab-rm.asp 5 //=============================================================================== 6 7 using System; 8 using System.Configuration; 9 using System.Data; 10 using System.Data.SqlClient; 11 using System.Collections; 12 13 namespace Proj.DAL 14 { 15 16 /// <summary> 17 /// 执行Sql 命令的通用方法 18 /// </summary> 19 public abstract class SqlHelper 20 { 21 22 //Database connection strings 23 public static readonly string ConnectionString = ConfigurationManager.AppSettings["ConnectionString"].Trim(); 24 25 #region ExecuteNonQuery 26 /// <summary> 27 /// 执行sql命令 28 /// </summary> 29 /// <param name="connectionString">连接字符串</param> 30 /// <param name="commandType">命令类型</param> 31 /// <param name="commandText">sql语句/参数化sql语句/存储过程名</param> 32 /// <param name="commandParameters">参数</param> 33 /// <returns>受影响的行数</returns> 34 /// 一般用于执行Update\delete \insert命令 35 public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters) 36 { 37 38 SqlCommand cmd = new SqlCommand(); 39 using (SqlConnection conn = new SqlConnection(connectionString)) 40 { 41 PrepareCommand(cmd, commandType, conn, commandText, commandParameters); 42 int val = cmd.ExecuteNonQuery(); 43 44 return val; 45 } 46 } 47 48 /// <summary> 49 /// 执行Sql Server存储过程 50 /// 注意:不能执行有out 参数的存储过程 51 /// </summary> 52 /// <param name="connectionString">连接字符串</param> 53 /// <param name="spName">存储过程名</param> 54 /// <param name="parameterValues">对象参数</param> 55 /// <returns>受影响的行数</returns> 56 public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues) 57 { 58 59 using (SqlConnection conn = new SqlConnection(connectionString)) 60 { 61 SqlCommand cmd = new SqlCommand(); 62 63 PrepareCommand(cmd, conn, spName, parameterValues); 64 int val = cmd.ExecuteNonQuery(); 65 66 return val; 67 } 68 } 69 #endregion 70 71 #region ExecuteReader 72 /// <summary> 73 /// 执行sql命令 74 /// </summary> 75 /// <param name="connectionString">连接字符串</param> 76 /// <param name="commandType">命令类型</param> 77 /// <param name="commandText">sql语句/参数化sql语句/存储过程名</param> 78 /// <param name="commandParameters">参数</param> 79 /// <returns>SqlDataReader 对象</returns> 80 public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters) 81 { 82 83 SqlConnection conn = new SqlConnection(connectionString); 84 try 85 { 86 SqlCommand cmd = new SqlCommand(); 87 PrepareCommand(cmd, commandType, conn, commandText, commandParameters); 88 SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 89 90 return rdr; 91 } 92 catch 93 { 94 conn.Close(); 95 throw; 96 } 97 } 98 99 /// <summary> 100 /// 执行Sql Server存储过程 101 /// 注意:不能执行有out 参数的存储过程 102 /// </summary> 103 /// <param name="connectionString">连接字符串</param> 104 /// <param name="spName">存储过程名</param> 105 /// <param name="parameterValues">对象参数</param> 106 /// <returns>受影响的行数</returns> 107 public static SqlDataReader ExecuteReader(string connectionString, string spName, params object[] parameterValues) 108 { 109 SqlConnection conn = new SqlConnection(connectionString); 110 try 111 { 112 SqlCommand cmd = new SqlCommand(); 113 114 PrepareCommand(cmd, conn, spName, parameterValues); 115 SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 116 117 return rdr; 118 } 119 catch 120 { 121 conn.Close(); 122 throw; 123 } 124 125 } 126 #endregion 127 128 #region ExecuteDataset 129 130 /// <summary> 131 /// 执行Sql Server存储过程 132 /// 注意:不能执行有out 参数的存储过程 133 /// </summary> 134 /// <param name="connectionString">连接字符串</param> 135 /// <param name="spName">存储过程名</param> 136 /// <param name="parameterValues">对象参数</param> 137 /// <returns>DataSet对象</returns> 138 public static DataSet ExecuteDataset(string connectionString, string spName, params object[] parameterValues) 139 { 140 using (SqlConnection conn = new SqlConnection(connectionString)) 141 { 142 SqlCommand cmd = new SqlCommand(); 143 144 PrepareCommand(cmd, conn, spName, parameterValues); 145 146 using (SqlDataAdapter da = new SqlDataAdapter(cmd)) 147 { 148 DataSet ds = new DataSet(); 149 150 da.Fill(ds); 151 152 return ds; 153 } 154 } 155 } 156 157 158 /// <summary> 159 /// 执行Sql 命令 160 /// </summary> 161 /// <param name="connectionString">连接字符串</param> 162 /// <param name="commandType">命令类型</param> 163 /// <param name="commandText">sql语句/参数化sql语句/存储过程名</param> 164 /// <param name="commandParameters">参数</param> 165 /// <returns>DataSet 对象</returns> 166 public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters) 167 { 168 using (SqlConnection conn = new SqlConnection(connectionString)) 169 { 170 171 SqlCommand cmd = new SqlCommand(); 172 173 PrepareCommand(cmd, commandType, conn, commandText, commandParameters); 174 using (SqlDataAdapter da = new SqlDataAdapter(cmd)) 175 { 176 DataSet ds = new DataSet(); 177 178 da.Fill(ds); 179 180 return ds; 181 } 182 } 183 } 184 185 #endregion 186 187 #region ExecuteScalar 188 /// <summary> 189 /// 执行Sql 命令 190 /// </summary> 191 /// <param name="connectionString">连接字符串</param> 192 /// <param name="commandType">命令类型</param> 193 /// <param name="commandText">sql语句/参数化sql语句/存储过程名</param> 194 /// <param name="commandParameters">参数</param> 195 /// <returns>执行结果对象</returns> 196 public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters) 197 { 198 SqlCommand cmd = new SqlCommand(); 199 200 using (SqlConnection conn = new SqlConnection(connectionString)) 201 { 202 PrepareCommand(cmd, commandType, conn, commandText, commandParameters); 203 object val = cmd.ExecuteScalar(); 204 205 return val; 206 } 207 } 208 209 /// <summary> 210 /// 执行Sql Server存储过程 211 /// 注意:不能执行有out 参数的存储过程 212 /// </summary> 213 /// <param name="connectionString">连接字符串</param> 214 /// <param name="spName">存储过程名</param> 215 /// <param name="parameterValues">对象参数</param> 216 /// <returns>执行结果对象</returns> 217 /// 一般用于 返回sum()\avg()等 218 public static object ExecuteScalar(string connectionString, string spName, params object[] parameterValues) 219 { 220 SqlCommand cmd = new SqlCommand(); 221 222 using (SqlConnection conn = new SqlConnection(connectionString)) 223 { 224 PrepareCommand(cmd, conn, spName, parameterValues); 225 object val = cmd.ExecuteScalar(); 226 227 return val; 228 } 229 } 230 231 232 #endregion 233 234 #region Private Method 235 /// <summary> 236 /// 设置一个等待执行的SqlCommand对象 237 /// </summary> 238 /// <param name="cmd">SqlCommand 对象,不允许空对象</param> 239 /// <param name="conn">SqlConnection 对象,不允许空对象</param> 240 /// <param name="commandText">Sql 语句</param> 241 /// <param name="cmdParms">SqlParameters 对象,允许为空对象</param> 242 private static void PrepareCommand(SqlCommand cmd, CommandType commandType, SqlConnection conn, string commandText, SqlParameter[] cmdParms) 243 { 244 //打开连接 245 if (conn.State != ConnectionState.Open) 246 conn.Open(); 247 248 //设置SqlCommand对象 249 cmd.Connection = conn; 250 cmd.CommandText = commandText; 251 cmd.CommandType = commandType; 252 253 if (cmdParms != null) 254 { 255 foreach (SqlParameter parm in cmdParms) 256 cmd.Parameters.Add(parm); 257 } 258 } 259 260 /// <summary> 261 /// 设置一个等待执行存储过程的SqlCommand对象 262 /// </summary> 263 /// <param name="cmd">SqlCommand 对象,不允许空对象</param> 264 /// <param name="conn">SqlConnection 对象,不允许空对象</param> 265 /// <param name="spName">Sql 语句</param> 266 /// <param name="parameterValues">不定个数的存储过程参数,允许为空</param> 267 private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, string spName, params object[] parameterValues) 268 { 269 //打开连接 270 if (conn.State != ConnectionState.Open) 271 conn.Open(); 272 273 //设置SqlCommand对象 274 cmd.Connection = conn; 275 cmd.CommandText = spName; 276 cmd.CommandType = CommandType.StoredProcedure; 277 278 //获取存储过程的参数 279 SqlCommandBuilder.DeriveParameters(cmd); 280 281 //移除Return_Value 参数 282 cmd.Parameters.RemoveAt(0); 283 284 //设置参数值 285 if (parameterValues != null) 286 { 287 for (int i = 0; i < cmd.Parameters.Count; i++) 288 { 289 cmd.Parameters[i].Value = parameterValues[i]; 290 291 } 292 } 293 } 294 #endregion 295 296 297 } 298 }
DAL层:
UserService.cs
根据给的参数与SQL语句结合操作数据库,将返回结果进行封装,返回给BLL层
1 using System; 2 using System.Collections.Generic; 3 using System.Data.SqlClient; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using Proj.Models; 8 9 10 namespace Proj.DAL 11 { 12 public class UserService 13 { 14 public List<User> GetUserById(string sId) 15 { 16 List<User> list = new List<User>(); 17 string sql = "SELECT * FROM [user] WHERE id= @Id";//加[]是因为user是数据库中关键字 18 SqlParameter[] para = new SqlParameter[] 19 { 20 new SqlParameter("@Id",sId) 21 }; 22 using (SqlDataReader reader = SqlHelper.ExecuteReader(SqlHelper.ConnectionString,System.Data.CommandType.Text,sql,para)) 23 { 24 while (reader.Read()) 25 { 26 User userList = new User(); 27 userList.Id = (string)reader["id"]; 28 userList.Name = (string)reader["name"]; 29 userList.Password = (string)reader["password"]; 30 userList.Role = (string)reader["role"]; 31 list.Add(userList); 32 } 33 } 34 return list; 35 } 36 } 37 }
BLL层:
UserManager:
将得到的结果进行加工,返回给UI层
1 using Proj.DAL; 2 using Proj.Models; 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace Proj.BLL 10 { 11 public class UserManager 12 { 13 public List<User> GetUsersById(string sId) 14 { 15 return new UserService().GetUserById(sId); 16 } 17 } 18 }
UI层:
Form1
1 using Proj.BLL; 2 using Proj.Models; 3 using System; 4 using System.Collections.Generic; 5 using System.ComponentModel; 6 using System.Data; 7 using System.Drawing; 8 using System.Linq; 9 using System.Text; 10 using System.Threading.Tasks; 11 using System.Windows.Forms; 12 13 namespace UI 14 { 15 public partial class Form1 : Form 16 { 17 public Form1() 18 { 19 InitializeComponent(); 20 } 21 22 private void Form1_Load(object sender, EventArgs e) 23 { 24 25 } 26 27 private void label2_Click(object sender, EventArgs e) 28 { 29 30 } 31 32 private void textBox2_TextChanged(object sender, EventArgs e) 33 { 34 35 } 36 37 private void btnCancle_Click(object sender, EventArgs e) 38 { 39 Close(); 40 } 41 42 private void btnLogin_Click(object sender, EventArgs e) 43 { 44 string sId = tbId.Text.Trim(); 45 string sPwd = tbPwd.Text.Trim(); 46 List<User> list = new UserManager().GetUsersById(sId); 47 if(list !=null&& list.Count>0) 48 { 49 if(sPwd == list[0].Password.Trim()) 50 { 51 MessageBox.Show("登陆成功!"); 52 } 53 else 54 { 55 MessageBox.Show("登陆失败!"); 56 } 57 } 58 else 59 { 60 MessageBox.Show("用户不存在!"); 61 } 62 } 63 } 64 } 65 using Proj.BLL; 66 using Proj.Models; 67 using System; 68 using System.Collections.Generic; 69 using System.ComponentModel; 70 using System.Data; 71 using System.Drawing; 72 using System.Linq; 73 using System.Text; 74 using System.Threading.Tasks; 75 using System.Windows.Forms; 76 77 namespace UI 78 { 79 public partial class Form1 : Form 80 { 81 public Form1() 82 { 83 InitializeComponent(); 84 } 85 86 private void Form1_Load(object sender, EventArgs e) 87 { 88 89 } 90 91 private void label2_Click(object sender, EventArgs e) 92 { 93 94 } 95 96 private void textBox2_TextChanged(object sender, EventArgs e) 97 { 98 99 } 100 101 private void btnCancle_Click(object sender, EventArgs e) 102 { 103 Close(); 104 } 105 106 private void btnLogin_Click(object sender, EventArgs e) 107 { 108 string sId = tbId.Text.Trim(); 109 string sPwd = tbPwd.Text.Trim(); 110 List<User> list = new UserManager().GetUsersById(sId); 111 if(list !=null&& list.Count>0) 112 { 113 if(sPwd == list[0].Password.Trim()) 114 { 115 MessageBox.Show("登陆成功!"); 116 } 117 else 118 { 119 MessageBox.Show("登陆失败!"); 120 } 121 } 122 else 123 { 124 MessageBox.Show("用户不存在!"); 125 } 126 } 127 } 128 }
就先到这吧。