在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
就个人而言,三层架构有点难理解,不知道该如何下手,各层与各层之间怎么调用 最近一直在研究三层架构,经过网上学习与多方打听写一下自己的心得。有不足之处,可以评论和私聊探讨 言归正传: 三层架构(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( |
请发表评论