(因为忙毕业的事,所以很长一段时间没有写这个系列的文章,现在继续,望大家见谅。)
在上一篇中,讨论了使用SQL构建数据访问层的方法,并且针对的是Access数据库。而这一篇中,将要创建一个针对SQLServer数据库的数据访问层,并且配合存储过程实现。
曾经有朋友问我使用SQL和存储过程在效率上的差别,惭愧的是我对这方面没有研究,也没有实际做过测试。通过查阅资料,发现在一般情况下,存储过程的效率由于使用SQL,但是也不绝对,也发现有的朋友测试时发现在特定情况下SQL的效率优于存储过程,所以这个问题不能一概而论。
好,废话不多说,这里先列出使用存储过程构建数据访问层的一般步骤:
1.创建新工程
2.创建数据库
3.编写相应存储过程
4.编写数据库辅助类
5.实现数据访问层
创建新工程
在开始所有开发工作前,我们需要在解决方案下新建一个工程,叫SQLServerDAL,用于存放所有SQLServer数据访问层的代码。
创建数据库
首先,我们要根据前文设计的数据库,在SQLServer中创建相应的数据库及数据表。我使用的是SQLServer2005,使用企业管理器创建,创建方法不再赘述。
编写存储过程
数据库创建完成后,我们就要编写存储过程了。由于数据访问层接口已经确定,所以需要哪些存储过程也很好确定。例如数据访问层接口中有一个添加管理员方法,那么就一定有一个存储过程实现这个功能。
还是以管理员模块为例,经过简单分析,需要一下存储过程:
插入管理员记录
删除管理员记录
更新管理员信息
按ID取得管理员记录
按用户名及密码取得管理员记录
按用户名取得管理员记录
取得全部管理员记录
创建这些存储过程的SQL代码如下:

插入管理员记录
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <T2噬菌体>
-- Create date: <2008-07-04>
-- Description: <插入管理员记录>
-- =============================================
CREATE PROCEDURE [dbo].[Pr_InsertAdmin]
(
@Name Nvarchar(20),
@Password Nvarchar(50)
)
AS
INSERT INTO TAdmin
(
[Name],
[Password]
)
VALUES
(
@Name,
@Password
)

删除管理员记录
1
set ANSI_NULLS ON
2
set QUOTED_IDENTIFIER ON
3
GO
4
-- =============================================
5
-- Author: <T2噬菌体>
6
-- Create date: <2008-07-04>
7
-- Description: <删除管理员记录>
8
-- =============================================
9
CREATE PROCEDURE [dbo].[Pr_DeleteAdmin]
10
(
11
@ID Int
12
)
13
AS
14
DELETE FROM TAdmin
15
WHERE [ID]=@ID

修改管理员信息
1
set ANSI_NULLS ON
2
set QUOTED_IDENTIFIER ON
3
GO
4
-- =============================================
5
-- Author: <T2噬菌体>
6
-- Create date: <2008-07-04>
7
-- Description: <修改管理员记录>
8
-- =============================================
9
CREATE PROCEDURE [dbo].[Pr_UpdateAdmin]
10
(
11
@ID Int,
12
@Name Nvarchar(20),
13
@Password Nvarchar(50)
14
)
15
AS
16
UPDATE TAdmin
17
SET
18
[Name]=@Name,
19
[Password]=@Password
20
WHERE [ID]=@ID

按ID取得管理员
1
set ANSI_NULLS ON
2
set QUOTED_IDENTIFIER ON
3
GO
4
-- =============================================
5
-- Author: <T2噬菌体>
6
-- Create date: <2008-07-04>
7
-- Description: <按ID取得管理员信息>
8
-- =============================================
9
CREATE PROCEDURE [dbo].[Pr_GetAdminByID]
10
(
11
@ID Int
12
)
13
AS
14
SELECT * FROM TAdmin
15
WHERE [ID]=@ID

按用户名和密码取得管理员
1
set ANSI_NULLS ON
2
set QUOTED_IDENTIFIER ON
3
GO
4
-- =============================================
5
-- Author: <T2噬菌体>
6
-- Create date: <2008-07-04>
7
-- Description: <按用户名及密码取得管理员信息>
8
-- =============================================
9
CREATE PROCEDURE [dbo].[Pr_GetAdminByNameAndPassword]
10
(
11
@Name Nvarchar(20),
12
@Password Nvarchar(50)
13
)
14
AS
15
SELECT * FROM TAdmin
16
WHERE [Name]=@Name
17
AND [Password]=@Password

按用户名取得管理员
1
set ANSI_NULLS ON
2
set QUOTED_IDENTIFIER ON
3
GO
4
-- =============================================
5
-- Author: <T2噬菌体>
6
-- Create date: <2008-07-04>
7
-- Description: <按用户名取得管理员信息>
8
-- =============================================
9
CREATE PROCEDURE [dbo].[Pr_GetAdminByName]
10
(
11
@Name Nvarchar(20)
12
)
13
AS
14
SELECT * FROM TAdmin
15
WHERE [Name]=@Name

