【ASP.NET开发】ASP.NET(MVC)三层架构知识的学习总结(转)
至从使用过一次MVC进行团队开发后,体会到了面向对象开发软件的便利。使用MVC的时候,各个层之间的低耦合使得他们之间的联系非常的第,也就降低了模块之间的依赖程度。
首先介绍一下MVC的意义,和各个层面之间的用途和功能。
1)实体层。主要用来声明在视图层和业务逻辑层之间传递数据的载体。通常代表来源与项目数据库中一个或者多个表组成的一条有意义的记录。
2)业务逻辑层。根据业务逻辑向视图层提供数据,这个项目中的类有权根据业务逻辑来决定是否调用数据库访问层的方法
3)数据库访问层。项业务逻辑层提供访问数据的方法。
4)视图层。主要是以网站开发为例。用于提供显示,添加,编辑和删除数据。
我在VS中创建的项目的结构图:
NetMVC就是所谓的视图层。Entity是实体层,用来声明开发过程中被要使用的所有变量。DAL是数据库访问层,主要完成所有操作对数据库的访问。BLL是业务逻辑层,处理视图层传来的业务逻辑,然后传递给数据库访问层进行处理。
本例主要演示的是登陆页面的实现,Entity层的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
using System; using System.Collections.Generic; using System.Text; namespace Entity { public class UserInfo { private int UserId; /// <summary> /// 用户比编号 /// </summary> public int UserId1 { get { return UserId; } set { UserId = value; } } private string username; /// <summary> /// 登录账户名称 /// </summary> public string Username { get { return username; } set { username = value; } } private string password; /// <summary> /// 登录密码 /// </summary> public string Password { get { return password; } set { password = value; } } private int loginCount; /// <summary> /// 登陆次数 /// </summary> public int LoginCount { get { return loginCount; } set { loginCount = value; } } private DateTime regDate; /// <summary> /// 注册时间 /// </summary> public DateTime RegDate { get { return regDate; } set { regDate = value; } } private DateTime lastLoginDate; /// <summary> /// 最后登录时间 /// </summary> public DateTime LastLoginDate { get { return lastLoginDate; } set { lastLoginDate = value; } } private bool isForbidden; private string passwordQuestion; /// <summary> /// 找回密码提示问题 /// </summary> public string PasswordQuestion { get { return passwordQuestion; } set { passwordQuestion = value; } } private string passwordAnswer; /// <summary> /// 找回密码答案 /// </summary> public string PasswordAnswer { get { return passwordAnswer; } set { passwordAnswer = value; } } } } |
完成对实体类的创建,接着就要完成对数据库访问层的创建(其中需要用到上篇问章所写的SqlHelper数据库访问通用类http://www.cnblogs.com/qq731109249/archive/2012/09/20/2694952.html),代码如下,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using System.Configuration; using Entity; namespace DAL { public class UserDal { private string connectionString = ConfigurationManager.ConnectionStrings[ "connectionString" ].ConnectionString; /// <summary> /// 添加用户 /// </summary> /// <param name="info">用户的实体类</param> /// <returns></returns> public bool AddUser(UserInfo info) { string sql = "insert into Users(Username,password) values('@Username','@password')" ; SqlParameter[] parameters = new SqlParameter[4]; parameters[0] = new SqlParameter( "@Username" , SqlDbType.NVarChar, 30); parameters[0].Value = info.Username; parameters[1] = new SqlParameter( "password" , SqlDbType.VarChar, 50); parameters[1].Value = info.Password; return new SqlDbHelper(connectionString).ExecuteNonQuery(sql) > 0; } /// <summary> /// 删除用户 /// </summary> /// <param name="UserId">用户编号</param> /// <returns></returns> public bool DeleteUser( int UserId) { string sql = "delete from users where UserId=" + UserId; return new SqlDbHelper(connectionString).ExecuteNonQuery(sql) > 0; } /// <summary> /// 更新用户 /// </summary> /// <param name="info">用户的实体类</param> /// <returns></returns> public bool UpDateUser(UserInfo info) { string sql = "update users set password=@password,loginCount=@loginCount where userid=@userid" ; SqlParameter[] parameters = new SqlParameter[7]; parameters[0] = new SqlParameter( "@password" , SqlDbType.VarChar, 30); parameters[0].Value = info.Password; parameters[1] = new SqlParameter( "@loginCount" , SqlDbType.Int, 4); parameters[1].Value = info.LoginCount; return new SqlDbHelper(connectionString).ExecuteNonQuery(sql) > 0; } /// <summary> /// 根据用户名或者用户编号查询用户 /// </summary> /// <param name="userId">用户编号</param> /// <returns></returns> public DataTable GetUser( int userId) { string sql = "select * from users where userId=@UserId" ; SqlParameter[] parameters = new SqlParameter[1]; parameters[0] = new SqlParameter( "@UserId" , SqlDbType.Int, 4); parameters[0].Value = userId; return new SqlDbHelper(connectionString).ExecuteDataTable(sql, CommandType.Text, parameters); } /// <summary> /// 根据用户名查询用户信息 /// </summary> /// <param name="Username">用户名</param> /// <returns></returns> public DataTable GetUser( string Username) { string sql = "select * from users where username=@username" ; SqlParameter[] parameters = new SqlParameter[1]; parameters[1] = new SqlParameter( "@username" , SqlDbType.NVarChar, 30); parameters[1].Value = Username; return new SqlDbHelper(connectionString).ExecuteDataTable(sql, CommandType.Text, parameters); } /// <summary> /// 按照用户编号升序查询从指定位置开始的指定条数记录 /// </summary> /// <param name="startIndex">查询的起始位置</param> /// <param name="size">返回的最大记录条数</param> /// <returns></returns> public DataTable GetUserList( int startIndex, int size) { string sql = "select top " + size + " * from users where UserId not in (select top " + startIndex + " UserId from Users order by UserId asc)order by UserId asc" ; return new SqlDbHelper(connectionString).ExecuteDataTable(sql); } /// <summary> /// 查询用户总数 /// </summary> /// <returns></returns> public int GetUserCount() { string sql = "select count(1) from Users" ; return int .Parse( new SqlDbHelper(connectionString).ExecuteScalar(sql).ToString()); } } } |
然后创建业务逻辑层,代码如下:
using System; using System.Collections.Generic; using System.Text; using DAL; using Entity; using System.Data; using System.Data.SqlClient; using System.Security.Cryptography; using System.Security; namespace BLL { public class UserBLL { private static string MD5Hash( string password) { MD5 md5 = MD5.Create(); //创建Md5算法实例 //将原始字符串转换成UTF-8编码的字节数组 byte [] sourceBytes = System.Text.Encoding.UTF8.GetBytes(password); //计算字节数组的哈希值 byte [] resultBytes = md5.ComputeHash(sourceBytes); StringBuilder buffer = new StringBuilder(resultBytes.Length); //将计算得到的哈希值的字节数组中的每一个字节转换成十六进制形式 foreach ( byte b in resultBytes) { buffer.Append(b.ToString( "X" )); } return buffer.ToString(); } /// <summary> /// 添加用户 /// </summary> /// <param name="info">用户的实体类</param> /// <returns></returns> public static bool AddUser(UserInfo info) { UserDal dal = new UserDal(); DataTable data = dal.GetUser(info.Username); if (data.Rows.Count > 0) { return false ; } else { info.Password =MD5Hash (info.Password); return new UserDal().AddUser(info); } } /// <summary> /// 删除用户 /// </summary> /// <param name="userId">用户编号</param> /// <returns></returns> public static bool DeleteUser( int userId) { return new UserDal().DeleteUser(userId); } /// <summary> /// 更新用户 /// </summary> /// <param name="info">用户的实体类</param> /// <param name="changePassword">是否需要对用户密码进行加密</param> /// <returns></returns> public static bool UpdateUser(UserInfo info, bool changePassword) { //如果更改密码就需要对新密码进行加密 //如果没有更改密码则不能对密码重复加密,否则会对用户造成无法登陆 if (changePassword) { info.Password = MD5Hash(info.Password); } return new UserDal().UpDateUser(info); } /// <summary> /// 根据用户编号查询用户 /// </summary> /// <param name="UserId">用户的编号</param> /// <returns></returns> public static DataTable GetUser( int UserId) { return new UserDal().GetUser(UserId); } /// <summary> /// 根据用户名查询用户信息 /// </summary> /// <param name="userName">用户名</param> /// <returns></returns> public static DataTable GetUser( string userName) { return new UserDal().GetUser(userName); } /// <summary> /// 按照用户编号升序查询从指定位置开始的指定条数的记录 /// </summary> /// <param name="startIndex">查询的起始位置</param> /// <param name="size">返回的最大记录条数</param> /// <returns></returns> public static DataTable GetUserList( int startIndex, int size) { return new UserDal().GetUserList(startIndex, size); } /// <summary> /// 查询用户总数 /// </summary> /// <returns></returns> public static int GetUserCount() { return new UserDal().GetUserCount(); } /// <summary> /// 根据用户名或者用户编号从数据库查询对应记录的实体,如果不存在则返回null /// </summary> /// <param name="userId">用户编号</param> /// <returns></returns> public static UserInfo GetUserEntity( int userId) { return ChangeToEntity( new UserDal().GetUser(userId)); } /// <summary> /// 根据用户名或者用户编号从数据库查询对应记录的实体,如果不存在则返回null /// </summary> /// <param name="userName">用户名</param> /// <returns></returns> public static UserInfo GetUserEntity( string userName) { return ChangeToEntity( new UserDal().GetUser(userName)); } /// <summary> /// 将包含Users表记录的DataTables中的第一条记录转换成Userinfo实体 /// </summary> /// <param name="data"></param> /// <returns></returns> private static UserInfo ChangeToEntity(DataTable data) { UserInfo info = null ; //如果data不为空并且包含的记录条数大于0、 if (data!= null &&data.Rows.Count > 0) { DataRow row = data.Rows[0]; info = new UserInfo(); } return info; } public static bool Login( string userName, string password) { bool exits = false ; UserInfo info = GetUserEntity(userName); if (info != null && MD5Hash(password) == info.Password) { exits = true ; info.LoginCount = info.LoginCount + 1; //将用户登陆的次数加1 info.LastLoginDate = DateTime.Now; //将用户最后的登录时间设置为现在 UpdateUser(info, false ); //更新用户的登陆次数和最后的登录时间 } return exits; } } } |
这个就完成了对数据库访问层,实体层,业务逻辑层的创建工作。因为在创建过程中被,有很多的重复的工作,我为了加快速度,就省略了一些的代码。
在登陆页面使用时,只需要引入业务逻辑层的方法,然后根据其中的方法,传入相应的参数,就可以完成所有的操作。