三层架构:UI(界面,User Interfa)、BLL(业务逻辑层)以及DAL(数据访问层)。三层之间通过Model实现数据的传递。在使用中牢记,三层之间的访问权限;UI→BLL→DAL。
采用三层架构的优点:高可拓展性、可维护性高,不足之处:工作量大、系统比较复杂(感觉最好是精通设计思想,如设计模式)、效率比较低。
项目的结构图:
建立相应的文件夹
首先配置应用程序配置文件 App.config
配置如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <?xml version="1.0" encoding="utf-8" ?>
2 <configuration>
3 <connectionStrings>
4 <add name="cons" connectionString="server=(local);user id=sa; pwd=********;database=GUbase"/>//连接字符串
5 </connectionStrings>
6 </configuration>
封装的数据库操作SQlHelper.cs
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 sing System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Configuration;
6 using System.Data.SqlClient;
7 using System.Data;
8
9 namespace 三层架构.DAL
10 {
11 class SQlHelper
12 {
13 private static readonly string cons = ConfigurationManager.ConnectionStrings["cons"].ConnectionString;//读取配置文件的连接字符串
14
15 #region ExecuteNoQuery//用于执行非查询语句
16 /// <summary>
17 /// ExecuteNoQuery
18 /// </summary>
19 /// <param name="sql">sql语句</param>
20 /// <param name="Parameters">参数</param>
21 /// <returns></returns>
22 public static int ExecuteNoQuery(string sql, params SqlParameter[] Parameters)
23 {
24 using (SqlConnection con = new SqlConnection(cons))
25 {
26 con.Open();
27 using (SqlCommand cmd = con.CreateCommand())
28 {
29 cmd.CommandText = sql;
30 cmd.Parameters.AddRange(Parameters);
31 return cmd.ExecuteNonQuery();
32 }
33 }
34
35 }
36 #endregion
37 #region ExecuteScalar
38 /// <summary>
39 /// ExecuteScalar//查询相关
40 /// </summary>
41 /// <param name="sql">sql语句</param>
42 /// <param name="Parameters">参数/param>
43 /// <returns></returns>
44 public static object ExecuteScalar(string sql, params SqlParameter[] Parameters)
45 {
46 using (SqlConnection con = new SqlConnection(cons))
47 {
48 con.Open();
49 using (SqlCommand cmd = con.CreateCommand())
50 {
51 cmd.CommandText = sql;
52 cmd.Parameters.AddRange(Parameters);
53 return cmd.ExecuteScalar();
54 }
55 }
56 }
57 #endregion
58 #region ExecuteDataTable
59 /// <summary>
60 /// ExecuteDataTable//查询获取相关字段的值
61 /// </summary>
62 /// <param name="sql">sql语句</param>
63 /// <param name="Parameters">参数/param>
64 /// <returns></returns>
65 public static DataTable ExecuteDataTable(string sql, params SqlParameter[] Parameters)
66 {
67 using (SqlConnection con = new SqlConnection(cons))
68 {
69 con.Open();
70 using (SqlCommand cmd = con.CreateCommand())
71 {
72 cmd.CommandText = sql;
73 cmd.Parameters.AddRange(Parameters);
74 DataTable table = new DataTable();
75 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
76 adapter.Fill(table);
77 return table;
78 }
79 }
80 }
81 #endregion
82 }
83 }
Model文件下的Person.cs 封装z字段相关,用于在三层之间数据的传递
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 三层架构.Model 7 { 8 class Person 9 { 10 public int Id { get; set; } 11 public string Name { get; set; } 12 public int Age { get; set; } 13 } 14 }
DAl下的PersonDAL.cs用于和数据库执行各种操作的SQL语句和方法
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using 三层架构.Model; 6 using System.Data.SqlClient; 7 using System.Data; 8 9 namespace 三层架构.DAL 10 { 11 class PersonDAL 12 { 13 #region 新增 14 /// <summary> 15 /// 新增 16 /// </summary> 17 /// <param name="model">对象</param> 18 /// <returns></returns> 19 public int AddNew(Person model)//把要插入数据的模型传递给AddNew() 20 { 21 object obj = SQlHelper.ExecuteScalar("insert into T_Person(Name,Age) values(@Name,@Age);select @@identity", new SqlParameter("Name", model.Name), new SqlParameter("Age", model.Age));//select @@identity执行插入后返回主键值 22 return Convert.ToInt32(obj); 23 } 24 #endregion 25 26 #region 删除 27 public int Delete(int id) 28 { 29 return SQlHelper.ExecuteNoQuery("delete from T_Person where Id=@Id", new SqlParameter("Id", id)); 30 } 31 #endregion 32 #region 更新 33 public int Update(Person model) 34 { 35 return SQlHelper.ExecuteNoQuery("update T_Person set Name=@Name, Age=@Age where Id=@Id", new SqlParameter("Id", model.Id), new SqlParameter("Name", model.Name), new SqlParameter("Age", model.Age)); 36 } 37 #endregion 38 #region 查询 39 public Person GetData(int id) 40 { 41 DataTable dt = SQlHelper.ExecuteDataTable("select * from T_Person where Id=@Id", new SqlParameter("Id", id)); 42 if (dt.Rows.Count < 0) 43 { 44 return null; 45 } 46 else if (dt.Rows.Count == 1) 47 { 48 DataRow row = dt.Rows[0]; 49 Person model = new Person(); 50 model.Id = Convert.ToInt32(row["Id"]); 51 model.Name = Convert.ToString(row["Name"]); 52 model.Age = Convert.ToInt32(row["Age"]); 53 return model; 54 } 55 else 56 { 57 throw new Exception("数据出错,多条数据"); 58 } 59 } 60 #endregion 61 public IEnumerable<Person> GetAll()//IEnumerable<Person>使用该接口实现只读性 62 { 63 DataTable dt = SQlHelper.ExecuteDataTable("select * from T_Person"); 64 List<Person> list = new List<Person>(); 65 foreach (DataRow row in dt.Rows) 66 { 67 Person model = new Person(); 68 model.Id = Convert.ToInt32(row["Id"]); 69 model.Name= Convert.ToString(row["Name"]); 70 model.Age = Convert.ToInt32(row["Age"]); 71 list.Add(model); 72 } 73 return list; 74 } 75 } 76 }
BLL下的PersonBLL.cs用于执行和数据库交互前业务逻辑的判断处理
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using 三层架构.Model; 6 using 三层架构.DAL; 7 using System.Data.SqlClient; 8 9 namespace 三层架构.BLL 10 { 11 class PersonBLL 12 { 13 #region 新增 14 15 public int AddNew(Person model)//把要插入数据的模型传递给AddNew() 16 { 17 return new PersonDAL().AddNew(model); 18 } 19 #endregion 20 21 #region 删除 22 public int Delete(int id) 23 { 24 return new PersonDAL().Delete(id); 25 } 26 #endregion 27 #region 更新 28 public int Update(Person model) 29 { 30 //BLL进行逻辑判断,DAL只进行数据库的操作!,这就是BLL和DAL的区别 31 if (model.Age <10) 32 { 33 throw new Exception("年龄非法!!"); 34 } 35 return new PersonDAL().Update(model); 36 } 37 #endregion 38 #region 查询 39 public Person GetData(int id) 40 { 41 return new PersonDAL().GetData(id); 42 } 43 #endregion 44 public IEnumerable<Person> GetAll()//IEnumerable<Person>使用该接口实现只读性 45 { 46 return new PersonDAL().GetAll(); 47 } 48 } 49 }
UI界面
采用三层架构用户界面变得相当简洁
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using 三层架构.Model; 10 using 三层架构.DAL; 11 using 三层架构.BLL; 12 13 namespace 三层架构 14 { 15 public partial class Form1 : Form 16 { 17 public Form1() 18 { 19 InitializeComponent(); 20 } 21 22 private void button1_Click(object sender, EventArgs e) 23 { 24 Person p1 = new Person(); 25 p1.Age = 20; 26 p1.Name = "小文"; 27 int id= new PersonBLL().AddNew(p1); 28 MessageBox.Show(id.ToString()); 29 } 30 31 private void button2_Click(object sender, EventArgs e) 32 { 33 int Id = 3; 34 int count = new PersonBLL().Delete(Id); 35 MessageBox.Show("删除成功!!"); 36 } 37 38 private void button3_Click(object sender, EventArgs e) 39 { 40 Person p = new Person(); 41 p.Id = 1; 42 p.Name = "想你"; 43 p.Age = 21; 44 new PersonBLL().Update(p); 45 MessageBox.Show("更新成功!!"); 46 } 47 48 private void button4_Click(object sender, EventArgs e) 49 { 50 int id = 1; 51 Person p= new PersonBLL().GetData(id); 52 int Id = p.Id; 53 int Age = p.Age; 54 MessageBox.Show(Id.ToString()); 55 MessageBox.Show(p.Name); 56 MessageBox.Show(Age.ToString()); 57 } 58 59 private void Form1_Load(object sender, EventArgs e) 60 { 61 dataGridView1.DataSource = new PersonBLL().GetAll(); 62 } 63 } 64 }
<下篇博客主要是根据本篇的代码格式,完成自己的三层架构的代码生成器,居然现在市面上有很多的代码生成器,但有的时候还是更加喜欢自己的风格,今天写了一些,估计过几天就可以完成,到时候发到博客上,揭秘代码生成器的原理>