取得全部管理员信息
1
set ANSI_NULLS ON
2
set QUOTED_IDENTIFIER ON
3
GO
4
-- =============================================
5
-- Author: <T2噬菌体>
6
-- Create date: <2008-07-04>
7
-- Description: <取得全部管理员信息>
8
-- =============================================
9
CREATE PROCEDURE [dbo].[Pr_GetAllAdmin]
10
AS
11
SELECT * FROM TAdmin
编写数据库辅助类
由于访问数据库的代码很相似,这里我们仍需要编写一个数据库辅助类,来将常用代码封装起来,方便复用。虽然在这里只使用到了存储过程,但是为了扩展性考虑,这个数据库辅助类仍然包含了通过SQL访问数据库的方法。具体实现如下:
SQLServerDALHelper.cs:

SQLServerDALHelper
1
using System;
2
using System.Collections.Generic;
3
using System.Configuration;
4
using System.Data;
5
using System.Data.SqlClient;
6
7
namespace NGuestBook.SQLServerDAL
8

{
9
/**//// <summary>
10
/// SQLServer数据库操作助手
11
/// </summary>
12
public sealed class SQLServerDALHelper
13
{
14
/**//// <summary>
15
/// 用于连接SQLServer数据库的连接字符串,存于Web.config中
16
/// </summary>
17
private static readonly string _sqlConnectionString = ConfigurationManager.AppSettings["SQLServerConnectionString"];
18
19
/**//// <summary>
20
/// 执行SQL命令,不返回任何值
21
/// </summary>
22
/// <param name="sql">SQL命令</param>
23
public static void ExecuteSQLNonQurey(string sql)
24
{
25
SqlConnection connection = new SqlConnection(_sqlConnectionString);
26
SqlCommand command = new SqlCommand(sql,connection);
27
connection.Open();
28
command.ExecuteNonQuery();
29
connection.Close();
30
}
31
32
/**//// <summary>
33
/// 执行SQL命令,并返回SqlDataReader
34
/// </summary>
35
/// <param name="sql">SQL命令</param>
36
/// <returns>包含查询结果的SqlDataReader</returns>
37
public static SqlDataReader ExecuteSQLReader(string sql)
38
{
39
SqlConnection connection = new SqlConnection(_sqlConnectionString);
40
SqlCommand command = new SqlCommand(sql, connection);
41
connection.Open();
42
SqlDataReader sqlReader = command.ExecuteReader();
43
//connection.Close();
44
45
return sqlReader;
46
}
47
48
/**//// <summary>
49
/// 执行存储过程,不返回任何值
50
/// </summary>
51
/// <param name="storedProcedureName">存储过程名</param>
52
/// <param name="parameters">参数</param>
53
public static void ExecuteProcedureNonQurey(string storedProcedureName,IDataParameter[] parameters)
54
{
55
SqlConnection connection = new SqlConnection(_sqlConnectionString);
56
SqlCommand command = new SqlCommand(storedProcedureName,connection);
57
command.CommandType = CommandType.StoredProcedure;
58
if (parameters != null)
59
{
60
foreach (SqlParameter parameter in parameters)
61
{
62
command.Parameters.Add(parameter);
63
}
64
}
65
connection.Open();
66
command.ExecuteNonQuery();
67
connection.Close();
68
}
69
70
/**//// <summary>
71
/// 执行存储,并返回SqlDataReader
72
/// </summary>
73
/// <param name="storedProcedureName">存储过程名</param>
74
/// <param name="parameters">参数</param>
75
/// <returns>包含查询结果的SqlDataReader</returns>
76
public static SqlDataReader ExecuteProcedureReader(string storedProcedureName,IDataParameter[] parameters)
77
{
78
SqlConnection connection = new SqlConnection(_sqlConnectionString);
79
SqlCommand command = new SqlCommand(storedProcedureName,connection);
80
command.CommandType = CommandType.StoredProcedure;
81
if (parameters != null)
82
{
83
foreach (SqlParameter parameter in parameters)
84
{
85
command.Parameters.Add(parameter);
86
}
87
}
88
connection.Open();
89
SqlDataReader sqlReader = command.ExecuteReader();
90
//connection.Close();
91
92
return sqlReader;
93
}
94
}
95
}
实现数据访问层
最后仍以管理员模块为例,看一下具体数据访问层的实现。
AdminDAL.cs:

AdminDAL
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Data;
5
using System.Data.SqlClient;
6
using NGuestBook.IDAL;
7
using NGuestBook.Entity;
8
9
namespace NGuestBook.SQLServerDAL
10

{
11
public class AdminDAL : IAdminDAL
12
{
13
/**//// <summary>
14
/// 插入管理员
15
/// </summary>
16
/// <param name="admin">管理员实体类</param>
17
/// <returns>是否成功</returns>
18
public bool Insert(AdminInfo admin)
19
{
20
SqlParameter[] parameters =
21
{
22
new SqlParameter("@Name",SqlDbType.NVarChar),
23
new SqlParameter("@Password",SqlDbType.NVarChar)
24
};
25
parameters[0].Value = admin.Name;
26
parameters[1].Value = admin.Password;
27
try
28
{
29
SQLServerDALHelper.ExecuteProcedureNonQurey("Pr_InsertAdmin", parameters);
30
return true;
31
}
32
catch
33
{
34
return false;
35
}
36
}
37
38
/**//// <summary>
39
/// 删除管理员
40
&nbs